@hawkeyexl/manni 4.11.0 → 4.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{batch-UAULUMGH.js → batch-EFSFG6GC.js} +20 -19
- package/dist/build-NIO3UIWJ.js +36 -0
- package/dist/calibrate-6VO7URRV.js +41 -0
- package/dist/capture-NMBVJO3C.js +38 -0
- package/dist/check-SHOYX2B5.js +30 -0
- package/dist/check-XMJKH3KV.js +34 -0
- package/dist/{check-VELUQAUW.js → check-Y62BJNC4.js} +35 -34
- package/dist/{check-VELUQAUW.js.map → check-Y62BJNC4.js.map} +1 -1
- package/dist/{check-YEOYBFST.js → check-ZMO3ZLMW.js} +19 -18
- package/dist/{chunk-BKVHX6FU.js → chunk-24AJK2RG.js} +5 -10
- package/dist/chunk-24AJK2RG.js.map +1 -0
- package/dist/{chunk-M42DZCOU.js → chunk-2OZF2VUB.js} +2 -2
- package/dist/chunk-2UJZXVHR.js +1868 -0
- package/dist/chunk-2UJZXVHR.js.map +1 -0
- package/dist/{chunk-HQR2ZBHW.js → chunk-3BRJCQPY.js} +36 -7
- package/dist/chunk-3BRJCQPY.js.map +1 -0
- package/dist/{chunk-U7CTFN2J.js → chunk-42VFJOAF.js} +7 -7
- package/dist/{chunk-LBSCW232.js → chunk-4Q24OYI3.js} +7 -7
- package/dist/{chunk-OPXWPJDA.js → chunk-4WJTURRO.js} +14 -14
- package/dist/{chunk-GDVZ5VII.js → chunk-5SID2SVL.js} +4 -4
- package/dist/{chunk-FUCPZVRY.js → chunk-AANUY4BH.js} +2 -2
- package/dist/chunk-ANPIIYRH.js +2272 -0
- package/dist/chunk-ANPIIYRH.js.map +1 -0
- package/dist/{chunk-WDWXAYVH.js → chunk-AYVKN3PG.js} +4 -4
- package/dist/{chunk-FQXWVS6J.js → chunk-CH6IOGXV.js} +9 -9
- package/dist/{chunk-4CK6ZSOK.js → chunk-D5Z6B4M7.js} +3 -3
- package/dist/{chunk-HA6MQMOY.js → chunk-D6SELXQ2.js} +6 -6
- package/dist/{chunk-2DRHT73U.js → chunk-DDILEF5F.js} +890 -1399
- package/dist/chunk-DDILEF5F.js.map +1 -0
- package/dist/{chunk-PCS4VJBV.js → chunk-DGRLHDM4.js} +9 -9
- package/dist/{chunk-2MJ62AYQ.js → chunk-DHGB4JBG.js} +4 -3
- package/dist/chunk-DHGB4JBG.js.map +1 -0
- package/dist/{chunk-Y6DOMTQD.js → chunk-DLU5FCFT.js} +27 -27
- package/dist/chunk-DLU5FCFT.js.map +1 -0
- package/dist/chunk-DSWKBZWW.js +16 -0
- package/dist/chunk-DSWKBZWW.js.map +1 -0
- package/dist/{chunk-KGEQJ5CC.js → chunk-F564FHMQ.js} +8 -8
- package/dist/{chunk-J6IDQGJL.js → chunk-FKAZUZQU.js} +469 -85
- package/dist/chunk-FKAZUZQU.js.map +1 -0
- package/dist/{chunk-IGSHYP74.js → chunk-G3MBUL5M.js} +4 -4
- package/dist/{chunk-ADMEPUBT.js → chunk-GQ3KRY3B.js} +3 -3
- package/dist/{chunk-T7JAOYE5.js → chunk-HDPN46JP.js} +6 -6
- package/dist/{chunk-R4WXQIOZ.js → chunk-IQQAJROD.js} +3 -3
- package/dist/{chunk-2IR4T5PO.js → chunk-IZXN3WI6.js} +2 -2
- package/dist/{chunk-NCPWXHDO.js → chunk-JEUFYSFQ.js} +4 -4
- package/dist/{chunk-LKP7QDFN.js → chunk-JSSM7VVV.js} +4 -4
- package/dist/{chunk-2IAZEB45.js → chunk-KFGZPVFA.js} +229 -821
- package/dist/chunk-KFGZPVFA.js.map +1 -0
- package/dist/{chunk-EIFCP6CZ.js → chunk-KGFSPJLD.js} +2 -2
- package/dist/{chunk-RLT5SEML.js → chunk-KMORGMCW.js} +6 -6
- package/dist/{chunk-WQWKYAAK.js → chunk-NUQF5F5J.js} +2 -2
- package/dist/{chunk-54F74XR3.js → chunk-NZ6KSHFD.js} +19 -19
- package/dist/{chunk-4D5IZSXM.js → chunk-OHUDZRLK.js} +3 -3
- package/dist/{chunk-FBMZJEB3.js → chunk-OKMTUAWO.js} +4 -4
- package/dist/{chunk-QLWC7MKD.js → chunk-OTJOBZJ5.js} +135 -135
- package/dist/chunk-OTJOBZJ5.js.map +1 -0
- package/dist/{chunk-6HWBRZIN.js → chunk-PS257NIU.js} +252 -193
- package/dist/chunk-PS257NIU.js.map +1 -0
- package/dist/chunk-QDC7JPFG.js +685 -0
- package/dist/chunk-QDC7JPFG.js.map +1 -0
- package/dist/{chunk-PCQ7ELJH.js → chunk-QEAGL4V5.js} +109 -5
- package/dist/chunk-QEAGL4V5.js.map +1 -0
- package/dist/{chunk-BBT6AVUG.js → chunk-QMY57PVW.js} +2 -2
- package/dist/{chunk-LPIF5LIE.js → chunk-QNDDPXFR.js} +2 -2
- package/dist/{chunk-PWBH7DCQ.js → chunk-QSIXNTRV.js} +4 -4
- package/dist/{chunk-VSEBFHAY.js → chunk-RGLFV4KO.js} +11369 -10218
- package/dist/chunk-RGLFV4KO.js.map +1 -0
- package/dist/{chunk-D4N2V43Z.js → chunk-SGR7ZAVE.js} +13 -7
- package/dist/chunk-SGR7ZAVE.js.map +1 -0
- package/dist/{chunk-GV56WGL2.js → chunk-SMHAYK6I.js} +1036 -883
- package/dist/chunk-SMHAYK6I.js.map +1 -0
- package/dist/{chunk-JPQDNYXH.js → chunk-STPGIKPY.js} +8 -2
- package/dist/chunk-STPGIKPY.js.map +1 -0
- package/dist/{chunk-NSBXVPZL.js → chunk-U22TOL5Y.js} +17 -17
- package/dist/{chunk-NGTVREIH.js → chunk-U6IHLEWT.js} +2 -2
- package/dist/{chunk-ODRPL3WB.js → chunk-UUCCV3SI.js} +2 -2
- package/dist/{chunk-MSRU4D4P.js → chunk-UXMCHBOJ.js} +2 -2
- package/dist/{chunk-B7XYNRJQ.js → chunk-VFAKGIDG.js} +2 -2
- package/dist/{chunk-QCHVR4ZM.js → chunk-VM7VAFJW.js} +33 -7
- package/dist/chunk-VM7VAFJW.js.map +1 -0
- package/dist/{chunk-VQK4VHLF.js → chunk-YQV75FIL.js} +2 -2
- package/dist/chunk-YUTVAMWW.js +2 -0
- package/dist/{cli-4MF37HAQ.js → cli-4CR7QIOK.js} +26 -25
- package/dist/{cli-4MF37HAQ.js.map → cli-4CR7QIOK.js.map} +1 -1
- package/dist/{cli-6KZTHWGP.js → cli-6R4W3HAH.js} +37 -36
- package/dist/{cli-6KZTHWGP.js.map → cli-6R4W3HAH.js.map} +1 -1
- package/dist/{cli-I62SRH3R.js → cli-BOMA2FMP.js} +14 -13
- package/dist/{cli-DRMZBZLB.js → cli-EDQPQOCE.js} +43 -42
- package/dist/{cli-DRMZBZLB.js.map → cli-EDQPQOCE.js.map} +1 -1
- package/dist/{cli-VID7PJS3.js → cli-GBF76EXT.js} +23 -22
- package/dist/{cli-VID7PJS3.js.map → cli-GBF76EXT.js.map} +1 -1
- package/dist/{cli-3BTCK4AB.js → cli-MQYCF3SR.js} +27 -26
- package/dist/{cli-3BTCK4AB.js.map → cli-MQYCF3SR.js.map} +1 -1
- package/dist/{cli-ONTC5PKT.js → cli-OJKFXQOM.js} +9 -9
- package/dist/{cli-VUKMWSSF.js → cli-PHZAO4LZ.js} +4 -4
- package/dist/{cli-RORDPAPE.js → cli-PTKFFNOW.js} +59 -38
- package/dist/cli-PTKFFNOW.js.map +1 -0
- package/dist/{cli-O4ABTN4Z.js → cli-UW2K5Z5J.js} +31 -30
- package/dist/{cli-O4ABTN4Z.js.map → cli-UW2K5Z5J.js.map} +1 -1
- package/dist/{cli-JJMOVIKS.js → cli-XXTNPPKB.js} +14 -14
- package/dist/cli.js +19 -13
- package/dist/cli.js.map +1 -1
- package/dist/{config-XDA42RJL.js → config-JJW75SBX.js} +5 -5
- package/dist/docmeta.js +13 -12
- package/dist/docmeta.js.map +1 -1
- package/dist/github-6VQKSB67.js +35 -0
- package/dist/github-RBSEM7ZK.js +30 -0
- package/dist/graph/runtime.d.ts +4 -1
- package/dist/graph/runtime.js +20 -9
- package/dist/graph/runtime.js.map +1 -1
- package/dist/{host-6GURH5HE.js → host-YSTYO5DX.js} +3 -3
- package/dist/index.d.ts +192 -26
- package/dist/index.js +129 -124
- package/dist/index.js.map +1 -1
- package/dist/{json-BXY44ED7.js → json-PU2HLHDQ.js} +18 -17
- package/dist/labels-SJNSOPBI.js +73 -0
- package/dist/labels-SJNSOPBI.js.map +1 -0
- package/dist/lint-KIVTHLGU.js +34 -0
- package/dist/list-RDEJDDJF.js +32 -0
- package/dist/list-SUTDWL2J.js +35 -0
- package/dist/{page-EV7OUBAU.js → page-UMAA3NCM.js} +18 -16
- package/dist/{prepare-JHJDJB6I.js → prepare-3I3LOXXD.js} +22 -21
- package/dist/{prepare-JHJDJB6I.js.map → prepare-3I3LOXXD.js.map} +1 -1
- package/dist/{pretty-SCRK66M5.js → pretty-ANLRHU4O.js} +18 -17
- package/dist/{pretty-Q5Y2PA64.js → pretty-Q3ZFKOR7.js} +18 -17
- package/dist/{provider-527CO4DM.js → provider-LBX4IXGX.js} +3 -3
- package/dist/{release-3D5PK6M7.js → release-VV3UTKE5.js} +3 -3
- package/dist/{reporters-M6LJ2IYU.js → reporters-26H3N2KW.js} +3 -3
- package/dist/{reporters-RBYTASMI.js → reporters-ILT36CIH.js} +7 -7
- package/dist/{reporters-A5ADKDYR.js → reporters-PNDLWT6K.js} +16 -15
- package/dist/run-QXCK33Z4.js +37 -0
- package/dist/{term-CQAGNG3Q.js → term-D2N7UN4P.js} +981 -141
- package/dist/term-D2N7UN4P.js.map +1 -0
- package/dist/validate-BRUCOT2O.js +19 -0
- package/package.json +3 -2
- package/plugin/manni/.claude-plugin/plugin.json +1 -1
- package/shapes/graph/shapes-1.1.0.ttl +785 -0
- package/dist/build-QSPNK5AL.js +0 -35
- package/dist/calibrate-KXN4URPM.js +0 -40
- package/dist/capture-JHTSUPUC.js +0 -37
- package/dist/check-MDGXEUWL.js +0 -20
- package/dist/check-WOQRKNZK.js +0 -29
- package/dist/chunk-2DRHT73U.js.map +0 -1
- package/dist/chunk-2IAZEB45.js.map +0 -1
- package/dist/chunk-2MJ62AYQ.js.map +0 -1
- package/dist/chunk-4VBSTXN6.js +0 -392
- package/dist/chunk-4VBSTXN6.js.map +0 -1
- package/dist/chunk-6HWBRZIN.js.map +0 -1
- package/dist/chunk-BKVHX6FU.js.map +0 -1
- package/dist/chunk-D4N2V43Z.js.map +0 -1
- package/dist/chunk-EFW7CAG4.js +0 -387
- package/dist/chunk-EFW7CAG4.js.map +0 -1
- package/dist/chunk-GV56WGL2.js.map +0 -1
- package/dist/chunk-HQR2ZBHW.js.map +0 -1
- package/dist/chunk-J6IDQGJL.js.map +0 -1
- package/dist/chunk-JPQDNYXH.js.map +0 -1
- package/dist/chunk-JROBZ7JA.js +0 -818
- package/dist/chunk-JROBZ7JA.js.map +0 -1
- package/dist/chunk-PCQ7ELJH.js.map +0 -1
- package/dist/chunk-QCHVR4ZM.js.map +0 -1
- package/dist/chunk-QLWC7MKD.js.map +0 -1
- package/dist/chunk-TU2WUBVZ.js +0 -2
- package/dist/chunk-VSEBFHAY.js.map +0 -1
- package/dist/chunk-Y6DOMTQD.js.map +0 -1
- package/dist/cli-RORDPAPE.js.map +0 -1
- package/dist/github-RY3FRA6P.js +0 -29
- package/dist/github-YKQSH7FS.js +0 -34
- package/dist/lint-YJ2L22BW.js +0 -33
- package/dist/list-NSG24VVX.js +0 -31
- package/dist/list-V6EGCSHX.js +0 -34
- package/dist/run-BUE2DDXN.js +0 -36
- package/dist/term-CQAGNG3Q.js.map +0 -1
- package/dist/validate-ZBW44RHT.js +0 -18
- /package/dist/{batch-UAULUMGH.js.map → batch-EFSFG6GC.js.map} +0 -0
- /package/dist/{build-QSPNK5AL.js.map → build-NIO3UIWJ.js.map} +0 -0
- /package/dist/{calibrate-KXN4URPM.js.map → calibrate-6VO7URRV.js.map} +0 -0
- /package/dist/{capture-JHTSUPUC.js.map → capture-NMBVJO3C.js.map} +0 -0
- /package/dist/{check-MDGXEUWL.js.map → check-SHOYX2B5.js.map} +0 -0
- /package/dist/{check-WOQRKNZK.js.map → check-XMJKH3KV.js.map} +0 -0
- /package/dist/{check-YEOYBFST.js.map → check-ZMO3ZLMW.js.map} +0 -0
- /package/dist/{chunk-M42DZCOU.js.map → chunk-2OZF2VUB.js.map} +0 -0
- /package/dist/{chunk-U7CTFN2J.js.map → chunk-42VFJOAF.js.map} +0 -0
- /package/dist/{chunk-LBSCW232.js.map → chunk-4Q24OYI3.js.map} +0 -0
- /package/dist/{chunk-OPXWPJDA.js.map → chunk-4WJTURRO.js.map} +0 -0
- /package/dist/{chunk-GDVZ5VII.js.map → chunk-5SID2SVL.js.map} +0 -0
- /package/dist/{chunk-FUCPZVRY.js.map → chunk-AANUY4BH.js.map} +0 -0
- /package/dist/{chunk-WDWXAYVH.js.map → chunk-AYVKN3PG.js.map} +0 -0
- /package/dist/{chunk-FQXWVS6J.js.map → chunk-CH6IOGXV.js.map} +0 -0
- /package/dist/{chunk-4CK6ZSOK.js.map → chunk-D5Z6B4M7.js.map} +0 -0
- /package/dist/{chunk-HA6MQMOY.js.map → chunk-D6SELXQ2.js.map} +0 -0
- /package/dist/{chunk-PCS4VJBV.js.map → chunk-DGRLHDM4.js.map} +0 -0
- /package/dist/{chunk-KGEQJ5CC.js.map → chunk-F564FHMQ.js.map} +0 -0
- /package/dist/{chunk-IGSHYP74.js.map → chunk-G3MBUL5M.js.map} +0 -0
- /package/dist/{chunk-ADMEPUBT.js.map → chunk-GQ3KRY3B.js.map} +0 -0
- /package/dist/{chunk-T7JAOYE5.js.map → chunk-HDPN46JP.js.map} +0 -0
- /package/dist/{chunk-R4WXQIOZ.js.map → chunk-IQQAJROD.js.map} +0 -0
- /package/dist/{chunk-2IR4T5PO.js.map → chunk-IZXN3WI6.js.map} +0 -0
- /package/dist/{chunk-NCPWXHDO.js.map → chunk-JEUFYSFQ.js.map} +0 -0
- /package/dist/{chunk-LKP7QDFN.js.map → chunk-JSSM7VVV.js.map} +0 -0
- /package/dist/{chunk-EIFCP6CZ.js.map → chunk-KGFSPJLD.js.map} +0 -0
- /package/dist/{chunk-RLT5SEML.js.map → chunk-KMORGMCW.js.map} +0 -0
- /package/dist/{chunk-WQWKYAAK.js.map → chunk-NUQF5F5J.js.map} +0 -0
- /package/dist/{chunk-54F74XR3.js.map → chunk-NZ6KSHFD.js.map} +0 -0
- /package/dist/{chunk-4D5IZSXM.js.map → chunk-OHUDZRLK.js.map} +0 -0
- /package/dist/{chunk-FBMZJEB3.js.map → chunk-OKMTUAWO.js.map} +0 -0
- /package/dist/{chunk-BBT6AVUG.js.map → chunk-QMY57PVW.js.map} +0 -0
- /package/dist/{chunk-LPIF5LIE.js.map → chunk-QNDDPXFR.js.map} +0 -0
- /package/dist/{chunk-PWBH7DCQ.js.map → chunk-QSIXNTRV.js.map} +0 -0
- /package/dist/{chunk-NSBXVPZL.js.map → chunk-U22TOL5Y.js.map} +0 -0
- /package/dist/{chunk-NGTVREIH.js.map → chunk-U6IHLEWT.js.map} +0 -0
- /package/dist/{chunk-ODRPL3WB.js.map → chunk-UUCCV3SI.js.map} +0 -0
- /package/dist/{chunk-MSRU4D4P.js.map → chunk-UXMCHBOJ.js.map} +0 -0
- /package/dist/{chunk-B7XYNRJQ.js.map → chunk-VFAKGIDG.js.map} +0 -0
- /package/dist/{chunk-VQK4VHLF.js.map → chunk-YQV75FIL.js.map} +0 -0
- /package/dist/{chunk-TU2WUBVZ.js.map → chunk-YUTVAMWW.js.map} +0 -0
- /package/dist/{cli-I62SRH3R.js.map → cli-BOMA2FMP.js.map} +0 -0
- /package/dist/{cli-ONTC5PKT.js.map → cli-OJKFXQOM.js.map} +0 -0
- /package/dist/{cli-VUKMWSSF.js.map → cli-PHZAO4LZ.js.map} +0 -0
- /package/dist/{cli-JJMOVIKS.js.map → cli-XXTNPPKB.js.map} +0 -0
- /package/dist/{config-XDA42RJL.js.map → config-JJW75SBX.js.map} +0 -0
- /package/dist/{github-RY3FRA6P.js.map → github-6VQKSB67.js.map} +0 -0
- /package/dist/{github-YKQSH7FS.js.map → github-RBSEM7ZK.js.map} +0 -0
- /package/dist/{host-6GURH5HE.js.map → host-YSTYO5DX.js.map} +0 -0
- /package/dist/{json-BXY44ED7.js.map → json-PU2HLHDQ.js.map} +0 -0
- /package/dist/{lint-YJ2L22BW.js.map → lint-KIVTHLGU.js.map} +0 -0
- /package/dist/{list-NSG24VVX.js.map → list-RDEJDDJF.js.map} +0 -0
- /package/dist/{list-V6EGCSHX.js.map → list-SUTDWL2J.js.map} +0 -0
- /package/dist/{page-EV7OUBAU.js.map → page-UMAA3NCM.js.map} +0 -0
- /package/dist/{pretty-Q5Y2PA64.js.map → pretty-ANLRHU4O.js.map} +0 -0
- /package/dist/{pretty-SCRK66M5.js.map → pretty-Q3ZFKOR7.js.map} +0 -0
- /package/dist/{provider-527CO4DM.js.map → provider-LBX4IXGX.js.map} +0 -0
- /package/dist/{release-3D5PK6M7.js.map → release-VV3UTKE5.js.map} +0 -0
- /package/dist/{reporters-A5ADKDYR.js.map → reporters-26H3N2KW.js.map} +0 -0
- /package/dist/{reporters-M6LJ2IYU.js.map → reporters-ILT36CIH.js.map} +0 -0
- /package/dist/{reporters-RBYTASMI.js.map → reporters-PNDLWT6K.js.map} +0 -0
- /package/dist/{run-BUE2DDXN.js.map → run-QXCK33Z4.js.map} +0 -0
- /package/dist/{validate-ZBW44RHT.js.map → validate-BRUCOT2O.js.map} +0 -0
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/graph/commands/build.ts","../src/graph/core/analyze.ts","../src/graph/core/analyze-cache.ts","../src/graph/core/localizations.ts","../src/graph/core/derive.ts","../src/graph/core/discover.ts","../src/graph/core/emit.ts","../src/graph/core/harvest.ts","../src/graph/core/git.ts","../src/graph/core/graph-output.ts","../src/graph/core/external.ts"],"sourcesContent":["/**\n * `manni graph build` — derive the knowledge graph from discovered docs and write\n * deterministic Turtle. Running twice over unchanged inputs produces\n * byte-identical output.\n */\nimport { mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, resolve } from \"node:path\";\nimport { GraphError } from \"../types.js\";\nimport { analyzeDoc } from \"../core/analyze.js\";\nimport { ANALYZE_CACHE_DIR, AnalyzeCache } from \"../core/analyze-cache.js\";\nimport { loadRunConfig } from \"../core/config.js\";\nimport { deriveGraph } from \"../core/derive.js\";\nimport {\n assertInputFormat,\n documentBase,\n documentSetPatterns,\n resolveDocumentSet,\n routesFrom,\n STDIN,\n type DocumentInputOptions,\n} from \"../core/discover.js\";\nimport { STDIN_PATH } from \"../core/iri.js\";\nimport { emitTurtle } from \"../core/emit.js\";\nimport { harvestWarnings } from \"../core/harvest.js\";\nimport { collectGitHistory } from \"../core/git.js\";\nimport { suppressGraphOutput } from \"../core/graph-output.js\";\nimport { openMetaView, withExternalMetadata } from \"../core/external.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\nimport pkg from \"../../../package.json\" with { type: \"json\" };\n\nexport interface BuildOptions extends DocumentInputOptions {\n /** Output path override (default: config `out`). */\n out?: string;\n cwd?: string;\n /**\n * What `-` reads: the document from stdin, read by the caller. Required\n * when `paths` holds `-`. Its display path is `<stdin>`, its node is\n * `{baseIri}stdin`, and its links resolve from `cwd`.\n */\n stdinContent?: string;\n /** `--allow-empty`: zero matched files writes an empty graph, not an error. */\n allowEmpty?: boolean;\n}\n\n/**\n * What a run that wanted git history and could not have it is told. Said once,\n * through `warn()` at the CLI edge: git is detected now rather than switched\n * (proposal 0051 §6), so the degradation graph ADR 01010 built the warnings\n * channel for is all that is left of the tri-state.\n *\n * The reason travels with the sentence. Detection removed the user's way of\n * saying \"I require this\", so the warning is the only thing standing between a\n * CI runner that lost git and a quietly thinner graph — and \"not a repository\"\n * wants a different fix from \"git is not on PATH\" or \"`git log` timed out\".\n */\nexport const GIT_ABSENT_WARNING =\n \"the graph has no revision history or commit agents\";\n\nexport function gitAbsentWarning(reason: string): string {\n return `${GIT_ABSENT_WARNING}: ${reason}`;\n}\n\nexport interface BuildResult {\n outPath: string;\n docs: number;\n quads: number;\n /**\n * Non-fatal diagnostics: the build succeeded, but something it would have\n * done by default could not run (see ADR 01010). Rendered to stderr by the\n * CLI; never affects the exit code.\n */\n warnings: string[];\n}\n\n/** The build with its Turtle in hand, before anything is written. */\nexport interface BuiltGraph extends BuildResult {\n turtle: string;\n}\n\nexport async function runBuild(opts: BuildOptions = {}): Promise<BuildResult> {\n const { turtle, ...result } = await buildGraph(opts);\n mkdirSync(dirname(result.outPath), { recursive: true });\n writeFileSync(result.outPath, turtle, \"utf8\");\n return result;\n}\n\n/**\n * `runBuild` without the write: the graph as Turtle, in memory. `manni check`\n * builds the graph this way and checks it, writing no file.\n */\nexport async function buildGraph(opts: BuildOptions = {}): Promise<BuiltGraph> {\n const cwd = opts.cwd ?? process.cwd();\n const config = loadRunConfig(\n {\n ...(opts.config === undefined ? {} : { configPath: opts.config }),\n ...(opts.noConfig === undefined ? {} : { noConfig: opts.noConfig }),\n ...(opts.paths === undefined ? {} : { paths: opts.paths }),\n ...(opts.collection === undefined ? {} : { collection: opts.collection }),\n },\n cwd,\n );\n\n const format = assertInputFormat(opts.paths ?? [], opts.as);\n // Collection pages are labelled from the config's directory and typed paths\n // from cwd, as meta labels them. Every read below resolves from `base`.\n const base = documentBase(config, opts, cwd);\n const files = resolveDocumentSet(config, opts, \"build\", cwd, base);\n const usingStdin = (opts.paths ?? []).includes(STDIN);\n const outPath = resolve(cwd, opts.out ?? config.out);\n if (files.length === 0 && !usingStdin) {\n if (opts.allowEmpty) {\n // Zero documents is an empty graph, written where the graph goes, so a\n // later step that reads it finds a file rather than a stale one.\n return { outPath, docs: 0, quads: 0, warnings: [], turtle: emitTurtle([]) };\n }\n throw new GraphError(\n `No input files matched: ${documentSetPatterns(config, opts).join(\", \")} (cwd: ${cwd})`,\n );\n }\n if (usingStdin && opts.stdinContent === undefined) {\n throw new GraphError(\"graph build was given `-` but no stdin content.\");\n }\n\n const allPaths = new Set(usingStdin ? [...files, STDIN_PATH] : files);\n // Each page's body parse is cached across runs (`analyze-cache.ts`). Link\n // resolution against `allPaths` and `routes` still runs on every build.\n const cache = new AnalyzeCache(resolve(cwd, ANALYZE_CACHE_DIR));\n const analyzeOptions = {\n routes: routesFrom(config, base),\n ...(format === undefined ? {} : { format }),\n parse: cache.parse,\n };\n const read = files.map((path) =>\n analyzeDoc(readFileSync(resolve(base, path), \"utf8\"), path, allPaths, analyzeOptions),\n );\n if (usingStdin && opts.stdinContent !== undefined) {\n read.push(analyzeDoc(opts.stdinContent, STDIN_PATH, allPaths, analyzeOptions));\n }\n\n // A page's metadata is what `manni meta validate` reads: its frontmatter\n // plus every key a manifest of its collections owns (proposal 0047), merged\n // through meta's own merge. Read from meta's section of the same config the\n // output marks come from, so one file answers both.\n const view = await openMetaView(\n {\n ...(opts.config === undefined ? {} : { configPath: opts.config }),\n ...(opts.noConfig === undefined ? {} : { noConfig: opts.noConfig }),\n },\n cwd,\n files,\n base,\n );\n const merged = await withExternalMetadata(read, view);\n\n // What the graph carries is the schema's call (proposal 0051 §5): a top-level\n // field marked `x-manni-graph-output: false` is dropped here, before derivation,\n // and the schemas are the set `manni meta validate` resolves (proposal 0074),\n // so it reaches none of Turtle, JSON-LD, iiRDS or the search index. All four\n // read what `deriveGraph` produces, so one filter at the fan-in is the whole\n // mechanism; suppressing a field downstream would be triple surgery in four\n // places. It runs after the merge, so a field kept in a manifest is filtered\n // by the same mark as one kept on the page.\n const docs = await suppressGraphOutput(merged, view);\n\n // Page-level keys that look like harvest inputs but are not. The graph block\n // is schema-strict, so a typo there is a hard error; at the page level\n // nothing validates, and a near miss derives silently nothing (ADR 01028).\n const warnings: string[] = harvestWarnings(docs);\n // The git pass only feeds the provenance derive source, so the subprocess is\n // skipped entirely when that source is off. Otherwise git is *detected*\n // (proposal 0051 §6): history is used wherever git can run over a\n // repository, and a run that would have used it and cannot says so once and\n // builds the rest — graph ADR 01010's degradation, without its switch.\n let gitHistory: Awaited<ReturnType<typeof collectGitHistory>> | undefined;\n if (config.build.derive.includes(\"provenance\")) {\n try {\n gitHistory = await collectGitHistory(base);\n } catch (e) {\n warnings.push(gitAbsentWarning(errorMessage(e)));\n }\n }\n\n const quads = deriveGraph(docs, {\n baseIri: config.baseIri,\n derive: config.build.derive,\n // The package version, stamped on the build agent (graph:version). One\n // package, one version: the tool no longer has one of its own.\n toolVersion: pkg.version,\n gitHistory,\n qualified: config.provenance.qualified,\n });\n const turtle = emitTurtle(quads);\n await cache.flush();\n\n return { outPath, docs: docs.length, quads: quads.length, warnings, turtle };\n}\n","/**\n * Document analysis: one source file → a `DocModel`. Metadata comes from the\n * metadata tool's extractor (the same one `manni meta validate` reads a page\n * with). Markdown and MDX body structure (headings, links, images, code\n * fences) comes from a remark/mdast walk in document order; every other format\n * comes from lint's section tree (proposal 0077 §2).\n */\nimport { createHash } from \"node:crypto\";\nimport { extname } from \"node:path\";\nimport { unified } from \"unified\";\nimport remarkParse from \"remark-parse\";\nimport remarkGfm from \"remark-gfm\";\nimport remarkFrontmatter from \"remark-frontmatter\";\nimport remarkMdx from \"remark-mdx\";\nimport { toString as mdastToString } from \"mdast-util-to-string\";\nimport GithubSlugger from \"github-slugger\";\nimport {\n extractFrontmatter,\n extractorForExtension,\n type MetadataExtractor,\n} from \"../../meta/index.js\";\nimport { parserByName, parserForExtension } from \"../../lint/parsers/index.js\";\nimport type {\n ContentNode,\n DocumentTree,\n SectionNode,\n} from \"../../lint/types.js\";\nimport type { Root, RootContent, Definition } from \"mdast\";\nimport { errorMessage } from \"../../shared/errors.js\";\nimport { GraphError } from \"../types.js\";\nimport type { DocImage, DocLink, DocModel, Section } from \"../types.js\";\nimport {\n DEFAULT_INDEX_FILES,\n DEFAULT_LINK_EXTENSIONS,\n type RouteMapping,\n} from \"./config.js\";\nimport { normalizeDocPath } from \"./iri.js\";\n\n/** The formats graph parses, as `--as` names them: lint's parser names. */\nexport const DOC_FORMATS = [\n \"asciidoc\",\n \"html\",\n \"markdown\",\n \"mdx\",\n \"rst\",\n \"xml\",\n] as const;\nexport type DocFormat = (typeof DOC_FORMATS)[number];\n/** The formats read through lint's tree rather than graph's mdast walk. */\nexport type TreeFormat = Exclude<DocFormat, \"markdown\" | \"mdx\">;\n\nexport function isTreeFormat(format: DocFormat): format is TreeFormat {\n return format !== \"markdown\" && format !== \"mdx\";\n}\n\nexport function isDocFormat(name: string): name is DocFormat {\n return (DOC_FORMATS as readonly string[]).includes(name);\n}\n\n/**\n * The format a page parses as: `format` (`--as`) when given, else the lint\n * parser claiming its extension. An extension nobody claims reaches here only\n * through `--ext`, and reads as markdown, as every page did before 0077.\n */\nexport function formatOf(path: string, format?: DocFormat): DocFormat {\n if (format !== undefined) return format;\n const name = parserForExtension(extname(path))?.name;\n return name !== undefined && isDocFormat(name) ? name : \"markdown\";\n}\n\nexport interface AnalyzeOptions {\n /** Site-route mappings for resolving root-absolute links. */\n routes?: RouteMapping[];\n /** `--as`: parse as this format whatever the path says. Absent, see `formatOf`. */\n format?: DocFormat;\n /**\n * How the body is parsed. Absent, `parseBody`. `graph build` passes a cache's\n * `parse` here, which returns what `parseBody` would (`analyze-cache.ts`).\n */\n parse?: (content: string, path: string, format: DocFormat) => DocBody;\n}\n\n/**\n * What a page's body yields before anything else in the corpus is consulted:\n * headings, and link and image targets as written, in document order.\n *\n * A pure function of the bytes and the format, so it can be cached across\n * runs. Resolving a target needs the rest of the corpus and the routes, so\n * that happens after, in `analyzeDoc`.\n */\nexport interface DocBody {\n firstH1?: string;\n sections: Section[];\n /** Raw link targets: links, resolved link references, and JSX `href`s. */\n linkTargets: string[];\n /** Raw image targets: images, resolved image references, and JSX `src`s. */\n imageTargets: string[];\n /** Code fence languages, sorted and distinct. */\n codeLanguages: string[];\n}\n\nconst processor = unified()\n .use(remarkParse)\n .use(remarkGfm)\n .use(remarkFrontmatter, [\"yaml\", \"toml\"]);\n\n/**\n * MDX gets its own processor, selected by extension (ADR 01022). It cannot be\n * the default: MDX reads `{` as an expression delimiter, so ordinary Markdown\n * prose containing braces would become a syntax error.\n */\nconst mdxProcessor = unified()\n .use(remarkParse)\n .use(remarkGfm)\n .use(remarkFrontmatter, [\"yaml\", \"toml\"])\n .use(remarkMdx);\n\n/** MDX JSX attribute, narrowed to the literal-string case we can act on. */\ninterface JsxAttribute {\n type: string;\n name?: string;\n value?: unknown;\n}\n\n/**\n * Elements whose `src` is an image.\n *\n * `href` is HTML's hyperlink attribute wherever it appears, so reading it from\n * any element only ever yields an extra edge. `src` is not analogous: it is the\n * generic external-resource attribute, shared by `iframe`, `video`, `script`,\n * `audio`, `source`, and `embed`. Emitting `schema:image` for a video embed or\n * an analytics script would be a wrong *type* assertion rather than a merely\n * extra one, so `src` is read only where it means an image (ADR 01022).\n */\nconst IMAGE_ELEMENTS = new Set([\"img\", \"image\"]);\n\n/**\n * The value of a JSX attribute, when it is a plain string literal.\n *\n * An expression attribute (`href={route}`) yields undefined rather than a\n * guess: its value is not knowable without evaluating the module, and a wrong\n * edge asserted confidently is worse than an absent one.\n */\nfunction jsxAttributeValue(\n node: unknown,\n attributeName: string,\n): string | undefined {\n const attributes = (node as { attributes?: JsxAttribute[] }).attributes;\n if (!Array.isArray(attributes)) return undefined;\n for (const attribute of attributes) {\n if (attribute.type !== \"mdxJsxAttribute\") continue;\n if (attribute.name !== attributeName) continue;\n return typeof attribute.value === \"string\" ? attribute.value : undefined;\n }\n return undefined;\n}\n\n/** True when the target has a URI scheme (http:, https:, mailto:, ...). */\nexport function hasScheme(target: string): boolean {\n return /^[a-z][a-z0-9+.-]*:/i.test(target);\n}\n\n/**\n * Resolve a relative link target against the linking doc's directory using\n * pure string math (posix, OS-independent). Returns null when the target\n * escapes the corpus root. A page labelled above the root (`../docs/a.md`)\n * already climbs, so its leading `..` segments are kept, never popped as if\n * they were directories, and its links may climb further.\n */\nexport function resolveRelative(\n docPath: string,\n target: string,\n): string | null {\n const baseSegments = normalizeDocPath(docPath).split(\"/\").slice(0, -1);\n const segments = [...baseSegments];\n for (const part of target.split(\"/\")) {\n if (part === \"\" || part === \".\") continue;\n if (part === \"..\") {\n if (segments.length === 0) return null;\n if (segments[segments.length - 1] === \"..\") segments.push(\"..\");\n else segments.pop();\n } else {\n segments.push(part);\n }\n }\n return segments.join(\"/\");\n}\n\nconst HAS_EXTENSION = /\\.[a-z0-9]+$/i;\n\n/**\n * Whether a link target addresses a *document* at all (ADR 01033).\n *\n * An extension list declares what documents look like in a corpus. A target\n * carrying some other explicit extension — `/manni/graph/ns.ttl`, `./dist.zip`, a\n * linked PDF — is a static asset the site serves, not a document dockg failed\n * to find, and reporting it as a broken link produces a finding the author\n * cannot act on: there is no `.md` they could add to fix it.\n *\n * Extensionless and directory targets stay in scope, so a genuine typo in a\n * pretty URL is still caught.\n */\nfunction addressesDocument(target: string, extensions: string[]): boolean {\n if (target === \"\" || !HAS_EXTENSION.test(target)) return true;\n // No configured extensions means the mapping has declared nothing about what\n // its documents look like — so there is no list to judge the target against,\n // and the narrowing does not apply. Gating on an empty list would answer \"no\"\n // to every extension-bearing target and skip genuinely broken `.md` links,\n // turning a narrowing into a way to switch the check off. `extensions: []` is\n // schema-valid (no minItems), so this is reachable config, not a theoretical.\n if (extensions.length === 0) return true;\n const ext = target.slice(target.lastIndexOf(\".\")).toLowerCase();\n return extensions.some((e) => e.toLowerCase() === ext);\n}\n\n/** Slug normalization for route matching: lowercase, dashes/underscores stripped. */\nfunction slugNorm(path: string): string {\n return path.toLowerCase().replace(/[-_]/g, \"\");\n}\n\n/**\n * Tiered lookup over the corpus: exact path, then case-insensitive, then\n * slug-normalized (published slugs are often kebab-cased versions of\n * camelCase filenames, e.g. Fern's /stop-record for stopRecord.mdx).\n * Ambiguous fallback matches (two files normalizing identically) stay\n * unresolved rather than guessing.\n */\nclass PathIndex {\n private readonly lower = new Map<string, string | null>();\n private readonly slugged = new Map<string, string | null>();\n\n constructor(private readonly exact: ReadonlySet<string>) {\n for (const path of exact) {\n const lower = path.toLowerCase();\n this.lower.set(lower, this.lower.has(lower) ? null : path);\n const slug = slugNorm(path);\n this.slugged.set(slug, this.slugged.has(slug) ? null : path);\n }\n }\n\n resolve(candidate: string): string | undefined {\n if (this.exact.has(candidate)) return candidate;\n return (\n this.lower.get(candidate.toLowerCase()) ??\n this.slugged.get(slugNorm(candidate)) ??\n undefined\n );\n }\n}\n\n/** decodeURIComponent that falls back to the raw string on malformed input. */\nfunction safeDecode(value: string): string {\n try {\n return decodeURIComponent(value);\n } catch {\n return value;\n }\n}\n\n/**\n * Candidate repo paths for an extensionless (or extension-bearing) link\n * target. Shared by route and relative resolution so both link forms resolve\n * identically: an explicit extension is taken verbatim; a trailing slash\n * prefers the directory's index files but falls back to extension candidates\n * (pretty URLs — Hugo/Docusaurus serve foo.md at /foo/); otherwise extensions\n * are tried before index files.\n */\nfunction targetCandidates(\n target: string,\n isDirectory: boolean,\n extensions: string[],\n indexFiles: string[],\n): string[] {\n if (target !== \"\" && HAS_EXTENSION.test(target)) return [target];\n const extensionCandidates =\n target === \"\" ? [] : extensions.map((ext) => `${target}${ext}`);\n const dir = target === \"\" ? \"\" : `${target}/`;\n const indexCandidates: string[] = [];\n for (const indexFile of indexFiles) {\n for (const ext of extensions)\n indexCandidates.push(`${dir}${indexFile}${ext}`);\n }\n return isDirectory\n ? [...indexCandidates, ...extensionCandidates]\n : [...extensionCandidates, ...indexCandidates];\n}\n\n/**\n * The language labelling a source path, from the nearest enclosing route\n * mapping that declares one (ADR 01037).\n *\n * \"Nearest\" is the longest matching `root`, so a `docs/de` mapping beats a\n * `docs` one for a file under both. A mapping that declares no language is\n * transparent rather than blocking: `{root: docs, language: en}` plus\n * `{root: docs/api}` still labels `docs/api/x.md` as English, the way a nested\n * directory inherits the setting of its parent.\n */\nexport function routeLanguageFor(\n path: string,\n routes: readonly RouteMapping[],\n): string | undefined {\n let best: { root: string; language: string } | undefined;\n for (const mapping of routes) {\n if (mapping.language === undefined) continue;\n const root = mapping.root;\n const covers = root === \"\" || path === root || path.startsWith(`${root}/`);\n if (!covers) continue;\n if (best === undefined || root.length > best.root.length) {\n best = { root, language: mapping.language };\n }\n }\n return best?.language;\n}\n\n/**\n * Resolve a root-absolute route (`/docs/actions/find`) to a source file via\n * the configured mappings. Returns the repo path, \"broken\" when a mapping's\n * basePath matched but no candidate file exists, or null when no mapping\n * covers the route.\n */\nfunction resolveRoute(\n pathPart: string,\n routes: RouteMapping[],\n index: PathIndex,\n): string | null {\n const isDirectory = /\\/+$/.test(pathPart);\n const clean = safeDecode(pathPart).replace(/\\/+$/, \"\");\n let anyMatched = false;\n for (const mapping of routes) {\n if (\n clean !== mapping.basePath &&\n !clean.startsWith(`${mapping.basePath}/`)\n ) {\n continue;\n }\n // Matched the basePath, but this mapping's documents do not carry that\n // extension — so the mapping says nothing about this target. Leave\n // `anyMatched` alone: another mapping may still claim it, and if none\n // does the caller skips the link rather than calling it broken.\n const rest = clean.slice(mapping.basePath.length).replace(/^\\/+/, \"\");\n if (!addressesDocument(rest, mapping.extensions)) continue;\n anyMatched = true;\n const prefix = mapping.root ? `${mapping.root}/` : \"\";\n // Bare basePath targets the root directory itself (index files only).\n const stem = rest === \"\" ? mapping.root : `${prefix}${rest}`;\n const candidates = targetCandidates(\n stem,\n isDirectory || rest === \"\",\n mapping.extensions,\n mapping.indexFiles,\n );\n for (const candidate of candidates) {\n const resolved = index.resolve(candidate);\n if (resolved) return resolved;\n }\n }\n return anyMatched ? \"broken\" : null;\n}\n\n/** One PathIndex per corpus set — analyzeDoc is called once per doc over the same set. */\nconst indexCache = new WeakMap<ReadonlySet<string>, PathIndex>();\n\nfunction pathIndexFor(allPaths: ReadonlySet<string>): PathIndex {\n let index = indexCache.get(allPaths);\n if (!index) {\n index = new PathIndex(allPaths);\n indexCache.set(allPaths, index);\n }\n return index;\n}\n\nfunction classifyLink(\n docPath: string,\n rawTarget: string,\n allPaths: ReadonlySet<string>,\n routes: RouteMapping[],\n): DocLink | null {\n const raw = rawTarget;\n if (hasScheme(raw)) {\n try {\n return { raw, kind: \"external\", url: new URL(raw).href };\n } catch {\n // Scheme-bearing but unparseable — example junk, not a link. Skip.\n return null;\n }\n }\n const hashAt = raw.indexOf(\"#\");\n const pathPart = hashAt === -1 ? raw : raw.slice(0, hashAt);\n const anchor = hashAt === -1 ? undefined : raw.slice(hashAt + 1);\n if (pathPart === \"\") return null; // same-document anchor\n // Site-root-absolute URLs (/docs/x/) are published-site routes. With route\n // mappings configured they resolve to source files (or count as broken when\n // a mapped basePath has no matching file); unmapped routes are skipped.\n if (pathPart.startsWith(\"/\")) {\n const resolved = resolveRoute(pathPart, routes, pathIndexFor(allPaths));\n if (resolved === null) return null;\n if (resolved === \"broken\") return { raw, kind: \"broken\" };\n const link: DocLink = { raw, kind: \"internal\", resolvedPath: resolved };\n if (anchor) link.anchor = anchor;\n return link;\n }\n const resolved = resolveRelative(docPath, safeDecode(pathPart));\n if (resolved !== null) {\n const index = pathIndexFor(allPaths);\n let candidates: string[];\n if (allPaths.has(resolved)) {\n candidates = [resolved];\n } else if (HAS_EXTENSION.test(resolved)) {\n // Exact-or-broken — unless the extension is not a document extension at\n // all, in which case it is an asset and no document was ever addressed\n // (ADR 01033). Checked after `allPaths`, so an asset that IS in the\n // corpus still links.\n if (!addressesDocument(resolved, DEFAULT_LINK_EXTENSIONS)) return null;\n candidates = [];\n } else {\n candidates = targetCandidates(\n resolved,\n pathPart.endsWith(\"/\"),\n DEFAULT_LINK_EXTENSIONS,\n DEFAULT_INDEX_FILES,\n );\n }\n for (const candidate of candidates) {\n const hit = index.resolve(candidate);\n if (hit) {\n const link: DocLink = { raw, kind: \"internal\", resolvedPath: hit };\n if (anchor) link.anchor = anchor;\n return link;\n }\n }\n }\n return { raw, kind: \"broken\" };\n}\n\nfunction classifyImage(docPath: string, rawTarget: string): DocImage {\n if (hasScheme(rawTarget)) {\n return { raw: rawTarget, target: rawTarget, external: true };\n }\n const resolved = resolveRelative(docPath, rawTarget);\n return { raw: rawTarget, target: resolved ?? rawTarget, external: false };\n}\n\n/**\n * meta's extractor for a non-Markdown format. Lint's parser names are meta's\n * extractor names, so the parser's own extension finds the extractor under\n * `--as` too, where the path's would not.\n */\nexport function extractorFor(format: TreeFormat): MetadataExtractor | undefined {\n return extractorForExtension(parserByName(format)?.extensions[0] ?? \"\");\n}\n\n/**\n * A page's own metadata, as `manni meta validate` reads it. `build` reads a\n * page with it and `fill` reads what a page already holds with it, so the two\n * cannot disagree about a format.\n */\nexport function metadataOf(\n content: string,\n path: string,\n format: DocFormat,\n): { data: Record<string, unknown>; present: boolean } {\n try {\n const meta =\n format === \"markdown\" || format === \"mdx\"\n ? extractFrontmatter(content, \"markdown\")\n : extractorFor(format)?.extract(content, path);\n return meta === undefined\n ? { data: {}, present: false }\n : { data: meta.data, present: meta.present };\n } catch (error) {\n // The extractor knows the bytes, not the file. Left as it is, build and\n // fill would report a YAML error with no hint of which page carries it.\n throw new GraphError(`${path}: ${errorMessage(error)}`);\n }\n}\n\n/** Analyze one document. `allPaths` is the discovered corpus for link resolution. */\nexport function analyzeDoc(\n content: string,\n relPath: string,\n allPaths: ReadonlySet<string>,\n options: AnalyzeOptions = {},\n): DocModel {\n const routes = options.routes ?? [];\n const path = normalizeDocPath(relPath);\n const format = formatOf(path, options.format);\n const parse = options.parse ?? parseBody;\n // A tree format is parsed first, so a malformed page is reported as a parse\n // failure rather than as whatever the metadata reader tripped on. Markdown\n // keeps its order: its parse cannot fail where its frontmatter can.\n let body = isTreeFormat(format) ? parse(content, path, format) : undefined;\n const meta = metadataOf(content, path, format);\n body ??= parse(content, path, format);\n\n const links: DocLink[] = [];\n for (const target of body.linkTargets) {\n const link = classifyLink(path, target, allPaths, routes);\n if (link) links.push(link);\n }\n const routeLanguage = routeLanguageFor(path, routes);\n\n return {\n path,\n frontmatter: meta.data,\n frontmatterPresent: meta.present,\n format,\n firstH1: body.firstH1,\n sections: body.sections,\n links,\n images: body.imageTargets.map((target) => classifyImage(path, target)),\n codeLanguages: body.codeLanguages,\n // Omitted rather than set to undefined, so a doc under no localized route\n // carries no key at all — `routeLanguage` in JSON output means something.\n ...(routeLanguage === undefined ? {} : { routeLanguage }),\n // Over the content as read — line endings included, so the digest is\n // byte-faithful and equals `sha256sum <file>` for any valid-UTF-8 file\n // (ADR 01036). The CRLF corpus fixture depends on this not normalizing.\n contentHash: createHash(\"sha256\").update(content, \"utf8\").digest(\"hex\"),\n };\n}\n\n/** Parse a page's body into its `DocBody`. `path` only names the page in an error. */\nexport function parseBody(\n content: string,\n path: string,\n format: DocFormat,\n): DocBody {\n if (isTreeFormat(format)) return parseTreeBody(content, path, format);\n const isMdx = format === \"mdx\";\n let tree: Root;\n try {\n tree = (isMdx ? mdxProcessor : processor).parse(content);\n } catch (error) {\n // Parsing MDX makes parse *failures* possible where Markdown had none:\n // remark-parse accepts anything, the MDX extension does not. Left raw, the\n // micromark throw escapes cli.ts's `fail()` — which only converts\n // GraphError — so the CLI dumps a stack trace, exits 1 (the code the\n // contract reserves for findings), and never names the file. Convert it.\n if (!isMdx) throw error;\n const reason = errorMessage(error);\n throw new GraphError(`Could not parse MDX in ${path}: ${reason}`);\n }\n\n const sections: Section[] = [];\n const linkTargets: string[] = [];\n const imageTargets: string[] = [];\n const codeLanguages = new Set<string>();\n const definitions = new Map<string, Definition>();\n let firstH1: string | undefined;\n\n // First pass: collect reference-link definitions.\n visit(tree, (node) => {\n if (node.type === \"definition\") {\n const def = node;\n definitions.set(def.identifier, def);\n }\n });\n\n const slugger = new GithubSlugger();\n /** Stack of open sections: [level, slug]. */\n const stack: Array<{ level: number; slug: string }> = [];\n /** Child counters keyed by parent slug (\"\" = document). */\n const childCount = new Map<string, number>();\n\n visit(tree, (node) => {\n switch (node.type) {\n case \"heading\": {\n const level = (node as { depth: number }).depth;\n const title = mdastToString(node);\n const slug = slugger.slug(title);\n if (level === 1 && firstH1 === undefined) firstH1 = title;\n // Reading the top frame *is* the emptiness test, so what the loop pops\n // is what the loop looked at.\n for (\n let top = stack.at(-1);\n top !== undefined && top.level >= level;\n top = stack.at(-1)\n ) {\n stack.pop();\n }\n const parentSlug = stack.at(-1)?.slug ?? null;\n const parentKey = parentSlug ?? \"\";\n const order = (childCount.get(parentKey) ?? 0) + 1;\n childCount.set(parentKey, order);\n sections.push({ slug, title, level, order, parentSlug });\n stack.push({ level, slug });\n break;\n }\n case \"link\": {\n linkTargets.push((node as { url: string }).url);\n break;\n }\n case \"linkReference\": {\n const def = definitions.get(\n (node as { identifier: string }).identifier,\n );\n if (def) linkTargets.push(def.url);\n break;\n }\n case \"image\": {\n imageTargets.push((node as { url: string }).url);\n break;\n }\n case \"imageReference\": {\n const def = definitions.get(\n (node as { identifier: string }).identifier,\n );\n if (def) imageTargets.push(def.url);\n break;\n }\n case \"code\": {\n const lang = (node as { lang?: string | null }).lang;\n if (lang) codeLanguages.add(lang);\n break;\n }\n // A JSX element's `href` is a link and its `src` is an image, on any\n // element (ADR 01022). Those are HTML's own names for the relationships,\n // so this stays structural — dockg never learns what `<LinkCard>` means.\n case \"mdxJsxFlowElement\":\n case \"mdxJsxTextElement\": {\n const href = jsxAttributeValue(node, \"href\");\n if (href !== undefined) linkTargets.push(href);\n const name = (node as { name?: string | null }).name ?? \"\";\n if (IMAGE_ELEMENTS.has(name.toLowerCase())) {\n const src = jsxAttributeValue(node, \"src\");\n if (src !== undefined) imageTargets.push(src);\n }\n break;\n }\n }\n });\n\n return {\n firstH1,\n sections,\n linkTargets,\n imageTargets,\n codeLanguages: [...codeLanguages].sort(),\n };\n}\n\n/**\n * Lint's tree for `content`, parsed as `format`. A parser's throw names the\n * format and the file, and exits 2, as an MDX parse failure does.\n */\nexport function parseTree(\n content: string,\n path: string,\n format: TreeFormat,\n): DocumentTree {\n const parser = parserByName(format);\n if (parser === undefined) {\n throw new GraphError(`No parser reads ${format}.`);\n }\n try {\n return parser.parse(content, path);\n } catch (error) {\n throw new GraphError(\n `Could not parse ${format} in ${path}: ${errorMessage(error)}`,\n );\n }\n}\n\n/**\n * Characters an IRI fragment accepts unchanged: the XML NCName set plus `:`,\n * which covers HTML ids, DITA `@id`, `xml:id`, Asciidoctor's `_install` and\n * Sphinx labels. Anything else is slugged, because a section IRI is never\n * percent-encoded.\n */\nconst IRI_SAFE_ID = /^[A-Za-z_][A-Za-z0-9_.:-]*$/;\n\n/** The sections minted from a lint tree, and the content each one owns. */\nexport interface TreeSections {\n sections: Section[];\n /** The content each section owns, parallel to `sections`. */\n owned: ContentNode[][];\n /** Content no minted section owns: the lead's, and a skipped heading's. */\n unowned: ContentNode[];\n firstH1: string | undefined;\n}\n\n/**\n * Mint graph sections from lint's tree, in document order. `analyzeDoc` and\n * the search index both call it, so their anchors agree.\n *\n * The anchor is the source's own id verbatim when it is IRI-safe, so a link\n * written to `#GUID-A1B2-C3D4` reaches the section; else the slugged title.\n * Ids and slugs share one namespace per document, so a duplicate of either\n * kind gains a `-N` suffix rather than merging two sections into one node.\n *\n * The level-0 lead, a heading lint made from a metadata title, and an\n * untitled heading (a DITA map's `topicref` without a navtitle) are not\n * sections. Each is transparent: its content belongs to the document, and its\n * subsections nest under its own parent, as Markdown's do under no heading.\n */\nexport function mintTreeSections(roots: SectionNode[]): TreeSections {\n const out: TreeSections = {\n sections: [],\n owned: [],\n unowned: [],\n firstH1: undefined,\n };\n const slugger = new GithubSlugger();\n const taken = new Set<string>();\n const childCount = new Map<string, number>();\n\n const anchorFor = (node: SectionNode): string => {\n const id = node.id;\n // `prov.` fragments are the provenance nodes' (derive.ts), minted with a\n // dot precisely because a slug never holds one. A verbatim id may.\n if (id !== undefined && IRI_SAFE_ID.test(id) && !id.startsWith(\"prov.\")) {\n let anchor = id;\n for (let n = 1; taken.has(anchor); n++) anchor = `${id}-${String(n)}`;\n taken.add(anchor);\n return anchor;\n }\n // The slugger dedupes against its own output only, so a slug an earlier\n // verbatim id took is asked for again until it is free. Each call advances\n // the slugger's suffix (-1, -2, ...), which is what ends the loop.\n let anchor = slugger.slug(node.title);\n while (taken.has(anchor)) anchor = slugger.slug(node.title);\n taken.add(anchor);\n return anchor;\n };\n\n const walk = (nodes: SectionNode[], parentSlug: string | null): void => {\n for (const node of nodes) {\n if (node.level === 0 || node.synthetic || node.title.trim() === \"\") {\n out.unowned.push(...node.children);\n walk(node.sections, parentSlug);\n continue;\n }\n const slug = anchorFor(node);\n if (node.level === 1 && out.firstH1 === undefined) {\n out.firstH1 = node.title;\n }\n const parentKey = parentSlug ?? \"\";\n const order = (childCount.get(parentKey) ?? 0) + 1;\n childCount.set(parentKey, order);\n out.sections.push({\n slug,\n title: node.title,\n level: node.level,\n order,\n parentSlug,\n });\n out.owned.push(node.children);\n walk(node.sections, slug);\n }\n };\n walk(roots, null);\n return out;\n}\n\n/** Every content node, nested ones included, in document order. */\nfunction eachContent(\n nodes: readonly ContentNode[],\n fn: (node: ContentNode) => void,\n): void {\n for (const node of nodes) {\n fn(node);\n switch (node.kind) {\n case \"list\":\n for (const item of node.items) eachContent(item.children, fn);\n break;\n case \"table\":\n for (const row of node.children) {\n for (const cell of row.children) eachContent(cell.children, fn);\n }\n break;\n case \"definitionList\":\n for (const item of node.children) eachContent(item.definition, fn);\n break;\n case \"admonition\":\n case \"blockquote\":\n case \"element\":\n eachContent(node.children, fn);\n break;\n default:\n break;\n }\n }\n}\n\n/** Every content node a tree's sections own directly, whichever section. */\nfunction treeContent(sections: readonly SectionNode[]): ContentNode[] {\n return sections.flatMap((s) => [...s.children, ...treeContent(s.sections)]);\n}\n\n/** A non-Markdown page's body, from lint's tree. */\nfunction parseTreeBody(\n content: string,\n path: string,\n format: TreeFormat,\n): DocBody {\n const tree = parseTree(content, path, format);\n const minted = mintTreeSections(tree.sections);\n const imageTargets: string[] = [];\n const codeLanguages = new Set<string>();\n eachContent(treeContent(tree.sections), (node) => {\n if (node.kind === \"image\") imageTargets.push(node.url);\n else if (node.kind === \"codeBlock\" && node.language) {\n codeLanguages.add(node.language);\n }\n });\n return {\n ...(minted.firstH1 === undefined ? {} : { firstH1: minted.firstH1 }),\n sections: minted.sections,\n linkTargets: tree.links.map((l) => l.target),\n imageTargets,\n codeLanguages: [...codeLanguages].sort(),\n };\n}\n\n/** Minimal depth-first mdast walk in document order. */\nfunction visit(\n node: Root | RootContent,\n fn: (node: RootContent) => void,\n): void {\n const children = (node as { children?: RootContent[] }).children;\n if (!children) return;\n for (const child of children) {\n fn(child);\n visit(child, fn);\n }\n}\n","/**\n * The cross-run cache for page parses.\n *\n * Parsing the body is most of what `graph build` spends on a page, and most\n * pages do not change between runs. `manni check` builds the graph on every\n * agent stop, so the parse is cached: one JSON file per page label under\n * `.manni/graph/analyze-cache/`, overwritten when the page changes. The\n * cache therefore holds about one entry per page ever built here.\n *\n * Only `parseBody`'s output is stored, which is a pure function of the bytes\n * and the format. Frontmatter, link resolution against the corpus, routes,\n * the meta view and git history all run on every build, so nothing a cache\n * entry holds depends on another page or on the clock.\n *\n * A cache is an optimization: an unreadable, unparseable or malformed entry\n * is a miss, and a write that fails is dropped. Neither can fail a run.\n * Node-only: the runtime and embed bundles never import it.\n */\nimport { createHash } from \"node:crypto\";\nimport { mkdir } from \"node:fs/promises\";\nimport { readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { writeTextAtomic } from \"../../shared/write-file.js\";\nimport pkg from \"../../../package.json\" with { type: \"json\" };\nimport { parseBody, type DocBody, type DocFormat } from \"./analyze.js\";\n\n/**\n * Where the cache lives, relative to the working directory, beside the\n * `fill` proposal cache (`.manni/graph/cache`) and the `embed` vector cache.\n */\nexport const ANALYZE_CACHE_DIR = \".manni/graph/analyze-cache\";\n\n/**\n * The entry format. Bump it when `parseBody` changes what it returns, so a\n * development build does not read entries an older parse wrote under the\n * same package version.\n */\nconst ENTRY_VERSION = 1;\n\nfunction sha256(text: string): string {\n return createHash(\"sha256\").update(text, \"utf8\").digest(\"hex\");\n}\n\nconst isStrings = (value: unknown): value is string[] =>\n Array.isArray(value) && value.every((v) => typeof v === \"string\");\n\nfunction isSection(value: unknown): boolean {\n if (typeof value !== \"object\" || value === null) return false;\n const s = value as Record<string, unknown>;\n return (\n typeof s.slug === \"string\" &&\n typeof s.title === \"string\" &&\n typeof s.level === \"number\" &&\n typeof s.order === \"number\" &&\n (s.parentSlug === null || typeof s.parentSlug === \"string\")\n );\n}\n\nfunction isDocBody(value: unknown): value is DocBody {\n if (typeof value !== \"object\" || value === null) return false;\n const b = value as Record<string, unknown>;\n return (\n (b.firstH1 === undefined || typeof b.firstH1 === \"string\") &&\n Array.isArray(b.sections) &&\n b.sections.every(isSection) &&\n isStrings(b.linkTargets) &&\n isStrings(b.imageTargets) &&\n isStrings(b.codeLanguages)\n );\n}\n\nexport class AnalyzeCache {\n /** Pages this run served from the cache. */\n hits = 0;\n /** Pages this run parsed. */\n misses = 0;\n private readonly writes: Promise<void>[] = [];\n\n constructor(\n private readonly dir: string,\n private readonly version: string = pkg.version,\n ) {}\n\n /** `parseBody`, served from the entry for `path` when its key matches. */\n readonly parse = (content: string, path: string, format: DocFormat): DocBody => {\n const key = sha256(JSON.stringify([ENTRY_VERSION, this.version, format, path, content]));\n // Named by a digest, so a label's `..` or `:` cannot choose where it lands.\n const file = join(this.dir, `${sha256(path)}.json`);\n const cached = readEntry(file, key);\n if (cached !== undefined) {\n this.hits++;\n return cached;\n }\n const body = parseBody(content, path, format);\n this.misses++;\n this.writes.push(this.write(file, JSON.stringify({ key, body })));\n return body;\n };\n\n /** Wait for this run's writes. Never rejects. */\n async flush(): Promise<void> {\n await Promise.all(this.writes);\n }\n\n private async write(file: string, text: string): Promise<void> {\n try {\n await mkdir(this.dir, { recursive: true });\n await writeTextAtomic(file, text);\n } catch {\n // Best-effort: the next run parses this page again.\n }\n }\n}\n\nfunction readEntry(file: string, key: string): DocBody | undefined {\n try {\n const entry = JSON.parse(readFileSync(file, \"utf8\")) as unknown;\n if (typeof entry !== \"object\" || entry === null) return undefined;\n const { key: stored, body } = entry as Record<string, unknown>;\n return stored === key && isDocBody(body) ? body : undefined;\n } catch {\n return undefined;\n }\n}\n","/**\n * The localization manifest (ADR 01038) — `graph/localizations.json`, the index of\n * indexes.\n *\n * Retrieval artifacts fan out per language: one `search.<lang>.json` and one\n * `vectors.<lang>.bin` each, because a single flat index over every locale\n * ranks across the boundary it exists to respect, and because one embedding\n * model cannot serve every language. The manifest is what makes that navigable\n * — a browser fetches this one small file, learns which localizations exist and\n * what each costs, and downloads only the pair it needs.\n *\n * Written by `manni graph export search`; `manni graph embed` fills in the\n * `vectors` block as it produces each sidecar, so a manifest entry without one\n * means exactly \"this language has no vectors yet\".\n *\n * No `node:` imports: the CLI writes it and the browser runtime reads it.\n */\nimport { byCodeUnit } from \"./sort.js\";\n\n/** Conventional filename, written beside the graph. */\nexport const LOCALIZATIONS_FILENAME = \"localizations.json\";\n\n/**\n * BCP-47's tag for undetermined, used as the bucket for documents that declare\n * no language. A real tag rather than a dockg invention, so a consumer that\n * knows BCP-47 already knows what it means — and so the bucket sorts, filters,\n * and names a file like any other language.\n */\nexport const UNDETERMINED = \"und\";\n\n/**\n * BCP-47's common shape: language(2-3) + optional script(4) + optional\n * region(2 alpha or 3 digit) + variants. Accepts de, de-DE, zh-Hans,\n * zh-Hans-CN, pt-BR and und; rejects English and de_DE.\n *\n * The same grammar appears in `config-schema.json` (for `routes[].language` and\n * `embed.byLanguage`) and in `shapes/graph/shapes-1.0.0.ttl` (for `dcterms:language`).\n * This copy exists because a tag also becomes a **filename**, and the shapes\n * only run under `manni graph check` — an unvalidated literal from the graph would\n * otherwise reach `writeFileSync` as a path segment. `test/unit/schema-sync.test.ts`\n * pins all three to each other.\n */\nexport const LANGUAGE_TAG =\n /^[A-Za-z]{2,3}(-[A-Za-z]{4})?(-([A-Za-z]{2}|[0-9]{3}))?(-([A-Za-z0-9]{5,8}|[0-9][A-Za-z0-9]{3}))*$/;\n\n/** Whether a string is usable as a language tag — and so as a filename segment. */\nexport function isLanguageTag(value: string): boolean {\n return LANGUAGE_TAG.test(value);\n}\n\n/**\n * The canonical spelling of a BCP-47 tag: `en-us` and `EN-US` both become\n * `en-US`. Tags are case-insensitive, so without this one locale splits into\n * two indexes and a filter matches only the spelling its author happened to\n * type. A string `Intl` refuses comes back as written, so the tag check that\n * guards filenames still sees, and reports, what the author wrote.\n *\n * `Intl` exists in every browser, so the runtime calls this too.\n */\nexport function canonicalLanguageTag(tag: string): string {\n try {\n return Intl.getCanonicalLocales(tag)[0] ?? tag;\n } catch {\n return tag;\n }\n}\n\n/** Where one language's lexical index lives, and what it holds. */\nexport interface SearchArtifact {\n /** Filename, relative to the manifest. */\n path: string;\n /** Indexed nodes. */\n entries: number;\n /** `sha256:…` of the file, so a consumer can detect a stale pair. */\n digest: string;\n}\n\n/** Where one language's vector sidecar lives, and what produced it. */\nexport interface VectorArtifact {\n path: string;\n /** The embedding model this language was embedded with. */\n model: string;\n dtype: string;\n dims: number;\n count: number;\n}\n\nexport interface LocalizationEntry {\n /** BCP-47 tag, or `und` for the undeclared bucket. */\n language: string;\n /** Documents in this language (sections excluded). */\n documents: number;\n search: SearchArtifact;\n /** Absent until `manni graph embed` has run for this language. */\n vectors?: VectorArtifact;\n}\n\nexport interface LocalizationsDoc {\n version: 1;\n /** One entry per language present, sorted by tag. */\n languages: LocalizationEntry[];\n}\n\n/** `search.de.json` — the lexical index for one language. */\nexport function searchIndexFilename(language: string): string {\n return `search.${language}.json`;\n}\n\n/** `vectors.de.bin` — the vector sidecar for one language. */\nexport function vectorIndexFilename(language: string): string {\n return `vectors.${language}.bin`;\n}\n\n/**\n * Serialize the manifest: sorted by language, two-space indent, trailing\n * newline — byte-stable like every other dockg artifact.\n */\nexport function emitLocalizations(doc: LocalizationsDoc): string {\n const languages = [...doc.languages].sort((a, b) =>\n byCodeUnit(a.language, b.language),\n );\n return `${JSON.stringify({ version: doc.version, languages }, null, 2)}\\n`;\n}\n\n/**\n * Parse and shape-check a manifest. Returns undefined for anything else.\n *\n * Every entry is checked, not just the envelope: callers reach straight for\n * `entry.search.path`, and a truncated or hand-edited file would otherwise\n * dereference `undefined` and surface as a raw TypeError with exit 1 rather\n * than the operational error (exit 2) an unreadable artifact owes.\n */\n/** A plain JSON object — not `null`, not an array. */\nfunction isRecord(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nexport function parseLocalizations(text: string): LocalizationsDoc | undefined {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return undefined;\n }\n // Checked as `unknown`. Casting to `LocalizationsDoc` first would hand the\n // compiler the answer to the question this function exists to ask, and every\n // guard below would then read as a test that cannot fail.\n if (!isRecord(parsed)) return undefined;\n if (parsed[\"version\"] !== 1 || !Array.isArray(parsed[\"languages\"])) {\n return undefined;\n }\n for (const entry of parsed[\"languages\"] as unknown[]) {\n if (!isRecord(entry)) return undefined;\n const language = entry[\"language\"];\n const search = entry[\"search\"];\n if (\n typeof language !== \"string\" ||\n !isLanguageTag(language) ||\n typeof entry[\"documents\"] !== \"number\" ||\n !isRecord(search) ||\n typeof search[\"path\"] !== \"string\" ||\n typeof search[\"entries\"] !== \"number\" ||\n typeof search[\"digest\"] !== \"string\" ||\n !ownsFilename(search[\"path\"], searchIndexFilename(language))\n ) {\n return undefined;\n }\n const v = entry[\"vectors\"];\n if (v !== undefined) {\n if (\n !isRecord(v) ||\n typeof v[\"path\"] !== \"string\" ||\n typeof v[\"model\"] !== \"string\" ||\n typeof v[\"dtype\"] !== \"string\" ||\n typeof v[\"dims\"] !== \"number\" ||\n typeof v[\"count\"] !== \"number\" ||\n // Same constraint `search.path` gets: the last segment must be the\n // filename this language's sidecar would be given. Without it,\n // `isSafeRelativePath` alone leaves `vectors.path` far more reachable\n // than `search.path` — and `search --mode vector` opens it.\n !ownsFilename(v[\"path\"], vectorIndexFilename(language))\n ) {\n return undefined;\n }\n }\n }\n return parsed as unknown as LocalizationsDoc;\n}\n\n/**\n * A path from the manifest is joined onto a directory and opened, so it is\n * checked like any other untrusted path segment.\n *\n * `export` refuses to *write* a filename it built from a bad language tag; this\n * is the same hole on the read side, reached through a manifest instead of\n * through frontmatter. A hand-edited `\"path\": \"../../etc/passwd\"` would\n * otherwise be joined and read by `embed` and `search`.\n *\n * Rejects an absolute path, a Windows drive letter, a backslash, and any `.`\n * or empty segment. `..` is allowed **only as a prefix**, so `a/../../x` — an\n * escape wearing a normal first segment — is refused while `../vecs/x.bin`,\n * the layout `embed -o` produces, is not.\n *\n * How far up a leading run may climb is deliberately *not* capped. It was,\n * briefly, and the cap rejected manifests `embed -o` itself writes: a sidecar\n * directory two levels from the index directory produced an artifact set dockg\n * could not read back. The bound that matters is `ownsFilename` — a crafted\n * manifest can only ever name a file already called `search.<lang>.json` or\n * `vectors.<lang>.bin`, which is a long way from arbitrary-file read, and no\n * number of `..` segments widens it.\n */\nexport function isSafeRelativePath(path: string): boolean {\n if (path === \"\" || path.startsWith(\"/\") || /^[A-Za-z]:/.test(path)) {\n return false;\n }\n if (path.includes(\"\\\\\")) return false;\n const segments = path.split(\"/\");\n let leading = true;\n for (const segment of segments) {\n if (segment === \"\" || segment === \".\") return false;\n if (segment === \"..\") {\n if (!leading) return false;\n continue;\n }\n leading = false;\n }\n return true;\n}\n\n/**\n * The path is relative-safe *and* its last segment is the filename this\n * language's artifact would be given.\n *\n * The filename check is the constraint that actually narrows what a crafted\n * manifest can reach: `isSafeRelativePath` bounds the directory it can point\n * into, this bounds the file.\n */\nfunction ownsFilename(path: string, expected: string): boolean {\n if (!isSafeRelativePath(path)) return false;\n return path.slice(path.lastIndexOf(\"/\") + 1) === expected;\n}\n","/**\n * Graph derivation: DocModel[] → deduplicated Quad[]. This file is the\n * vocabulary mapping — the deterministic rules for what documentation\n * structure becomes which triples.\n */\nimport type { DocModel } from \"../types.js\";\nimport type { DeriveSource } from \"./config.js\";\nimport type { GitHistory } from \"./git.js\";\nimport { hasScheme, resolveRelative } from \"./analyze.js\";\nimport type { AgentKind } from \"./iri.js\";\nimport {\n conceptSlug,\n encodeSegment,\n mintAgentIri,\n mintBuildActivityIri,\n mintConceptIri,\n mintDocIri,\n mintGraphIri,\n mintProductIri,\n mintSchemeIri,\n mintSectionIri,\n normalizeDocPath,\n} from \"./iri.js\";\nimport { byCodeUnit } from \"./sort.js\";\nimport { canonicalLanguageTag } from \"./localizations.js\";\nimport { NS, RDF_TYPE, ROLE } from \"./vocab.js\";\nimport {\n GRAPH_NOT_APPLICABLE_TO_VARIANT,\n GRAPH_NOT_SOFTWARE_SUBJECT,\n IIRDS_HAS_SUBJECT,\n IIRDS_HAS_TOPIC_TYPE,\n IIRDS_PRODUCT_VARIANT,\n IIRDS_RELATES_TO_LIFECYCLE_PHASE,\n IIRDS_RELATES_TO_PRODUCT_VARIANT,\n PAGE_TYPE_TO_TOPIC_TYPE,\n SOFTWARE_LIFECYCLE_IRIS,\n SOFTWARE_SUBJECT_IRIS,\n TOPIC_TYPE_IRIS,\n} from \"./iirds.js\";\n\n/**\n * Resolve a provenance target (a `graph.derived-from` / `graph.revision-of`\n * entry) to a corpus doc path: doc-relative first, then repo-relative; null\n * when neither names a discovered doc.\n */\nfunction resolveProvDocPath(\n docPath: string,\n raw: string,\n docByPath: ReadonlyMap<string, DocModel>,\n): string | null {\n const docRelative = resolveRelative(docPath, raw);\n if (docRelative !== null && docByPath.has(docRelative)) return docRelative;\n const repoRelative = normalizeDocPath(raw);\n return docByPath.has(repoRelative) ? repoRelative : null;\n}\n\nexport type Term =\n | { kind: \"iri\"; value: string }\n | { kind: \"literal\"; value: string; datatype?: string };\n\nexport interface Quad {\n s: string;\n p: string;\n o: Term;\n}\n\nexport interface DeriveOptions {\n baseIri: string;\n derive: DeriveSource[];\n /** dockg's own version, stamped on the build agent (provenance source). */\n toolVersion?: string;\n /** Per-file git history; set only under `provenance.git`. */\n gitHistory?: GitHistory;\n /** Emit qualified attribution/association nodes (`provenance.qualified`). */\n qualified?: boolean;\n}\n\nconst iri = (value: string): Term => ({ kind: \"iri\", value });\nconst lit = (value: string): Term => ({ kind: \"literal\", value });\nconst typedLit = (value: string, datatype: string): Term => ({\n kind: \"literal\",\n value,\n datatype,\n});\n\nconst DATE_RE = /^\\d{4}-\\d{2}-\\d{2}$/;\nconst DATETIME_RE = /^\\d{4}-\\d{2}-\\d{2}[T ]\\d{2}:\\d{2}/;\n\n/** Type a frontmatter date value; plain literal when unrecognized. */\nfunction dateTerm(value: string): Term {\n if (DATE_RE.test(value)) return typedLit(value, `${NS.xsd}date`);\n if (DATETIME_RE.test(value)) return typedLit(value, `${NS.xsd}dateTime`);\n return lit(value);\n}\n\nfunction asString(v: unknown): string | undefined {\n if (typeof v === \"string\" && v.length > 0) return v;\n if (typeof v === \"number\") return String(v);\n // TOML frontmatter yields Date instances (smol-toml TomlDate). String(date)\n // is locale/timezone-dependent and would break byte-identical output;\n // ISO 8601 is stable everywhere.\n if (v instanceof Date) {\n return Number.isNaN(v.getTime()) ? undefined : v.toISOString();\n }\n return undefined;\n}\n\nfunction asStringArray(v: unknown): string[] {\n if (typeof v === \"string\") return v.length > 0 ? [v] : [];\n if (Array.isArray(v)) {\n return v.flatMap((item) => {\n const s = asString(item);\n return s === undefined ? [] : [s];\n });\n }\n return [];\n}\n\n/**\n * The names in an `author`/`authors` value. Stewardship allows a name, a\n * person object with a `name` (the MyST and Docusaurus shape), or a list of\n * either. A person object with no name names no one.\n */\nfunction asPersonNames(v: unknown): string[] {\n const one = (item: unknown): string[] => {\n const name =\n item != null && typeof item === \"object\" && !Array.isArray(item)\n ? asString(asRecord(item).name)\n : asString(item);\n return name === undefined ? [] : [name];\n };\n return Array.isArray(v) ? v.flatMap(one) : one(v);\n}\n\n/** A plain object as a string-keyed record; anything else becomes `{}`. */\nfunction asRecord(v: unknown): Record<string, unknown> {\n return v != null && typeof v === \"object\" && !Array.isArray(v)\n ? (v as Record<string, unknown>)\n : {};\n}\n\n/** First defined frontmatter value among aliases. */\nfunction fmValue(fm: Record<string, unknown>, keys: string[]): unknown {\n for (const key of keys) {\n if (fm[key] !== undefined && fm[key] !== null) return fm[key];\n }\n return undefined;\n}\n\n/** PROV-O's three prov:Agent subclasses, and their IRI path segments. */\ntype ProvAgentClass = \"Person\" | \"Organization\" | \"SoftwareAgent\";\n\nconst AGENT_KIND: Record<ProvAgentClass, AgentKind> = {\n Person: \"person\",\n Organization: \"org\",\n SoftwareAgent: \"software\",\n};\n\n/** The `graph` block of frontmatter, or undefined. */\nfunction graphBlock(\n fm: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n const block = fm[\"graph\"];\n return block && typeof block === \"object\" && !Array.isArray(block)\n ? (block as Record<string, unknown>)\n : undefined;\n}\n\n/**\n * The harvest rule (ADR 01024): **deeper wins; the page level is the fallback**\n * — per fact, not per page. A `graph` block that speaks to a fact owns it\n * outright; where the block is silent, the page-level twin feeds the graph.\n *\n * Only the facts the `graph` block has a twin for are resolved here. Page-level\n * `prerequisites` / `next-steps` / `related-pages` belong to `docmeta:structure`\n * and are deliberately not harvested — that is a separate vocabulary, not this\n * one's fallback.\n *\n * Returns a graph-shaped object even when the page carries no `graph` block at\n * all, so a page typed only at the top level still derives its iiRDS typing.\n */\nfunction resolveGraph(\n block: Record<string, unknown> | undefined,\n fm: Record<string, unknown>,\n): Record<string, unknown> {\n const k: Record<string, unknown> = { ...(block ?? {}) };\n\n const fallback = (key: string, pageKeys: string[]) => {\n if (k[key] !== undefined && k[key] !== null) return;\n const pageValue = fmValue(fm, pageKeys);\n if (pageValue !== undefined) k[key] = pageValue;\n };\n\n fallback(\"concepts\", [\"concepts\"]);\n fallback(\"applies-to\", [\"applies-to\"]);\n fallback(\"not-applicable-to\", [\"not-applicable-to\"]);\n fallback(\"revision-of\", [\"supersedes\"]);\n\n // `type` is the one fact whose two altitudes speak different vocabularies:\n // the page's is open (docmeta:core), `graph.type` is the closed iiRDS enum. A\n // page type with no iiRDS counterpart derives nothing rather than inventing\n // one.\n if (k[\"type\"] === undefined || k[\"type\"] === null) {\n const pageType = asString(fmValue(fm, [\"type\"]));\n // hasOwn guards the prototype chain: `type: constructor` would otherwise\n // resolve to Object and pass the truthiness check below, writing a\n // function into graph.type.\n const derived =\n pageType && Object.hasOwn(PAGE_TYPE_TO_TOPIC_TYPE, pageType)\n ? PAGE_TYPE_TO_TOPIC_TYPE[pageType]\n : undefined;\n if (derived) k[\"type\"] = derived;\n }\n\n return k;\n}\n\n/**\n * The mapping entries of a `provenance` / `meta-provenance` list. Both are\n * lists of entries keyed by `generated-by` (proposal 0046), and a list is all\n * either of them may be — anything else names no machine, so it derives\n * nothing rather than being guessed at.\n *\n * Not `metaProvenanceEntries` from meta's barrel: that reader narrows an entry\n * to its model, `fields` and `evals`, and the harvest also needs `confidence`,\n * which it drops.\n */\nfunction recordEntries(value: unknown): Array<Record<string, unknown>> {\n if (!Array.isArray(value)) return [];\n return value.filter(\n (e): e is Record<string, unknown> =>\n !!e && typeof e === \"object\" && !Array.isArray(e),\n );\n}\n\n/** A JSON Pointer's reference tokens, each unescaped per RFC 6901. */\nfunction pointerSegments(pointer: string): string[] {\n return pointer\n .split(\"/\")\n .slice(1)\n .map((s) => s.replace(/~1/g, \"/\").replace(/~0/g, \"~\"));\n}\n\nexport function deriveGraph(docs: DocModel[], options: DeriveOptions): Quad[] {\n const { baseIri } = options;\n const sources = new Set(options.derive);\n const quads: Quad[] = [];\n const add = (s: string, p: string, o: Term) => quads.push({ s, p, o });\n /**\n * Concept IRIs minted while deriving. A set rather than a flag because\n * `concept()` is a closure: a captured `let` assigned only inside one stays\n * narrowed to its initializer at the read below, which would make the\n * scheme node unreachable as far as the compiler is concerned.\n */\n const mintedConcepts = new Set<string>();\n\n /** Concept node + membership triples; returns the concept IRI. */\n const concept = (label: string): string => {\n const c = mintConceptIri(baseIri, label);\n add(c, RDF_TYPE, iri(`${NS.skos}Concept`));\n add(c, `${NS.skos}prefLabel`, lit(label));\n add(c, `${NS.skos}inScheme`, iri(mintSchemeIri(baseIri)));\n mintedConcepts.add(c);\n return c;\n };\n\n /** ProductVariant node (type + label); returns its IRI. Positive and\n * negative applicability converge on one node per label. */\n const variantNode = (label: string): string => {\n const variant = mintProductIri(baseIri, label);\n add(variant, RDF_TYPE, iri(IIRDS_PRODUCT_VARIANT));\n add(variant, `${NS.dcterms}title`, lit(label));\n return variant;\n };\n\n /**\n * Emit the iiRDS typing fields (type, applies-to, about-product-lifecycle,\n * about-product-aspect) plus the negative-scope fields (not-applicable-to,\n * not-about-product-aspect) for `subjectIri` from a graph-like object. Shared\n * by the document `graph` block and the per-section `graph.sections` block so\n * the mapping cannot drift between them (ADR 01012/01013/01014).\n */\n const emitIirdsTyping = (subjectIri: string, k: Record<string, unknown>) => {\n const topicType = asString(k[\"type\"]);\n const topicTypeIri = topicType && TOPIC_TYPE_IRIS[topicType];\n if (topicTypeIri) add(subjectIri, IIRDS_HAS_TOPIC_TYPE, iri(topicTypeIri));\n\n for (const label of asStringArray(k[\"applies-to\"])) {\n add(\n subjectIri,\n IIRDS_RELATES_TO_PRODUCT_VARIANT,\n iri(variantNode(label)),\n );\n }\n for (const label of asStringArray(k[\"not-applicable-to\"])) {\n add(subjectIri, GRAPH_NOT_APPLICABLE_TO_VARIANT, iri(variantNode(label)));\n }\n\n for (const value of asStringArray(k[\"about-product-lifecycle\"])) {\n const phase = SOFTWARE_LIFECYCLE_IRIS[value];\n if (phase) add(subjectIri, IIRDS_RELATES_TO_LIFECYCLE_PHASE, iri(phase));\n }\n for (const value of asStringArray(k[\"about-product-aspect\"])) {\n const subject = SOFTWARE_SUBJECT_IRIS[value];\n if (subject) add(subjectIri, IIRDS_HAS_SUBJECT, iri(subject));\n }\n for (const value of asStringArray(k[\"not-about-product-aspect\"])) {\n const subject = SOFTWARE_SUBJECT_IRIS[value];\n if (subject) add(subjectIri, GRAPH_NOT_SOFTWARE_SUBJECT, iri(subject));\n }\n };\n\n const docByPath = new Map(docs.map((d) => [normalizeDocPath(d.path), d]));\n const prov = sources.has(\"provenance\");\n\n /**\n * Agent node; dedupe converges repeats of the same name AND kind. The IRI\n * is segmented by kind (`agent/person/…`, `agent/software/…`) so a human\n * and a model whose names slug alike stay distinct nodes.\n */\n const agentNode = (name: string, type: ProvAgentClass): string => {\n const a = mintAgentIri(baseIri, AGENT_KIND[type], name);\n add(a, RDF_TYPE, iri(`${NS.prov}${type}`));\n add(a, `${NS.foaf}name`, lit(name));\n return a;\n };\n\n const qualified = options.qualified === true;\n\n // Qualification node IRIs use \".\" separators (github-slugger can never emit\n // a dot, so heading slugs cannot collide) and carry the agent slug, so two\n // agents on one activity/doc never merge into a single node.\n\n /** doc ↔ author qualification: {docIri}#prov.attribution.{agentSlug}. */\n const qualifyAttribution = (\n docIri: string,\n agentIri: string,\n name: string,\n ): void => {\n if (!qualified) return;\n const node = `${docIri}#prov.attribution.${conceptSlug(name)}`;\n add(docIri, `${NS.prov}qualifiedAttribution`, iri(node));\n add(node, RDF_TYPE, iri(`${NS.prov}Attribution`));\n add(node, `${NS.prov}agent`, iri(agentIri));\n add(node, `${NS.prov}hadRole`, iri(ROLE.author));\n };\n\n /** activity ↔ agent qualification: {activityIri}.assoc.{agentSlug}. */\n const qualifyAssociation = (\n activityIri: string,\n agentIri: string,\n role: string,\n ): void => {\n if (!qualified) return;\n const agentSlug = agentIri.slice(agentIri.lastIndexOf(\"/\") + 1);\n const node = `${activityIri}.assoc.${agentSlug}`;\n add(activityIri, `${NS.prov}qualifiedAssociation`, iri(node));\n add(node, RDF_TYPE, iri(`${NS.prov}Association`));\n add(node, `${NS.prov}agent`, iri(agentIri));\n add(node, `${NS.prov}hadRole`, iri(role));\n };\n\n /** Author agent + creator/attribution edges (+ qualification when on). */\n const attributeAuthor = (docIri: string, name: string): void => {\n const a = agentNode(name, \"Person\");\n add(docIri, `${NS.dcterms}creator`, iri(a));\n add(docIri, `${NS.prov}wasAttributedTo`, iri(a));\n qualifyAttribution(docIri, a, name);\n };\n\n /**\n * Shared mapping for graph.derived-from / graph.revision-of / page\n * `translation-of` entries.\n *\n * `inverse`, when given, is also emitted back from the resolved target — but\n * only for a target inside the corpus. A URL names a resource dockg has not\n * analyzed and does not speak for, so it gains an inbound edge and never an\n * outbound claim (ADR 01037).\n */\n const provTargetEdge = (\n doc: DocModel,\n docIri: string,\n raw: string,\n predicate: string,\n inverse?: string,\n ): void => {\n if (hasScheme(raw)) {\n add(docIri, predicate, iri(raw));\n return;\n }\n const target = resolveProvDocPath(\n normalizeDocPath(doc.path),\n raw,\n docByPath,\n );\n if (target) {\n const targetIri = mintDocIri(baseIri, target);\n add(docIri, predicate, iri(targetIri));\n if (inverse) add(targetIri, inverse, iri(docIri));\n } else {\n add(docIri, `${NS.graph}brokenLink`, lit(raw));\n }\n };\n\n for (const doc of docs) {\n const docIri = mintDocIri(baseIri, doc.path);\n const fm = doc.frontmatter;\n const block = graphBlock(fm);\n // `block` is the `graph` block as written (block-only facts: sections,\n // provenance, the SKOS hierarchy); `harvested` folds in the page-level\n // fallbacks.\n const harvested = resolveGraph(block, fm);\n let createdEmitted = false;\n let modifiedEmitted = false;\n\n add(docIri, RDF_TYPE, iri(`${NS.graph}Document`));\n if (prov) add(docIri, RDF_TYPE, iri(`${NS.prov}Entity`));\n add(docIri, `${NS.graph}path`, lit(normalizeDocPath(doc.path)));\n // Intrinsic like path, not gated behind a derive source (ADR 01036): a hash\n // present only sometimes cannot tell \"unchanged\" from \"not stamped\", which\n // is the whole question it exists to answer.\n add(docIri, `${NS.graph}contentHash`, lit(doc.contentHash));\n\n if (sources.has(\"frontmatter\")) {\n const title = asString(fmValue(fm, [\"title\"])) ?? doc.firstH1;\n if (title) add(docIri, `${NS.dcterms}title`, lit(title));\n\n const description = asString(fmValue(fm, [\"description\"]));\n if (description)\n add(docIri, `${NS.dcterms}description`, lit(description));\n\n for (const author of asPersonNames(fmValue(fm, [\"author\", \"authors\"]))) {\n if (prov) {\n attributeAuthor(docIri, author);\n } else {\n add(docIri, `${NS.dcterms}creator`, lit(author));\n }\n }\n\n // Stewardship's spelling first (`created`, `last-updated`), then the\n // aliases other generators write. One value per predicate: the first\n // key present wins and the rest are ignored.\n const created = asString(fmValue(fm, [\"created\", \"date\"]));\n if (created) {\n add(docIri, `${NS.dcterms}created`, dateTerm(created));\n if (prov) add(docIri, `${NS.prov}generatedAtTime`, dateTerm(created));\n createdEmitted = true;\n }\n\n const modified = asString(\n fmValue(fm, [\"last-updated\", \"updated\", \"lastmod\", \"modified\"]),\n );\n if (modified) {\n add(docIri, `${NS.dcterms}modified`, dateTerm(modified));\n modifiedEmitted = true;\n }\n\n // The page's own key outranks the route it sits under (ADR 01037): a\n // single English page inside a translated tree can correct its label,\n // and a corpus that declares nothing keeps deriving nothing.\n //\n // Written in its canonical spelling: tags are case-insensitive, and\n // `en-us` beside `en-US` would otherwise split one locale into two\n // indexes and miss a `--lang` filter typed the other way.\n const language =\n asString(fmValue(fm, [\"lang\", \"language\"])) ?? doc.routeLanguage;\n if (language) {\n add(docIri, `${NS.dcterms}language`, lit(canonicalLanguageTag(language)));\n }\n\n // Page-level only: the `graph` block is closed and carries no\n // translation key, so this fact lives at the altitude `lang` already\n // does (ADR 01023, ADR 01037). Both directions are materialized, so\n // \"every localization of this page\" is one lookup for a consumer with no\n // inbound index of its own.\n for (const raw of asStringArray(fmValue(fm, [\"translation-of\"]))) {\n provTargetEdge(\n doc,\n docIri,\n raw,\n `${NS.schema}translationOfWork`,\n `${NS.schema}workTranslation`,\n );\n }\n\n // The graph block: the SKOS hierarchy has no page-level twin, so it reads\n // the block as written (frontmatter key `graph`, RDF prefix `graph:`).\n if (block) {\n const label = asString(block[\"label\"]);\n if (label) {\n const topic = concept(label);\n add(docIri, `${NS.foaf}primaryTopic`, iri(topic));\n for (const alt of asStringArray(block[\"alt-labels\"])) {\n add(topic, `${NS.skos}altLabel`, lit(alt));\n }\n // Frontmatter key → SKOS predicate. `related-concepts` is spelled for\n // what it points at (in step with the page-level `related-pages`);\n // the predicate it emits is still plain skos:related.\n for (const [key, predicate] of [\n [\"broader\", \"broader\"],\n [\"narrower\", \"narrower\"],\n [\"related-concepts\", \"related\"],\n ] as const) {\n for (const value of asStringArray(block[key])) {\n add(topic, `${NS.skos}${predicate}`, iri(concept(value)));\n }\n }\n }\n }\n\n // iiRDS Core + Software typing (ADR 01012), over the harvested block so a\n // page typed only at the top level still types its document (ADR 01024).\n emitIirdsTyping(docIri, harvested);\n }\n\n if (sources.has(\"tags\")) {\n // Two distinct facts, both landing on dcterms:subject: dockg's own\n // tag harvest (`tags`/`keywords`), and the concepts fact — where\n // `graph.concepts` beats the page-level `concepts` outright rather than\n // adding to it (ADR 01024).\n const labels = [\n ...asStringArray(fmValue(fm, [\"tags\", \"keywords\"])),\n ...asStringArray(harvested[\"concepts\"]),\n ];\n for (const label of labels) {\n add(docIri, `${NS.dcterms}subject`, iri(concept(label)));\n }\n }\n\n if (sources.has(\"sections\")) {\n // graph.sections: slug-keyed iiRDS typing attached to section nodes\n // (ADR 01013). Explicit-only — a section gets nothing from the doc.\n const sectionMeta = asRecord(block?.[\"sections\"]);\n const sectionSlugs = new Set(doc.sections.map((s) => s.slug));\n\n for (const section of doc.sections) {\n const secIri = mintSectionIri(docIri, section.slug);\n const parentIri = section.parentSlug\n ? mintSectionIri(docIri, section.parentSlug)\n : docIri;\n add(secIri, RDF_TYPE, iri(`${NS.graph}Section`));\n add(secIri, `${NS.dcterms}title`, lit(section.title));\n add(\n secIri,\n `${NS.graph}level`,\n typedLit(String(section.level), `${NS.xsd}integer`),\n );\n add(\n secIri,\n `${NS.graph}order`,\n typedLit(String(section.order), `${NS.xsd}integer`),\n );\n add(parentIri, `${NS.dcterms}hasPart`, iri(secIri));\n\n const meta = asRecord(sectionMeta[section.slug]);\n emitIirdsTyping(secIri, meta);\n for (const label of asStringArray(meta[\"concepts\"])) {\n add(secIri, `${NS.dcterms}subject`, iri(concept(label)));\n }\n }\n\n // A graph.sections key naming no heading is a broken reference (surfaced\n // by stats, gated by stats --check) — never a silent drop.\n for (const slug of Object.keys(sectionMeta)) {\n if (!sectionSlugs.has(slug)) {\n add(docIri, `${NS.graph}brokenSectionRef`, lit(slug));\n }\n }\n }\n\n if (sources.has(\"links\")) {\n for (const link of doc.links) {\n if (link.kind === \"external\" && link.url) {\n add(docIri, `${NS.dcterms}references`, iri(link.url));\n } else if (link.kind === \"internal\" && link.resolvedPath) {\n const targetIri = mintDocIri(baseIri, link.resolvedPath);\n const target = docByPath.get(link.resolvedPath);\n // Bound first, so the anchor the test found is the anchor the IRI is\n // minted from rather than a second read the type cannot connect to\n // the first.\n const anchor = link.anchor;\n const anchorResolves =\n anchor !== undefined &&\n target !== undefined &&\n target.sections.some((s) => s.slug === anchor);\n add(\n docIri,\n `${NS.dcterms}references`,\n iri(\n anchorResolves ? mintSectionIri(targetIri, anchor) : targetIri,\n ),\n );\n } else if (link.kind === \"broken\") {\n add(docIri, `${NS.graph}brokenLink`, lit(link.raw));\n }\n }\n }\n\n if (sources.has(\"images\")) {\n for (const image of doc.images) {\n const target = image.external\n ? image.target\n : `${baseIri}file/${normalizeDocPath(image.target)\n .split(\"/\")\n .map(encodeSegment)\n .join(\"/\")}`;\n add(docIri, `${NS.schema}image`, iri(target));\n }\n }\n\n if (sources.has(\"code\")) {\n for (const language of doc.codeLanguages) {\n add(docIri, `${NS.graph}codeLanguage`, lit(language));\n }\n }\n\n if (prov) {\n // graph.derived-from / graph.revision-of: doc-relative path,\n // repo-relative path, or URL — one shared resolution. `derived-from` is block-only\n // (document lineage is curated by hand); `revision-of` harvests the\n // page-level `supersedes` when the block is silent (ADR 01024).\n for (const raw of block ? asStringArray(block[\"derived-from\"]) : []) {\n provTargetEdge(doc, docIri, raw, `${NS.prov}wasDerivedFrom`);\n }\n for (const raw of asStringArray(harvested[\"revision-of\"])) {\n provTargetEdge(doc, docIri, raw, `${NS.prov}wasRevisionOf`);\n }\n\n // Per-file git history (provenance.git): frontmatter always wins on\n // dates; authors merge; renames become revision edges to the\n // historical-path entities.\n const gitFile = options.gitHistory?.files.get(normalizeDocPath(doc.path));\n if (gitFile) {\n if (!createdEmitted && gitFile.created) {\n add(docIri, `${NS.dcterms}created`, dateTerm(gitFile.created));\n add(docIri, `${NS.prov}generatedAtTime`, dateTerm(gitFile.created));\n }\n if (!modifiedEmitted && gitFile.modified) {\n add(docIri, `${NS.dcterms}modified`, dateTerm(gitFile.modified));\n }\n for (const author of gitFile.authors) {\n attributeAuthor(docIri, author);\n }\n for (const oldPath of gitFile.renamedFrom) {\n const oldIri = mintDocIri(baseIri, oldPath);\n add(docIri, `${NS.prov}wasRevisionOf`, iri(oldIri));\n add(oldIri, RDF_TYPE, iri(`${NS.prov}Entity`));\n }\n }\n\n // Whole-page generation. There is no page-level `generated-by` any more\n // (proposal 0046): the machines that wrote a page are the DISTINCT\n // `generated-by` values across its page-level `provenance` entries, each\n // of which pins a line range. The activity stays one per page, so a\n // single-model page emits exactly what it always did. Its fragment uses\n // a \".\" separator, which github-slugger can never produce — heading\n // slugs cannot collide with provenance fragments.\n const machines = [\n ...new Set(\n recordEntries(fmValue(fm, [\"provenance\"])).flatMap((e) => {\n const m = asString(e[\"generated-by\"]);\n return m === undefined ? [] : [m];\n }),\n ),\n ].sort(byCodeUnit);\n if (machines.length > 0) {\n const activity = `${docIri}#prov.generation`;\n add(docIri, `${NS.prov}wasGeneratedBy`, iri(activity));\n add(activity, RDF_TYPE, iri(`${NS.prov}Activity`));\n for (const machine of machines) {\n const model = agentNode(machine, \"SoftwareAgent\");\n add(activity, `${NS.prov}wasAssociatedWith`, iri(model));\n qualifyAssociation(activity, model, ROLE.generator);\n }\n }\n\n // Page-level `meta-provenance` (written by `manni graph fill`): one\n // activity PER MODEL so multiple fills by different models keep truthful\n // attribution. Only the doc's own topic concept is prov:generated —\n // shared subject/tag concepts are never attributed, or one doc's LLM\n // would taint every doc using the same tag.\n for (const entry of recordEntries(fmValue(fm, [\"meta-provenance\"]))) {\n const model = asString(entry[\"generated-by\"]);\n if (!model) continue;\n // A pointer names a value anywhere on the page, so only the ones under\n // `/graph/` are graph's business. The filled field is the first segment\n // after it: `/graph/sections/install/type` attributes `sections`, the\n // field a reviewer would look at. First pointer wins on confidence,\n // which 0046 keys by the whole pointer rather than by the field.\n const pointers = asStringArray(entry[\"fields\"]);\n const confidence = asRecord(entry[\"confidence\"]);\n const filled = new Map<string, string>();\n for (const pointer of pointers) {\n if (!pointer.startsWith(\"/graph/\")) continue;\n const field = pointerSegments(pointer)[1];\n if (field === undefined || field === \"\") continue;\n if (!filled.has(field)) filled.set(field, pointer);\n }\n if (filled.size === 0) continue;\n const activity = `${docIri}#prov.graph-fill.${conceptSlug(model)}`;\n const modelAgent = agentNode(model, \"SoftwareAgent\");\n add(activity, RDF_TYPE, iri(`${NS.prov}Activity`));\n add(activity, `${NS.prov}wasAssociatedWith`, iri(modelAgent));\n qualifyAssociation(activity, modelAgent, ROLE.generator);\n // Each filled field is reified as an entry node carrying its name and\n // (when fill recorded one) the model's confidence — a plain,\n // blank-node-free per-field audit edge (ADR 01015).\n for (const [field, pointer] of filled) {\n const fieldNode = `${activity}.field.${field}`;\n add(activity, `${NS.graph}filledFieldEntry`, iri(fieldNode));\n add(fieldNode, `${NS.graph}filledField`, lit(field));\n const c = confidence[pointer];\n if (typeof c === \"number\") {\n add(\n fieldNode,\n `${NS.graph}confidence`,\n typedLit(String(Math.round(c * 100) / 100), `${NS.xsd}decimal`),\n );\n }\n }\n const label = block ? asString(block[\"label\"]) : undefined;\n if (label && filled.has(\"label\")) {\n add(\n activity,\n `${NS.prov}generated`,\n iri(mintConceptIri(baseIri, label)),\n );\n }\n }\n }\n }\n\n if (prov) {\n const graphIri = mintGraphIri(baseIri);\n const activity = mintBuildActivityIri(baseIri);\n const tool = agentNode(\"manni\", \"SoftwareAgent\");\n add(graphIri, RDF_TYPE, iri(`${NS.prov}Entity`));\n add(graphIri, `${NS.prov}wasGeneratedBy`, iri(activity));\n add(activity, RDF_TYPE, iri(`${NS.prov}Activity`));\n add(activity, `${NS.prov}wasAssociatedWith`, iri(tool));\n qualifyAssociation(activity, tool, ROLE.tool);\n if (options.toolVersion) {\n add(tool, `${NS.graph}version`, lit(options.toolVersion));\n }\n for (const doc of docs) {\n add(activity, `${NS.prov}used`, iri(mintDocIri(baseIri, doc.path)));\n }\n const headTime = options.gitHistory?.headTime;\n if (headTime) {\n add(\n activity,\n `${NS.prov}endedAtTime`,\n typedLit(headTime, `${NS.xsd}dateTime`),\n );\n }\n }\n\n if (mintedConcepts.size > 0) {\n const scheme = mintSchemeIri(baseIri);\n add(scheme, RDF_TYPE, iri(`${NS.skos}ConceptScheme`));\n add(scheme, `${NS.dcterms}title`, lit(\"manni graph concepts\"));\n }\n\n return dedupe(quads);\n}\n\nfunction quadKey(q: Quad): string {\n const o =\n q.o.kind === \"iri\"\n ? `i:${q.o.value}`\n : `l:${q.o.value}|${q.o.datatype ?? \"\"}`;\n return `${q.s}|${q.p}|${o}`;\n}\n\nfunction dedupe(quads: Quad[]): Quad[] {\n const seen = new Set<string>();\n const out: Quad[] = [];\n for (const q of quads) {\n const key = quadKey(q);\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(q);\n }\n return out;\n}\n","/**\n * Input discovery: expand the run's document set to a stable, sorted,\n * deduplicated list of cwd-relative forward-slash paths. Determinism starts\n * here — the file list order is independent of glob order and filesystem\n * enumeration order.\n *\n * The set itself is the family's (proposal 0041, and 0051 §1 copying 0048 §1):\n * positional paths, or the collections declared once at the top level of\n * `manni.config.yaml`. `graph.inputs` and `graph.exclude` are gone, and a run that\n * names neither is an operational error rather than a silent walk of every\n * markdown file beneath the working directory (proposal 0014).\n */\nimport { statSync } from \"node:fs\";\nimport { extname, relative, resolve } from \"node:path\";\nimport fg from \"fast-glob\";\nimport {\n parserForExtension,\n supportedExtensions,\n unsupportedFormatMessage,\n} from \"../../lint/parsers/index.js\";\nimport { STDIN_REQUIRES_AS } from \"../../shared/cli-options.js\";\nimport { selectCollections } from \"../../shared/collections.js\";\nimport { warn } from \"../../shared/warn.js\";\nimport { GraphError } from \"../types.js\";\nimport { DOC_FORMATS, isDocFormat, type DocFormat } from \"./analyze.js\";\nimport {\n assertCollectionWithoutPaths,\n DEFAULT_CONFIG_FILENAME,\n type GraphConfig,\n type RouteMapping,\n} from \"./config.js\";\nimport { byCodeUnit } from \"./sort.js\";\n\nexport function discoverFiles(\n inputs: string[],\n exclude: string[],\n cwd: string,\n): string[] {\n const matches = fg.sync(inputs, {\n cwd,\n ignore: exclude,\n onlyFiles: true,\n dot: false,\n unique: true,\n });\n return [...new Set(matches.map((m) => m.replace(/\\\\/g, \"/\")))].sort(\n byCodeUnit,\n );\n}\n\n/**\n * What every tool in the family never reads, whatever it was asked for. The\n * same pair meta's file walk, cite's source index and docevals' discovery\n * ignore; it replaced graph's own `exclude` default (proposal 0041).\n */\nconst FAMILY_EXCLUDE = [\"**/node_modules/**\", \"**/.git/**\"];\n\n/**\n * What a directory walk or a glob keeps when `--ext` is not given: lint's walk\n * set, read from its registry so the two domains cannot drift (proposal 0077\n * §3). The filter matters because a positional path may be a *directory*,\n * which expands to everything beneath it. Without it, `manni graph build docs`\n * would mint a graph node for every image and data file in the tree, and a\n * node's IRI is the part of the output a consumer stores. `.xml` is not in\n * it, so a `pom.xml` is never swept in; a named one is still read.\n */\nexport const DEFAULT_EXTENSIONS = supportedExtensions();\n\n/** The positional that reads stdin. One more input, never instead of the rest. */\nexport const STDIN = \"-\";\n\n/**\n * Hold `--as` to the formats graph parses, and require it with `-`: stdin has\n * no file name to choose a parser by. Returns the format, or undefined when\n * none was forced.\n */\nexport function assertInputFormat(\n paths: readonly string[],\n as: string | undefined,\n): DocFormat | undefined {\n if (as === undefined) {\n if (paths.includes(STDIN)) throw new GraphError(STDIN_REQUIRES_AS);\n return undefined;\n }\n if (!isDocFormat(as)) {\n throw new GraphError(\n `Unknown format \"${as}\". Known formats: ${DOC_FORMATS.join(\", \")}.`,\n );\n }\n return as;\n}\n\n/** The word the empty-input message uses for what the command would do. */\nexport type DocumentVerb = \"build\" | \"fill\";\n\nexport interface DocumentSetOptions {\n /**\n * Positional paths: files, directories and globs, relative to the working\n * directory. Empty or absent means the selected collections' `paths:`.\n */\n paths?: string[];\n /**\n * `--collection <name>`, repeatable. Empty or absent means every declared\n * collection, because commander's collector hands `[]` over when the flag\n * was never typed (see `selectCollections`).\n */\n collection?: string[];\n /** `--exclude <glob>`, repeatable. Applies to paths and collections alike. */\n exclude?: string[];\n /**\n * `--ext <list>`: what a directory walk or a glob keeps. Absent means\n * `DEFAULT_EXTENSIONS`. A file named outright is never filtered by it.\n */\n ext?: string[];\n /** `--as <format>`: parse every input as this format. Required with `-`. */\n as?: string;\n}\n\n/**\n * The document-set options every command that reads documents takes beside its\n * positional paths: `-c`, `--no-config`, `--collection` and `--exclude`.\n */\nexport interface DocumentInputOptions extends DocumentSetOptions {\n /** `-c/--config`. */\n config?: string;\n /** `--no-config`: skip discovery and run on the built-in defaults. */\n noConfig?: boolean;\n}\n\n/**\n * Every file `inputs` match beneath `base`, as absolute paths, split by how\n * they were reached. A file named outright is `named`. A directory expands to\n * everything beneath it, and a glob is left for fast-glob to interpret; both\n * land in `walked`, the half `--ext` filters. A literal path with `(` or `[`\n * in its name still means itself, because only the glob is a pattern.\n */\nfunction expandInputs(\n inputs: string[],\n base: string,\n ignore: string[],\n): { named: string[]; walked: string[] } {\n const named: string[] = [];\n const patterns: string[] = [];\n for (const input of inputs) {\n if (fg.isDynamicPattern(input)) {\n patterns.push(input.replace(/\\\\/g, \"/\"));\n continue;\n }\n let isDirectory: boolean;\n try {\n isDirectory = statSync(resolve(base, input)).isDirectory();\n } catch {\n // Missing: kept as written, so it matches nothing and the caller's\n // empty-match error names it.\n patterns.push(input.replace(/\\\\/g, \"/\"));\n continue;\n }\n const literal = fg.convertPathToPattern(input);\n if (isDirectory) patterns.push(`${literal.replace(/\\/$/, \"\")}/**/*`);\n else named.push(...glob([literal], base, ignore));\n }\n return { named, walked: glob(patterns, base, ignore) };\n}\n\nfunction glob(patterns: string[], base: string, ignore: string[]): string[] {\n if (patterns.length === 0) return [];\n return fg.sync(patterns, {\n cwd: base,\n ignore,\n absolute: true,\n dot: false,\n onlyFiles: true,\n });\n}\n\n/** `--ext` values as lower-case extensions with their dot. */\nfunction normalizeExtensions(exts: readonly string[]): Set<string> {\n return new Set(\n exts.map((e) => {\n const lower = e.toLowerCase();\n return lower.startsWith(\".\") ? lower : `.${lower}`;\n }),\n );\n}\n\n/**\n * The documents a run covers. Positional `paths` are what the operator typed,\n * resolved from `cwd`. Without them the run reads the selected collections,\n * each collection's `paths:` resolved from the config file's directory and\n * narrowed by its own `exclude:`. The family-wide exclusions and `--exclude`\n * apply to both. Labels are relative to `base`, which `documentBase` picks\n * the way `manni meta validate` does, so a collection page's IRI does not\n * depend on where the run started.\n *\n * `-` is not a file, so it is left out of what this returns: the caller reads\n * stdin itself. It still counts as a positional path, so a run given only `-`\n * reads stdin alone and never falls back to the collections.\n */\nexport function resolveDocumentSet(\n config: GraphConfig,\n options: DocumentSetOptions = {},\n verb: DocumentVerb = \"build\",\n cwd = process.cwd(),\n base = documentBase(config, options, cwd),\n): string[] {\n const paths = options.paths ?? [];\n const wanted = options.collection ?? [];\n assertCollectionWithoutPaths(wanted, paths);\n const format = assertInputFormat(paths, options.as);\n if (wanted.length > 0 && config.configSource === null) {\n throw new GraphError(\"--collection needs a config file to select from.\");\n }\n const collections = selectCollections(\n config.collections,\n wanted,\n config.configSource ?? DEFAULT_CONFIG_FILENAME,\n (message) => new GraphError(message),\n );\n\n const exclude = [...FAMILY_EXCLUDE, ...(options.exclude ?? [])];\n let named: string[] = [];\n let walked: string[];\n if (paths.length > 0) {\n ({ named, walked } = expandInputs(\n paths.filter((p) => p !== STDIN),\n cwd,\n exclude,\n ));\n } else {\n // A collection's `exclude:` shapes that collection only, so each is walked\n // with its own and the results are joined.\n const patterns = collections.flatMap((c) => c.paths);\n if (patterns.length === 0) {\n throw new GraphError(\n `No files to ${verb}. Pass paths/globs, or declare a collection under \\`collections:\\` in manni.config.yaml.`,\n );\n }\n walked = collections.flatMap((c) => {\n const found = expandInputs(c.paths, config.configDir, [\n ...exclude,\n ...c.exclude,\n ]);\n return [...found.named, ...found.walked];\n });\n }\n\n const exts = normalizeExtensions(options.ext ?? DEFAULT_EXTENSIONS);\n // A named file is read when a parser claims it, or when `--as` picks one.\n // Anything else is skipped by name, with lint's sentence for it, so the\n // run's \"No input files matched\" never hides a file the user did name.\n const keepNamed = (p: string): boolean => {\n const ext = extname(p);\n if (format !== undefined || parserForExtension(ext) !== undefined) {\n return true;\n }\n const label = relative(base, p).replace(/\\\\/g, \"/\");\n warn(`skipped ${label}: ${unsupportedFormatMessage(ext || label)}`);\n return false;\n };\n const keepWalked = (p: string): boolean => exts.has(extname(p).toLowerCase());\n return [\n ...new Set(\n [...named.filter(keepNamed), ...walked.filter(keepWalked)].map((p) =>\n relative(base, p).replace(/\\\\/g, \"/\"),\n ),\n ),\n ].sort(byCodeUnit);\n}\n\n/**\n * The directory a run's document labels are relative to, decided as\n * `manni meta validate` decides it. Positional paths are what the operator\n * typed, so they are labelled from the working directory. Collection pages are\n * labelled from the config file's directory, so one collection builds one graph\n * from anywhere beneath it. A config that declares no collection has no pages\n * of its own, so the base is then `cwd`.\n */\nexport function documentBase(\n config: GraphConfig,\n options: Pick<DocumentSetOptions, \"paths\"> = {},\n cwd = process.cwd(),\n): string {\n const typed = (options.paths ?? []).length > 0;\n return typed || config.collections.length === 0 ? cwd : config.configDir;\n}\n\n/**\n * The configured route mappings, each `root` rebased from the config file's\n * directory onto `base`. A route then resolves to the label its page carries,\n * whichever directory the labels are relative to.\n */\nexport function routesFrom(config: GraphConfig, base: string): RouteMapping[] {\n return config.routes.map((m) => ({\n ...m,\n root: relative(base, resolve(config.configDir, m.root)).replace(/\\\\/g, \"/\"),\n }));\n}\n\n/** The patterns a run asked about, for the empty-match message. */\nexport function documentSetPatterns(\n config: GraphConfig,\n options: DocumentSetOptions = {},\n): string[] {\n const paths = options.paths ?? [];\n if (paths.length > 0) return paths;\n return selectCollections(\n config.collections,\n options.collection ?? [],\n config.configSource ?? DEFAULT_CONFIG_FILENAME,\n (message) => new GraphError(message),\n ).flatMap((c) => c.paths);\n}\n","/**\n * Deterministic Turtle serialization — the git-diff contract. Canonical form:\n * fixed sorted prefix header; subjects sorted by full IRI; within a subject,\n * rdf:type first (as `a`), then predicates sorted by full IRI; objects sorted\n * (IRIs before literals, each lexicographic); LF line endings, UTF-8, exactly\n * one trailing newline. Byte-identical output for any input quad order.\n *\n * Deliberately not N3.Writer: its formatting is incidental library behavior.\n * Correctness of escaping is guarded by a round-trip test through n3's parser.\n */\nimport type { Quad, Term } from \"./derive.js\";\nimport { byCodeUnit } from \"./sort.js\";\nimport { NS, PREFIXES, RDF_TYPE } from \"./vocab.js\";\n\n/** Conservative PN_LOCAL: shorten only when the local name is trivially safe. */\nconst SAFE_LOCAL = /^[A-Za-z_][A-Za-z0-9_-]*$/;\n\n/**\n * Percent-encode characters the Turtle IRIREF production forbids\n * (controls, space, <>\"{}|^` and backslash) so output always parses,\n * whatever made it into a node value.\n */\n// Forbidden by IRIREF: <>\"{}|^ plus backtick and backslash.\nconst ILLEGAL_IRI_CHARS = '<>\"{}|^\\x60\\x5c';\n\nfunction sanitizeIri(iriValue: string): string {\n let out = \"\";\n for (const ch of iriValue) {\n const code = ch.codePointAt(0) as number;\n const illegal = code <= 0x20 || ILLEGAL_IRI_CHARS.includes(ch);\n out += illegal\n ? \"%\" + code.toString(16).toUpperCase().padStart(2, \"0\")\n : ch;\n }\n return out;\n}\n\n/**\n * Memo: the same predicates/objects recur once per quad; shorten each once.\n * Cleared at the start of every emit so long-lived embedders don't accumulate\n * every IRI ever serialized.\n */\nconst shortenMemo = new Map<string, string>();\n\nfunction shorten(iriValue: string): string {\n const memoized = shortenMemo.get(iriValue);\n if (memoized !== undefined) return memoized;\n let result: string | undefined;\n for (const [prefix, ns] of PREFIXES) {\n if (iriValue.startsWith(ns)) {\n const local = iriValue.slice(ns.length);\n if (SAFE_LOCAL.test(local)) {\n result = `${prefix}:${local}`;\n break;\n }\n }\n }\n result ??= `<${sanitizeIri(iriValue)}>`;\n shortenMemo.set(iriValue, result);\n return result;\n}\n\nfunction escapeLiteral(value: string): string {\n return value\n .replace(/\\\\/g, \"\\\\\\\\\")\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, \"\\\\n\")\n .replace(/\\r/g, \"\\\\r\")\n .replace(/\\t/g, \"\\\\t\");\n}\n\nconst INTEGER = `${NS.xsd}integer`;\nconst INTEGER_RE = /^-?\\d+$/;\n\nfunction renderTerm(term: Term): string {\n if (term.kind === \"iri\") return shorten(term.value);\n if (term.datatype === INTEGER && INTEGER_RE.test(term.value))\n return term.value;\n const quoted = `\"${escapeLiteral(term.value)}\"`;\n return term.datatype ? `${quoted}^^${shorten(term.datatype)}` : quoted;\n}\n\n/** Sort objects: IRIs before literals, each lexicographically. */\nfunction compareTerms(a: Term, b: Term): number {\n if (a.kind !== b.kind) return a.kind === \"iri\" ? -1 : 1;\n const byValue = byCodeUnit(a.value, b.value);\n if (byValue !== 0) return byValue;\n const da = a.kind === \"literal\" ? (a.datatype ?? \"\") : \"\";\n const db = b.kind === \"literal\" ? (b.datatype ?? \"\") : \"\";\n return byCodeUnit(da, db);\n}\n\nexport function emitTurtle(quads: Quad[]): string {\n shortenMemo.clear();\n const lines: string[] = [];\n for (const [prefix, ns] of PREFIXES) {\n lines.push(`@prefix ${prefix}: <${ns}> .`);\n }\n\n // subject → predicate → terms\n const subjects = new Map<string, Map<string, Term[]>>();\n for (const quad of quads) {\n let preds = subjects.get(quad.s);\n if (!preds) {\n preds = new Map();\n subjects.set(quad.s, preds);\n }\n let terms = preds.get(quad.p);\n if (!terms) {\n terms = [];\n preds.set(quad.p, terms);\n }\n terms.push(quad.o);\n }\n\n // Sorting the *entries* rather than the keys: each predicate map comes out\n // of the map with the subject it belongs to, and each term list with its\n // predicate, so nothing is looked up again and nothing has to be asserted.\n const sortedSubjects = [...subjects.entries()].sort(([a], [b]) =>\n byCodeUnit(a, b),\n );\n for (const [subject, preds] of sortedSubjects) {\n const sortedPreds = [...preds.entries()].sort(([a], [b]) => {\n if (a === RDF_TYPE) return b === RDF_TYPE ? 0 : -1;\n if (b === RDF_TYPE) return 1;\n return byCodeUnit(a, b);\n });\n\n const entries = sortedPreds.map(([p, terms], i) => {\n const objects = [...terms].sort(compareTerms).map(renderTerm).join(\", \");\n const pred = p === RDF_TYPE ? \"a\" : shorten(p);\n const terminator = i === sortedPreds.length - 1 ? \" .\" : \" ;\";\n return { pred, objects, terminator };\n });\n\n // A subject is in the map only because a quad put a predicate under it, so\n // `entries` is never empty; the destructuring says so and leaves the rest\n // of the block unreachable if it ever were.\n const [first, ...rest] = entries;\n if (first === undefined) continue;\n lines.push(\"\");\n lines.push(\n `${shorten(subject)} ${first.pred} ${first.objects}${first.terminator}`,\n );\n for (const entry of rest) {\n lines.push(` ${entry.pred} ${entry.objects}${entry.terminator}`);\n }\n }\n\n return `${lines.join(\"\\n\")}\\n`;\n}\n","/**\n * Near-miss detection for the page-level keys the harvest rule reads\n * (ADR 01024, ADR 01028).\n *\n * Five page-level keys are graph inputs — `type`, `concepts`, `applies-to`,\n * `not-applicable-to`, `supersedes` — and unlike the `graph` block, nothing\n * validates them. The `graph` block is `additionalProperties: false`, so a typo\n * inside it is a hard schema error; the same typo at the page level derives\n * silently nothing, because a page may legitimately carry any other key it\n * likes (a site generator's, a linter's, an author's).\n *\n * A schema is therefore the wrong instrument: rejecting unknown page keys would\n * reject every page. What is wrong with `applies_to` is not that dockg does not\n * know it — it is that it is one character from a key dockg *does* know, on a\n * page that declares nothing else of the kind. That is what this detects, and\n * it is the whole scope: dockg does not implement the vocabularies these keys\n * belong to and must not start claiming their facts (ADR 01024).\n *\n * Warnings only. A near miss is a suspicion, not a finding, and a suspicion\n * must never fail a build.\n */\nimport { PAGE_TYPE_TO_TOPIC_TYPE } from \"./iirds.js\";\nimport { byCodeUnit } from \"./sort.js\";\nimport type { DocModel } from \"../types.js\";\n\n/**\n * The page-level keys dockg reads, in the spelling it expects.\n *\n * Five are `resolveGraph`'s harvest inputs (ADR 01024). The localization three\n * are read straight by the emitter — `lang`/`language` into `dcterms:language`,\n * `translation-of` into the schema.org translation pair (ADR 01037) — and are\n * listed here for the same reason: a typo in any of them derives nothing while\n * looking exactly like a declared fact.\n */\nexport const HARVESTED_KEYS: readonly string[] = [\n \"applies-to\",\n \"concepts\",\n \"lang\",\n \"language\",\n \"not-applicable-to\",\n \"supersedes\",\n \"translation-of\",\n \"type\",\n];\n\n/**\n * Levenshtein distance, capped: anything past `max` returns `max + 1`, since\n * the caller only cares whether a candidate is *close*.\n */\nfunction distance(a: string, b: string, max: number): number {\n if (a === b) return 0;\n if (Math.abs(a.length - b.length) > max) return max + 1;\n let prev = Array.from({ length: b.length + 1 }, (_, i) => i);\n for (let i = 1; i <= a.length; i++) {\n const row = [i];\n for (let j = 1; j <= b.length; j++) {\n row[j] = Math.min(\n (prev[j] ?? 0) + 1,\n (row[j - 1] ?? 0) + 1,\n (prev[j - 1] ?? 0) + (a[i - 1] === b[j - 1] ? 0 : 1),\n );\n }\n prev = row;\n }\n return prev[b.length] ?? max + 1;\n}\n\n/**\n * The known name a candidate was probably meant to be, or undefined.\n *\n * Distance 1 for short names, 2 for longer ones: `type` and `types` differ by\n * one and mean different things, while `not-applicable-to` can absorb two typos\n * and still be unmistakable. Separator-only differences (`applies_to`,\n * `appliesTo`) normalize to an exact match and are always caught.\n */\nfunction nearestKnown(\n candidate: string,\n known: readonly string[],\n): string | undefined {\n // Split camelCase BEFORE lowercasing — doing it after is a no-op, because\n // there is no uppercase left to match. `appliesTo` then reaches `applies-to`\n // exactly, instead of relying on the distance fallback to rescue it, and\n // `notApplicabelTo` (two typos plus a case boundary) becomes reachable at\n // all.\n const normalize = (s: string): string =>\n s\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .toLowerCase()\n .replace(/[_\\s]+/g, \"-\");\n const c = normalize(candidate);\n for (const k of known) {\n if (c === normalize(k) && candidate !== k) return k;\n }\n let best: { key: string; d: number } | undefined;\n for (const k of known) {\n const max = k.length > 8 ? 2 : 1;\n const d = distance(c, normalize(k), max);\n if (d > max) continue;\n if (!best || d < best.d) best = { key: k, d };\n }\n return best?.key;\n}\n\n/**\n * Warnings for page-level keys and page `type` values that look like harvest\n * inputs but are not. Sorted, so the output is deterministic like everything\n * else dockg emits.\n */\nexport function harvestWarnings(docs: readonly DocModel[]): string[] {\n const out: string[] = [];\n const mappedTypes = Object.keys(PAGE_TYPE_TO_TOPIC_TYPE);\n\n for (const doc of docs) {\n const fm = doc.frontmatter;\n const present = new Set(Object.keys(fm));\n\n for (const key of present) {\n if (HARVESTED_KEYS.includes(key)) continue;\n const meant = nearestKnown(key, HARVESTED_KEYS);\n // Only suspicious if the page does not already declare the real key: a\n // page carrying both `applies-to` and `applies_to` has made its choice.\n if (meant === undefined || present.has(meant)) continue;\n out.push(\n `${doc.path}: page key \"${key}\" is not read by manni graph and looks like \"${meant}\" — nothing was derived from it`,\n );\n }\n\n // A page `type` outside the map derives nothing, by design: dockg\n // references iiRDS terms and never mints them. That is correct for\n // `blog-post`, and almost never what the author meant for `how to`.\n const type = fm[\"type\"];\n // Object.hasOwn, not `in`: `type: constructor` and `type: toString` walk\n // the prototype chain and would be read as mapped types, silently skipping\n // the check.\n if (\n typeof type === \"string\" &&\n !Object.hasOwn(PAGE_TYPE_TO_TOPIC_TYPE, type)\n ) {\n const meant = nearestKnown(type, mappedTypes);\n if (meant !== undefined) {\n out.push(\n `${doc.path}: page type \"${type}\" maps to no iiRDS topic type and looks like \"${meant}\" — no graph.type was derived`,\n );\n }\n }\n }\n\n return out.sort(byCodeUnit);\n}\n","/**\n * One-pass git history collection for provenance derivation. A single\n * `git log` subprocess covers the whole corpus: per-file creation and\n * last-modification committer dates, author names, and rename chains\n * (followed backward so history accrues to the file's current path).\n * Deterministic per commit — the wall clock never enters the result.\n *\n * Author emails are deliberately not collected into the result (privacy):\n * names only, matching frontmatter author handling.\n */\nimport { GraphError } from \"../types.js\";\nimport { realExec, type ExecFn } from \"@hawkeyexl/inference\";\nimport { posix } from \"node:path\";\nimport { normalizeDocPath } from \"./iri.js\";\n\nexport interface GitFileHistory {\n /** Committer ISO date of the oldest commit touching the file (or its earlier names). */\n created?: string;\n /** Committer ISO date of the newest commit touching it. */\n modified?: string;\n /** Unique author names, newest contribution first. */\n authors: string[];\n /** Earlier paths of this file, nearest rename first (git -M heuristic; best-effort). */\n renamedFrom: string[];\n}\n\nexport interface GitHistory {\n /** HEAD committer ISO date — stamps the build activity's prov:endedAtTime. */\n headTime?: string;\n files: Map<string, GitFileHistory>;\n}\n\n/**\n * Git versions print a UTC committer date from `%cI` as either `+00:00` or\n * `Z`. Both name the same instant, so one spelling keeps the graph identical\n * whichever git wrote it. Other offsets pass through unchanged.\n */\nexport function canonicalGitTime(time: string): string {\n return time.replace(/[+-]00:00$/, \"Z\");\n}\n\n/** Record line marker: %x01 keeps commit headers unambiguous in the stream. */\nconst RECORD = \"\\u0001\";\nconst STATUS_LINE = /^([AMDRC])\\d*\\t(.+)$/;\n\n/**\n * Undo git's C-style path quoting. Even with core.quotepath=off, paths\n * containing double quotes, backslashes, or control characters arrive as\n * `\"docs/a\\\"b.md\"` — quotepath only disables quoting of non-ASCII bytes.\n * Octal escapes are raw UTF-8 bytes, decoded together at the end.\n */\nexport function unquoteGitPath(path: string): string {\n if (path.length < 2 || !path.startsWith('\"') || !path.endsWith('\"')) {\n return path;\n }\n const inner = path.slice(1, -1);\n const bytes: number[] = [];\n for (let i = 0; i < inner.length; i++) {\n // `?? \"\"` cannot fire under the loop's own bound; it is how that is said\n // without an assertion, and an empty chunk contributes no bytes anyway.\n const ch = inner[i] ?? \"\";\n if (ch !== \"\\\\\") {\n for (const byte of Buffer.from(ch, \"utf8\")) bytes.push(byte);\n continue;\n }\n const next = inner[++i];\n if (next === undefined) break;\n if (next >= \"0\" && next <= \"7\") {\n let octal = next;\n while (octal.length < 3) {\n const digit = inner[i + 1];\n if (digit === undefined || digit < \"0\" || digit > \"7\") break;\n octal += digit;\n i++;\n }\n bytes.push(Number.parseInt(octal, 8));\n } else {\n const map: Record<string, string> = { n: \"\\n\", t: \"\\t\", r: \"\\r\" };\n for (const byte of Buffer.from(map[next] ?? next, \"utf8\"))\n bytes.push(byte);\n }\n }\n return Buffer.from(bytes).toString(\"utf8\");\n}\n\n/**\n * Unset every inherited `GIT_*` variable for the child process.\n *\n * git exports GIT_DIR, GIT_INDEX_FILE, GIT_WORK_TREE and friends to the\n * subprocesses it runs — every hook, and anything spawned from one. Inheriting\n * them makes `git log` read *that* repository instead of `cwd`, so the same\n * inputs would yield a different graph depending on who invoked dockg, and a\n * build outside a repo would silently succeed against an unrelated one. Both\n * break the determinism contract, so the ambient state is dropped wholesale\n * rather than enumerated: git keeps adding variables to this namespace.\n */\nfunction clearedGitEnv(): Record<string, string | undefined> {\n const cleared: Record<string, string | undefined> = {};\n for (const key of Object.keys(process.env)) {\n if (key.startsWith(\"GIT_\")) cleared[key] = undefined;\n }\n return cleared;\n}\n\nexport async function collectGitHistory(\n cwd: string,\n exec: ExecFn = realExec,\n): Promise<GitHistory> {\n const git = async (args: string[]): Promise<string> => {\n const result = await exec([\"git\", ...args], {\n cwd,\n timeoutMs: 60000,\n env: clearedGitEnv(),\n });\n // Messages stay neutral about *why* git provenance was requested; the\n // caller frames the failure as an error or a warning.\n if (result.spawnError) {\n throw new GraphError(\n `git could not be run: ${result.spawnError} (is git installed and on PATH?)`,\n );\n }\n if (result.timedOut) {\n throw new GraphError(\n \"`git log` timed out after 60s — the repo history may be too large for whole-history provenance\",\n );\n }\n if (result.code !== 0) {\n const detail = result.stderr.trim().slice(-300);\n throw new GraphError(\n `git history could not be read (is ${cwd} a git repo with at least one commit?)${detail ? ` — git said: ${detail}` : \"\"}`,\n );\n }\n return result.stdout;\n };\n // Keys are relative to `cwd`, the directory the caller's labels count from\n // (`documentBase`). git reports paths from the repository root, so each is\n // rebased by `cwd`'s own place in the repository. `--relative` would do that\n // too, but it drops every path outside `cwd`: a page labelled `../x.md`, and\n // a rename from outside, whose fold into the current name is the point.\n const prefix = `/${(await git([\"rev-parse\", \"--show-prefix\"])).trim()}`;\n const label = (raw: string): string =>\n posix.relative(prefix, `/${normalizeDocPath(unquoteGitPath(raw))}`);\n const stdout = await git([\n \"-c\",\n \"core.quotepath=off\",\n \"log\",\n `--format=${RECORD}%H%x09%an%x09%cI`,\n \"--name-status\",\n \"-M\",\n ]);\n if (stdout.trim() === \"\") {\n throw new GraphError(\n `git history could not be read (is ${cwd} a git repo with at least one commit?)`,\n );\n }\n\n const files = new Map<string, GitFileHistory>();\n /** Maps a historical path to the file's current (newest) path. */\n const currentName = new Map<string, string>();\n let headTime: string | undefined;\n let commitAuthor = \"\";\n let commitTime = \"\";\n\n const entry = (path: string): GitFileHistory => {\n let file = files.get(path);\n if (!file) {\n file = { authors: [], renamedFrom: [] };\n files.set(path, file);\n }\n return file;\n };\n\n /** Register that the commit being parsed touched `path` (as known at that time). */\n const touch = (pathThen: string): GitFileHistory => {\n const path = label(pathThen);\n const current = currentName.get(path) ?? path;\n const file = entry(current);\n // Walking newest→oldest: first touch wins `modified`, every touch pushes\n // `created` older, authors keep first-appearance (newest) order.\n file.modified ??= commitTime;\n file.created = commitTime;\n if (!file.authors.includes(commitAuthor)) file.authors.push(commitAuthor);\n return file;\n };\n\n for (const line of stdout.split(\"\\n\")) {\n if (line.startsWith(RECORD)) {\n const [, author = \"\", rawTime = \"\"] = line.slice(1).split(\"\\t\");\n const time = canonicalGitTime(rawTime);\n commitAuthor = author;\n commitTime = time;\n headTime ??= time;\n continue;\n }\n const match = STATUS_LINE.exec(line);\n // Both groups are mandatory in the pattern, so a match carries both;\n // requiring them subsumes the bare `if (!match) continue` this replaces.\n const status = match?.[1];\n const rest = match?.[2];\n if (status === undefined || rest === undefined) continue;\n if (status === \"R\" || status === \"C\") {\n const [oldPath, newPath] = rest.split(\"\\t\");\n if (!oldPath || !newPath) continue;\n if (status === \"C\") {\n // Copies create a new file from an old one; the old file's own history\n // is separate. Record the touch on the copy only.\n touch(newPath);\n continue;\n }\n const file = touch(newPath);\n const normalizedOld = label(oldPath);\n file.renamedFrom.push(normalizedOld);\n // Older commits refer to the pre-rename path; fold them into this file.\n const normalizedNew = label(newPath);\n currentName.set(\n normalizedOld,\n currentName.get(normalizedNew) ?? normalizedNew,\n );\n } else {\n touch(rest);\n }\n }\n\n return { headTime, files };\n}\n","/**\n * `x-manni-graph-output` (proposal 0051 §5), on graph's side of the seam.\n *\n * Which fields belong in a published graph is a property of the field, not of\n * this tool, so it is recorded where the field is defined. The keyword is a\n * boolean beside a top-level property, registered on every Ajv `manni meta`\n * builds and read back through `Validator.graphOutputPreferences`. Absent means\n * `true`: every field is harvested. A mark nested inside `graph` is ignored, as\n * 0047 rule 2 ignores an `x-manni-location` there — the mark governs a\n * top-level key, and `graph` is the top-level key.\n *\n * The filter runs once, before `deriveGraph`, because all four published\n * outputs descend from what derivation produces: `emitTurtle` writes the graph,\n * and JSON-LD, the iiRDS package and the search index are all built by reading\n * that graph back. Dropping the field here keeps it out of every one of them.\n *\n * Encrypted values (proposal 0045) are harvested like any other value. graph\n * never decrypts, so what lands in the graph is the `~…` token, which says a\n * value exists and nothing about what it is. A field that should not reach a\n * published graph at all is marked `false` — one mechanism for \"keep this out\n * of the output\", rather than one rule for encryption and another for\n * everything else (0051 stress test 4).\n */\nimport type { MetaPageView } from \"../../meta/internal.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\nimport { GraphError } from \"../types.js\";\nimport type { DocModel } from \"../types.js\";\n\n/**\n * `docs`, with every top-level frontmatter key its schemas mark\n * `x-manni-graph-output: false` removed.\n *\n * A page's schemas are the set `manni meta validate` resolves for it (proposal\n * 0074): its own `$schema`, then meta's overrides, `schemas:`, `strict` and\n * the default set, read from meta's section of the same config. graph keeps\n * no schema set of its own, so one config answers both what a page is checked\n * against and what its published graph may carry.\n *\n * The docs arrive with their manifests' values already merged\n * (`withExternalMetadata`), so a field kept beside the page is filtered by\n * the same mark as one kept on it.\n *\n * A document whose schemas mark nothing is returned as it came in, so the\n * common case allocates nothing.\n */\nexport async function suppressGraphOutput(\n docs: readonly DocModel[],\n sets: Pick<MetaPageView, \"validator\" | \"refsFor\">,\n): Promise<DocModel[]> {\n const out: DocModel[] = [];\n for (const doc of docs) {\n let preferences: Map<string, boolean>;\n try {\n const refs = sets.refsFor(doc.path, doc.frontmatter);\n preferences = await sets.validator.graphOutputPreferences(doc.frontmatter, refs);\n } catch (e) {\n // Loudly, and for the whole run. The schema is what decides which fields\n // a published graph may carry; a graph built while it could not be read\n // is a graph nobody checked, and quietly building one is the failure\n // this keyword exists to prevent.\n throw new GraphError(\n `${doc.path}: cannot read which fields the graph may carry: ${errorMessage(e)}`,\n );\n }\n\n const suppressed = [...preferences]\n .filter(([, allowed]) => !allowed)\n .map(([key]) => key);\n if (suppressed.length === 0) {\n out.push(doc);\n continue;\n }\n\n const frontmatter: Record<string, unknown> = { ...doc.frontmatter };\n for (const key of suppressed) Reflect.deleteProperty(frontmatter, key);\n out.push({ ...doc, frontmatter });\n }\n return out;\n}\n","/**\n * A page's metadata as `manni meta validate` reads it: its frontmatter, plus\n * every key an external-metadata manifest of one of its collections owns\n * (proposals 0037, 0041, 0047, 0058 and 0068).\n *\n * A corpus that keeps `owner`, `last-updated` or `meta-provenance` in a\n * `{page}.meta.yaml` beside each page would otherwise read to graph as a set\n * of pages that declare none of them. So graph reads through meta's merge,\n * not a loader of its own: the join, ownership and keyless-manifest rules are\n * the ones `meta validate` applies, and so are its refusals, which reach the\n * user in meta's words and exit 2.\n *\n * The config is meta's section of the file the run is under, the same one\n * graph already reads the output marks from (proposal 0074). `--no-config`\n * declares no collection, so no manifest is read, exactly as meta reads none.\n * A page read from stdin belongs to no collection, so no manifest supplies it.\n *\n * Encrypted values (proposal 0045) are merged as the manifest holds them.\n * graph never decrypts, so the graph carries the `~…` token.\n */\nimport { resolve } from \"node:path\";\nimport { metaPageView, type MetaPageView } from \"../../meta/internal.js\";\nimport { errorMessage } from \"../../shared/errors.js\";\nimport { GraphError, type DocModel } from \"../types.js\";\nimport type { DocFormat } from \"./analyze.js\";\nimport { STDIN_PATH } from \"./iri.js\";\n\n/** Which config a run reads meta's section of, as its flags said. */\nexport interface MetaViewSource {\n /** `-c/--config`. */\n configPath?: string;\n /** `--no-config`. */\n noConfig?: boolean;\n}\n\n/**\n * Meta's view of the run's pages. `paths` are the run's documents relative\n * to `base` (`documentBase`), and the view's labels are too. `-c` stays\n * relative to `cwd`, where it was typed. A `{page}` manifest is read for\n * exactly these. A manifest meta refuses is refused here in meta's sentence,\n * as an operational error.\n */\nexport async function openMetaView(\n source: MetaViewSource,\n cwd: string,\n paths: readonly string[],\n base = cwd,\n): Promise<MetaPageView> {\n try {\n return await metaPageView({\n cwd: base,\n ...(source.configPath === undefined\n ? {}\n : { configPath: resolve(cwd, source.configPath) }),\n ...(source.noConfig === undefined ? {} : { noConfig: source.noConfig }),\n pages: paths.filter((p) => p !== STDIN_PATH).map((p) => resolve(base, p)),\n });\n } catch (e) {\n throw new GraphError(errorMessage(e));\n }\n}\n\n/** A page's own metadata and what its manifests add to it. */\nexport interface MergedPage {\n /** The page's metadata with every manifest-supplied key in place. */\n data: Record<string, unknown>;\n /** The top-level keys a manifest supplied, with their merged values. */\n supplied: Record<string, unknown>;\n}\n\n/** The `/key` pointer of a top-level key, RFC 6901 escaped. */\nfunction pointerOf(key: string): string {\n return `/${key.replace(/~/g, \"~0\").replace(/\\//g, \"~1\")}`;\n}\n\n/**\n * Merge one page's frontmatter with its manifests. `present` is whether the\n * page has a frontmatter block at all, and `format` is what graph parsed it as.\n */\nexport async function mergePage(\n view: MetaPageView,\n path: string,\n frontmatter: Record<string, unknown>,\n present: boolean,\n format: DocFormat,\n): Promise<MergedPage> {\n let merged;\n try {\n merged = await view.merge(path, {\n data: frontmatter,\n present,\n format,\n lineFor: () => undefined,\n });\n } catch (e) {\n throw new GraphError(errorMessage(e));\n }\n const data = merged.extracted.data;\n const supplied: Record<string, unknown> = {};\n for (const key of Object.keys(data)) {\n if (merged.locate(pointerOf(key)) !== undefined) supplied[key] = data[key];\n }\n return { data, supplied };\n}\n\n/** `docs`, each with its manifests' values merged into its frontmatter. */\nexport async function withExternalMetadata(\n docs: readonly DocModel[],\n view: MetaPageView,\n): Promise<DocModel[]> {\n const out: DocModel[] = [];\n for (const doc of docs) {\n const { data } = await mergePage(\n view,\n doc.path,\n doc.frontmatter,\n doc.frontmatterPresent,\n doc.format,\n );\n // A run with no manifest hands the page's own object back, so the common\n // case allocates nothing.\n out.push(data === doc.frontmatter ? doc : { ...doc, frontmatter: data });\n }\n return out;\n}\n"],"mappings":"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","names":["readFileSync","resolve","resolved","anchor","createHash","createHash","extname","extname","resolve","resolve","resolve","readFileSync"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../package.json"],"sourcesContent":["{\n \"name\": \"@hawkeyexl/manni\",\n \"version\": \"4.11.0\",\n \"description\": \"One command line for documentation that is meant to be checked. `manni meta` validates the presence and format of document metadata (Markdown frontmatter and more) against JSON Schema, built for CI. Formerly docmeta.\",\n \"type\": \"module\",\n \"bin\": {\n \"manni\": \"dist/cli.js\",\n \"docmeta\": \"dist/docmeta.js\"\n },\n \"main\": \"dist/index.js\",\n \"module\": \"dist/index.js\",\n \"types\": \"dist/index.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.js\"\n },\n \"./graph/runtime\": {\n \"types\": \"./dist/graph/runtime.d.ts\",\n \"import\": \"./dist/graph/runtime.js\"\n },\n \"./graph/embed\": {\n \"types\": \"./dist/graph/embed.d.ts\",\n \"import\": \"./dist/graph/embed.js\"\n },\n \"./package.json\": \"./package.json\"\n },\n \"files\": [\n \"dist\",\n \"schemas\",\n \"plugin\",\n \"shapes\",\n \"templates\"\n ],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/hawkeyexl/manni.git\"\n },\n \"homepage\": \"https://hawkeyexl.github.io/manni/\",\n \"bugs\": {\n \"url\": \"https://github.com/hawkeyexl/manni/issues\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"engines\": {\n \"node\": \">=24\"\n },\n \"scripts\": {\n \"prebuild\": \"npm run check:deps\",\n \"build\": \"node scripts/clean-dist.mjs && tsup\",\n \"dev\": \"node scripts/clean-dist.mjs && tsup --watch\",\n \"pretest\": \"npm run check:deps\",\n \"test\": \"vitest run\",\n \"test:watch\": \"vitest\",\n \"test:graph:real\": \"vitest run --config vitest.graph-real.config.ts\",\n \"test:coverage\": \"vitest run --coverage\",\n \"pretypecheck\": \"npm run check:deps\",\n \"typecheck\": \"tsc --noEmit\",\n \"lint\": \"eslint .\",\n \"check:deps\": \"node scripts/check-deps.mjs\",\n \"query:ui\": \"npm run build && node dist/cli.js meta query --db .manni/meta/query.db && node scripts/query-ui.mjs .manni/meta/query.db\",\n \"check:tgdp-pin\": \"node scripts/lint-check-tgdp-pin.mjs\",\n \"smoke:lint\": \"npm run build && node scripts/lint-smoke.mjs\",\n \"docs:check-cli\": \"node scripts/check-cli-reference.mjs\",\n \"docs:check-action\": \"node scripts/check-action-reference.mjs\",\n \"docs:check-api\": \"node scripts/check-api-reference.mjs\",\n \"docs:check-links\": \"node scripts/check-doc-links.mjs\",\n \"docs:check-docevals\": \"node dist/cli.js docevals run --deterministic-only --no-generate\",\n \"docs:check-graph\": \"node scripts/check-docs-graph.mjs\",\n \"docs:check-tables\": \"node scripts/check-table-rows.mjs\",\n \"docs:check-versions\": \"node scripts/check-versions.mjs\",\n \"docs:sync-versions\": \"node scripts/sync-versions.mjs\",\n \"schemas:sync\": \"node scripts/sync-builtin-schemas.mjs\",\n \"schemas:check\": \"node scripts/check-builtin-schemas.mjs\",\n \"schemas:check-published\": \"node scripts/check-published-schemas.mjs\",\n \"commitlint\": \"commitlint --edit\",\n \"semantic-release\": \"semantic-release\",\n \"prepare\": \"node scripts/prepare.mjs\",\n \"prepublishOnly\": \"npm run build\"\n },\n \"keywords\": [\n \"frontmatter\",\n \"metadata\",\n \"json-schema\",\n \"markdown\",\n \"validation\",\n \"cli\",\n \"ci\",\n \"okf\"\n ],\n \"license\": \"MIT\",\n \"overrides\": {\n \"esbuild\": \"^0.28.2\"\n },\n \"dependencies\": {\n \"@apidevtools/json-schema-ref-parser\": \"^11.9.3\",\n \"@asciidoctor/core\": \"^3.0.4\",\n \"@axe-core/playwright\": \"^4.13.0\",\n \"@hawkeyexl/inference\": \"^0.5.0\",\n \"@inquirer/prompts\": \"^7.10.1\",\n \"@types/n3\": \"^1.26.3\",\n \"@xmldom/xmldom\": \"^0.9.12\",\n \"ajv\": \"^8.17.1\",\n \"ajv-draft-04\": \"^1.0.0\",\n \"ajv-formats\": \"^3.0.1\",\n \"commander\": \"^15.0.0\",\n \"fast-glob\": \"^3.3.2\",\n \"github-slugger\": \"^2.0.0\",\n \"mdast-util-to-string\": \"^4.0.0\",\n \"minisearch\": \"^7.2.0\",\n \"n3\": \"^1.26.0\",\n \"parse5\": \"^8.0.1\",\n \"picocolors\": \"^1.1.1\",\n \"picomatch\": \"^4.0.7\",\n \"playwright-core\": \"^1.63.0\",\n \"rdf-validate-shacl\": \"^0.6.5\",\n \"remark-frontmatter\": \"^5.0.0\",\n \"remark-gfm\": \"^4.0.1\",\n \"remark-mdx\": \"^3.1.1\",\n \"remark-parse\": \"^11.0.0\",\n \"smol-toml\": \"^1.8.0\",\n \"unified\": \"^11.0.5\",\n \"unist-util-visit\": \"^5.1.0\",\n \"yaml\": \"^2.6.1\"\n },\n \"devDependencies\": {\n \"@commitlint/cli\": \"^21.2.2\",\n \"@commitlint/config-conventional\": \"^21.2.2\",\n \"@comunica/query-sparql-rdfjs-lite\": \"^5.3.0\",\n \"@eslint/js\": \"^10.0.1\",\n \"@rdfjs/types\": \"^2.0.1\",\n \"@semantic-release/changelog\": \"^6.0.3\",\n \"@semantic-release/commit-analyzer\": \"^13.0.1\",\n \"@semantic-release/git\": \"^10.0.1\",\n \"@semantic-release/github\": \"^12.0.8\",\n \"@semantic-release/npm\": \"^13.1.5\",\n \"@semantic-release/release-notes-generator\": \"^14.1.1\",\n \"@types/jsonld\": \"^1.5.15\",\n \"@types/mdast\": \"^4.0.4\",\n \"@types/node\": \"^26.3.0\",\n \"@types/picomatch\": \"^4.0.3\",\n \"@types/unist\": \"^3.0.3\",\n \"@types/yauzl\": \"^3.4.0\",\n \"@vitest/coverage-v8\": \"^4.1.11\",\n \"eslint\": \"^10.9.1\",\n \"globals\": \"^17.11.0\",\n \"husky\": \"^9.1.7\",\n \"jsonld\": \"^9.0.0\",\n \"rdfxml-streaming-parser\": \"^3.3.0\",\n \"semantic-release\": \"^25.0.9\",\n \"tsup\": \"^8.3.5\",\n \"typescript\": \"^6.0.3\",\n \"typescript-eslint\": \"^8.68.0\",\n \"vitest\": \"^4.1.11\",\n \"yauzl\": \"^3.4.0\"\n },\n \"peerDependencies\": {\n \"@huggingface/transformers\": \">=4\",\n \"node-llama-cpp\": \"^3.19.0\"\n },\n \"peerDependenciesMeta\": {\n \"@huggingface/transformers\": {\n \"optional\": true\n },\n \"node-llama-cpp\": {\n \"optional\": true\n }\n }\n}\n"],"mappings":"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","names":[]}
|