@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,10 +1,13 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
import {
|
|
3
|
+
renderFindingsGithub
|
|
4
|
+
} from "./chunk-QNDDPXFR.js";
|
|
2
5
|
import {
|
|
3
6
|
renderFindingsJson,
|
|
4
7
|
renderFormatsJson,
|
|
5
8
|
renderGetJson,
|
|
6
9
|
renderListJson
|
|
7
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-UXMCHBOJ.js";
|
|
8
11
|
import {
|
|
9
12
|
renderFindingsPretty,
|
|
10
13
|
renderFormatsPretty,
|
|
@@ -12,7 +15,7 @@ import {
|
|
|
12
15
|
renderListPretty,
|
|
13
16
|
renderValeWiring,
|
|
14
17
|
renderWritePretty
|
|
15
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-STPGIKPY.js";
|
|
16
19
|
import {
|
|
17
20
|
FINDING_FORMATS,
|
|
18
21
|
JUNIT_CLASSNAME,
|
|
@@ -24,22 +27,25 @@ import {
|
|
|
24
27
|
runCheck,
|
|
25
28
|
summarize,
|
|
26
29
|
toResults
|
|
27
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-QDC7JPFG.js";
|
|
28
31
|
import {
|
|
29
32
|
LIST_FORMATS,
|
|
30
33
|
runList
|
|
31
|
-
} from "./chunk-
|
|
32
|
-
import {
|
|
33
|
-
renderFindingsGithub
|
|
34
|
-
} from "./chunk-LPIF5LIE.js";
|
|
34
|
+
} from "./chunk-VFAKGIDG.js";
|
|
35
35
|
import {
|
|
36
|
+
DEFAULT_CRAWL_MIN_PAGES,
|
|
37
|
+
DEFAULT_FILL_CACHE_DIR,
|
|
38
|
+
DEFAULT_FILL_CONFIDENCE,
|
|
36
39
|
DEFAULT_LANGUAGE,
|
|
37
40
|
DITA_HOLDS,
|
|
38
41
|
DOCBOOK_HOLDS,
|
|
39
42
|
LIST_HOLDS,
|
|
40
43
|
MANIFEST_FORMAT,
|
|
44
|
+
SKOS,
|
|
45
|
+
SKOS_PROPERTIES,
|
|
41
46
|
TBX_V3_NAMESPACE,
|
|
42
47
|
TERM_FIELDS,
|
|
48
|
+
TERM_MATCH_FIELDS,
|
|
43
49
|
TERM_READERS,
|
|
44
50
|
TERM_RULES,
|
|
45
51
|
TERM_WRITE_FORMATS,
|
|
@@ -70,52 +76,70 @@ import {
|
|
|
70
76
|
resolveTermRun,
|
|
71
77
|
rstEntry,
|
|
72
78
|
sharedLanguage,
|
|
79
|
+
slugOf,
|
|
73
80
|
tbxEntryLines,
|
|
74
81
|
tbxInput,
|
|
75
82
|
tbxSourceOf,
|
|
76
83
|
valeConfigFor,
|
|
77
84
|
xmlAttribute,
|
|
78
85
|
xmlText
|
|
79
|
-
} from "./chunk-
|
|
80
|
-
import "./chunk-77AINBYM.js";
|
|
86
|
+
} from "./chunk-FKAZUZQU.js";
|
|
81
87
|
import "./chunk-IKEWBMCN.js";
|
|
82
|
-
import "./chunk-
|
|
83
|
-
import "./chunk-
|
|
88
|
+
import "./chunk-YUTVAMWW.js";
|
|
89
|
+
import "./chunk-JSSM7VVV.js";
|
|
84
90
|
import {
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
import "./chunk-PCQ7ELJH.js";
|
|
91
|
+
DEFAULT_CHUNK_CHARS,
|
|
92
|
+
splitBody
|
|
93
|
+
} from "./chunk-PS257NIU.js";
|
|
89
94
|
import {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
splitList
|
|
93
|
-
} from "./chunk-GV56WGL2.js";
|
|
95
|
+
mergeMetaProvenance
|
|
96
|
+
} from "./chunk-2OZF2VUB.js";
|
|
94
97
|
import {
|
|
95
98
|
OMITTED_WHEN_CLEAN,
|
|
96
99
|
renderJunit,
|
|
97
100
|
renderSarif
|
|
98
|
-
} from "./chunk-
|
|
101
|
+
} from "./chunk-SGR7ZAVE.js";
|
|
102
|
+
import "./chunk-QEAGL4V5.js";
|
|
103
|
+
import {
|
|
104
|
+
collect,
|
|
105
|
+
readStdin,
|
|
106
|
+
splitList
|
|
107
|
+
} from "./chunk-SMHAYK6I.js";
|
|
108
|
+
import "./chunk-DSWKBZWW.js";
|
|
99
109
|
import {
|
|
100
110
|
STDIN_TOKEN,
|
|
101
111
|
extractorByName,
|
|
102
112
|
extractorForExtension
|
|
103
|
-
} from "./chunk-
|
|
104
|
-
import
|
|
105
|
-
|
|
106
|
-
} from "./chunk-YEUYKR62.js";
|
|
113
|
+
} from "./chunk-RGLFV4KO.js";
|
|
114
|
+
import "./chunk-77AINBYM.js";
|
|
115
|
+
import "./chunk-MNH7QO4Z.js";
|
|
107
116
|
import {
|
|
108
117
|
shouldColor
|
|
109
118
|
} from "./chunk-RNVYGWIC.js";
|
|
110
|
-
import "./chunk-MNH7QO4Z.js";
|
|
111
|
-
import "./chunk-QLWC7MKD.js";
|
|
112
119
|
import {
|
|
113
|
-
|
|
120
|
+
fail
|
|
121
|
+
} from "./chunk-YEUYKR62.js";
|
|
122
|
+
import "./chunk-OTJOBZJ5.js";
|
|
123
|
+
import {
|
|
124
|
+
notice,
|
|
125
|
+
warn
|
|
114
126
|
} from "./chunk-HX44GB4Z.js";
|
|
115
|
-
import
|
|
127
|
+
import {
|
|
128
|
+
DEFAULT_PROVIDER,
|
|
129
|
+
LOCAL_FLAG_HELP,
|
|
130
|
+
assertKnownProvider,
|
|
131
|
+
assertLocalFlag,
|
|
132
|
+
assertModelHasProvider,
|
|
133
|
+
localNotice,
|
|
134
|
+
noOfflineModel,
|
|
135
|
+
offlineIdentity,
|
|
136
|
+
providerSpecFor,
|
|
137
|
+
resolveIdentity,
|
|
138
|
+
selectProvider
|
|
139
|
+
} from "./chunk-VM7VAFJW.js";
|
|
116
140
|
import {
|
|
117
141
|
package_default
|
|
118
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-DHGB4JBG.js";
|
|
119
143
|
import "./chunk-OWBRDNRZ.js";
|
|
120
144
|
import {
|
|
121
145
|
errorMessage
|
|
@@ -125,6 +149,143 @@ import "./chunk-2H7UOFLK.js";
|
|
|
125
149
|
// src/term/cli.ts
|
|
126
150
|
import { Command } from "commander";
|
|
127
151
|
|
|
152
|
+
// src/term/commands/fill.ts
|
|
153
|
+
import { existsSync } from "node:fs";
|
|
154
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
155
|
+
import { dirname as dirname2, extname as extname2, join as join3, resolve as resolve2 } from "node:path";
|
|
156
|
+
import {
|
|
157
|
+
JsonCache,
|
|
158
|
+
buildCacheKey,
|
|
159
|
+
completeValidatedJSON,
|
|
160
|
+
makeProvider as makeInferenceProvider,
|
|
161
|
+
sha256,
|
|
162
|
+
validatorFor
|
|
163
|
+
} from "@hawkeyexl/inference";
|
|
164
|
+
|
|
165
|
+
// src/term/core/fill-plan.ts
|
|
166
|
+
import { dirname, extname } from "node:path";
|
|
167
|
+
function fold(value) {
|
|
168
|
+
return value.trim().toLowerCase();
|
|
169
|
+
}
|
|
170
|
+
function termIndex(terms) {
|
|
171
|
+
const index = /* @__PURE__ */ new Map();
|
|
172
|
+
const claim = (key, term) => {
|
|
173
|
+
if (!index.has(fold(key))) index.set(fold(key), term);
|
|
174
|
+
};
|
|
175
|
+
for (const term of terms) {
|
|
176
|
+
claim(term.record.label, term);
|
|
177
|
+
claim(term.id, term);
|
|
178
|
+
for (const alt of term.record["alt-labels"] ?? []) claim(alt, term);
|
|
179
|
+
}
|
|
180
|
+
return index;
|
|
181
|
+
}
|
|
182
|
+
function addUnique(list, value) {
|
|
183
|
+
if (!list.some((v) => fold(v) === fold(value))) list.push(value);
|
|
184
|
+
}
|
|
185
|
+
var EDGE_LISTS = { broader: "broader", narrower: "narrower", "related-concepts": "related" };
|
|
186
|
+
function namedConcepts(set) {
|
|
187
|
+
const alias = /* @__PURE__ */ new Map();
|
|
188
|
+
for (const block of set.blocks) {
|
|
189
|
+
for (const alt of block.altLabels ?? []) if (!alias.has(fold(alt))) alias.set(fold(alt), block.label);
|
|
190
|
+
}
|
|
191
|
+
const concepts = [];
|
|
192
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
193
|
+
const named = (value, at2, language) => {
|
|
194
|
+
const label = alias.get(fold(value)) ?? value;
|
|
195
|
+
let concept = byKey.get(fold(label));
|
|
196
|
+
if (concept === void 0) {
|
|
197
|
+
concept = { label: label.trim(), from: [], altLabels: [], broader: [], narrower: [], related: [] };
|
|
198
|
+
concepts.push(concept);
|
|
199
|
+
byKey.set(fold(label), concept);
|
|
200
|
+
}
|
|
201
|
+
if (concept.language === void 0 && language !== void 0) concept.language = language;
|
|
202
|
+
if (!concept.from.some((f) => f.file === at2.file && f.line === at2.line)) concept.from.push(at2);
|
|
203
|
+
};
|
|
204
|
+
const at = (file, line) => line === void 0 ? { file } : { file, line };
|
|
205
|
+
for (const reference of set.references) {
|
|
206
|
+
named(reference.label, at(reference.file, reference.line), reference.language);
|
|
207
|
+
}
|
|
208
|
+
for (const block of set.blocks) {
|
|
209
|
+
for (const edge of block.edges) named(edge.value, at(block.file, edge.line ?? block.line), block.language);
|
|
210
|
+
}
|
|
211
|
+
for (const block of set.blocks) {
|
|
212
|
+
const concept = byKey.get(fold(block.label));
|
|
213
|
+
if (concept !== void 0) enrich(concept, block);
|
|
214
|
+
}
|
|
215
|
+
return concepts;
|
|
216
|
+
}
|
|
217
|
+
function enrich(concept, block) {
|
|
218
|
+
for (const alt of block.altLabels ?? []) if (fold(alt) !== fold(concept.label)) addUnique(concept.altLabels, alt);
|
|
219
|
+
for (const edge of block.edges) addUnique(concept[EDGE_LISTS[edge.field]], edge.value);
|
|
220
|
+
if (concept.definition === void 0 && block.definition !== void 0) concept.definition = block.definition;
|
|
221
|
+
}
|
|
222
|
+
function planFromMetadata(set) {
|
|
223
|
+
const index = termIndex(set.terms);
|
|
224
|
+
const create = namedConcepts(set).filter((concept) => !index.has(fold(concept.label)));
|
|
225
|
+
const carried2 = /* @__PURE__ */ new Map();
|
|
226
|
+
for (const block of set.blocks) {
|
|
227
|
+
const term = index.get(fold(block.label));
|
|
228
|
+
if (term !== void 0 && block.definition !== void 0 && !carried2.has(term)) carried2.set(term, block.definition);
|
|
229
|
+
}
|
|
230
|
+
const missing = set.terms.filter((t) => t.record.definition === void 0 && t.record.see === void 0).map((term) => {
|
|
231
|
+
const definition = carried2.get(term);
|
|
232
|
+
return definition === void 0 ? { term } : { term, carried: definition };
|
|
233
|
+
});
|
|
234
|
+
return { create, missing };
|
|
235
|
+
}
|
|
236
|
+
function sharedTermDirectory(terms) {
|
|
237
|
+
const dirs = new Set(
|
|
238
|
+
terms.filter((t) => t.location.construct === "page" && t.location.path !== void 0).map((t) => dirname(t.location.path ?? ""))
|
|
239
|
+
);
|
|
240
|
+
return dirs.size === 1 ? [...dirs][0] : void 0;
|
|
241
|
+
}
|
|
242
|
+
var FILL_PAGE_FORMATS = {
|
|
243
|
+
".md": "markdown",
|
|
244
|
+
".mdx": "mdx",
|
|
245
|
+
".adoc": "asciidoc",
|
|
246
|
+
".rst": "rst",
|
|
247
|
+
".html": "html",
|
|
248
|
+
".dita": "dita"
|
|
249
|
+
};
|
|
250
|
+
function mostCommon(extensions) {
|
|
251
|
+
const counts = /* @__PURE__ */ new Map();
|
|
252
|
+
for (const ext of extensions) if (ext in FILL_PAGE_FORMATS) counts.set(ext, (counts.get(ext) ?? 0) + 1);
|
|
253
|
+
let best;
|
|
254
|
+
for (const [ext, n] of counts) if (best === void 0 || n > (counts.get(best) ?? 0)) best = ext;
|
|
255
|
+
return best;
|
|
256
|
+
}
|
|
257
|
+
function pageExtension(terms, dir, pages) {
|
|
258
|
+
const inDir = terms.filter((t) => t.location.construct === "page" && t.location.path !== void 0).filter((t) => dirname(t.location.path ?? "") === dir).map((t) => extname(t.location.path ?? "").toLowerCase());
|
|
259
|
+
return mostCommon(inDir) ?? mostCommon(pages.map((p) => extname(p).toLowerCase())) ?? ".md";
|
|
260
|
+
}
|
|
261
|
+
function mergeFound(found) {
|
|
262
|
+
const out = [];
|
|
263
|
+
const byKey = /* @__PURE__ */ new Map();
|
|
264
|
+
for (const f of found) {
|
|
265
|
+
let c = byKey.get(fold(f.label));
|
|
266
|
+
if (c === void 0) {
|
|
267
|
+
c = { label: f.label.trim(), altLabels: [], from: [] };
|
|
268
|
+
out.push(c);
|
|
269
|
+
byKey.set(fold(f.label), c);
|
|
270
|
+
}
|
|
271
|
+
for (const alt of f.altLabels ?? []) if (fold(alt) !== fold(c.label)) addUnique(c.altLabels, alt);
|
|
272
|
+
if (c.language === void 0 && f.language !== void 0) c.language = f.language;
|
|
273
|
+
if (!c.from.some((at) => at.file === f.file)) c.from.push(f.line === void 0 ? { file: f.file } : { file: f.file, line: f.line });
|
|
274
|
+
if (f.confidence !== void 0 && (c.confidence === void 0 || f.confidence > c.confidence)) {
|
|
275
|
+
c.confidence = f.confidence;
|
|
276
|
+
if (f.definition !== void 0) c.definition = f.definition;
|
|
277
|
+
} else if (c.definition === void 0 && f.definition !== void 0) {
|
|
278
|
+
c.definition = f.definition;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
return out;
|
|
282
|
+
}
|
|
283
|
+
function newCandidates(candidates, known, minPages) {
|
|
284
|
+
return candidates.filter(
|
|
285
|
+
(c) => c.from.length >= minPages && !known.has(fold(c.label)) && !c.altLabels.some((a) => known.has(fold(a)))
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
128
289
|
// src/term/core/writers/documents.ts
|
|
129
290
|
import { join } from "node:path";
|
|
130
291
|
|
|
@@ -515,92 +676,179 @@ var jsonWriter = {
|
|
|
515
676
|
};
|
|
516
677
|
|
|
517
678
|
// src/term/core/writers/skos.ts
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
"narrower",
|
|
525
|
-
"related-terms",
|
|
526
|
-
"scope-note"
|
|
527
|
-
];
|
|
528
|
-
var CONTEXT = {
|
|
529
|
-
skos: "http://www.w3.org/2004/02/skos/core#",
|
|
679
|
+
import { DataFactory, Writer } from "n3";
|
|
680
|
+
var HOLDS2 = SKOS_PROPERTIES.map((p) => p.field);
|
|
681
|
+
var REDIRECT_HOLDS = ["label", "see"];
|
|
682
|
+
var RDF_TYPE = "http://www.w3.org/1999/02/22-rdf-syntax-ns#type";
|
|
683
|
+
var PREFIXES = {
|
|
684
|
+
skos: SKOS,
|
|
530
685
|
dcterms: "http://purl.org/dc/terms/"
|
|
531
686
|
};
|
|
532
687
|
var SCHEME_ID = "";
|
|
533
|
-
|
|
534
|
-
|
|
688
|
+
var DESCRIPTION = "Generated by manni term write.";
|
|
689
|
+
var SINGLE = /* @__PURE__ */ new Set([
|
|
690
|
+
"skos:inScheme",
|
|
691
|
+
"skos:topConceptOf",
|
|
692
|
+
"skos:prefLabel",
|
|
693
|
+
"skos:definition",
|
|
694
|
+
"skos:scopeNote",
|
|
695
|
+
"skos:notation",
|
|
696
|
+
"dcterms:description"
|
|
697
|
+
]);
|
|
698
|
+
function literal(term, text) {
|
|
699
|
+
return term.language === void 0 ? { text } : { text, language: term.language };
|
|
535
700
|
}
|
|
536
701
|
function resolve(terms, self, value) {
|
|
537
702
|
const wanted = value.toLowerCase();
|
|
538
|
-
const others = terms.filter((t) => t !== self);
|
|
703
|
+
const others = terms.filter((t) => t.id !== self);
|
|
539
704
|
return others.find((t) => t.record.label.toLowerCase() === wanted) ?? others.find((t) => t.id.toLowerCase() === wanted);
|
|
540
705
|
}
|
|
541
|
-
function
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
const target = resolve(terms, self, value);
|
|
545
|
-
if (target !== void 0 && !ids.includes(target.id)) ids.push(target.id);
|
|
546
|
-
}
|
|
547
|
-
return ids.map((id) => ({ "@id": `#${id}` }));
|
|
706
|
+
function sameValue(a, b) {
|
|
707
|
+
if ("iri" in a) return "iri" in b && a.iri === b.iri;
|
|
708
|
+
return !("iri" in b) && a.text === b.text && a.language === b.language;
|
|
548
709
|
}
|
|
549
|
-
function
|
|
550
|
-
|
|
551
|
-
const node = {
|
|
552
|
-
"@id": `#${term.id}`,
|
|
553
|
-
"@type": "skos:Concept",
|
|
554
|
-
"skos:inScheme": { "@id": SCHEME_ID },
|
|
555
|
-
"skos:prefLabel": literal(term, record.label)
|
|
556
|
-
};
|
|
557
|
-
if (record["alt-labels"] !== void 0) node["skos:altLabel"] = record["alt-labels"].map((v) => literal(term, v));
|
|
558
|
-
if (record["hidden-labels"] !== void 0) {
|
|
559
|
-
node["skos:hiddenLabel"] = record["hidden-labels"].map((v) => literal(term, v));
|
|
560
|
-
}
|
|
561
|
-
if (record.definition !== void 0) node["skos:definition"] = literal(term, record.definition);
|
|
562
|
-
if (record["scope-note"] !== void 0) node["skos:scopeNote"] = literal(term, record["scope-note"]);
|
|
563
|
-
const relations = [
|
|
564
|
-
["skos:broader", record.broader],
|
|
565
|
-
["skos:narrower", record.narrower],
|
|
566
|
-
["skos:related", record["related-terms"]]
|
|
567
|
-
];
|
|
568
|
-
for (const [key, values] of relations) {
|
|
569
|
-
const refs = references(terms, term, values);
|
|
570
|
-
if (refs.length > 0) node[key] = refs;
|
|
571
|
-
}
|
|
572
|
-
return node;
|
|
710
|
+
function pushUnique(values, value) {
|
|
711
|
+
if (!values.some((v) => sameValue(v, value))) values.push(value);
|
|
573
712
|
}
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
713
|
+
function graphOf(terms) {
|
|
714
|
+
const redirects = /* @__PURE__ */ new Map();
|
|
715
|
+
for (const term of terms) {
|
|
716
|
+
const target = term.record.see === void 0 ? void 0 : resolve(terms, term.id, term.record.see);
|
|
717
|
+
if (target !== void 0) redirects.set(term, target.id);
|
|
718
|
+
}
|
|
719
|
+
const concepts = terms.filter((t) => !redirects.has(t));
|
|
720
|
+
const conflicts = [];
|
|
721
|
+
const nodes = [];
|
|
722
|
+
const tops = [];
|
|
723
|
+
for (const group of conceptGroups(concepts)) {
|
|
724
|
+
const [first] = group;
|
|
725
|
+
if (first === void 0) continue;
|
|
726
|
+
const { id } = first;
|
|
727
|
+
const values = /* @__PURE__ */ new Map();
|
|
728
|
+
const add = (property, value) => {
|
|
729
|
+
const list = values.get(property) ?? [];
|
|
730
|
+
pushUnique(list, value);
|
|
731
|
+
values.set(property, list);
|
|
590
732
|
};
|
|
591
|
-
const
|
|
733
|
+
for (const { property, field, kind } of SKOS_PROPERTIES) {
|
|
734
|
+
const name = `skos:${property}`;
|
|
735
|
+
if (kind === "code") {
|
|
736
|
+
const merged = mergeFirst(id, group.map((t) => ({ [field]: t.record[field] })));
|
|
737
|
+
conflicts.push(...merged.conflicts);
|
|
738
|
+
const text = merged.merged[field];
|
|
739
|
+
if (typeof text === "string") add(name, { text });
|
|
740
|
+
continue;
|
|
741
|
+
}
|
|
742
|
+
for (const term of group) {
|
|
743
|
+
const raw = term.record[field];
|
|
744
|
+
const list = raw === void 0 ? [] : typeof raw === "string" ? [raw] : raw;
|
|
745
|
+
for (const value of list) {
|
|
746
|
+
if (kind === "iris") add(name, { iri: value });
|
|
747
|
+
else if (kind === "concepts") {
|
|
748
|
+
const target = resolve(terms, id, value);
|
|
749
|
+
if (target !== void 0) add(name, { iri: `#${target.id}` });
|
|
750
|
+
} else add(name, literal(term, value));
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
if (property === "altLabel") {
|
|
754
|
+
for (const [redirect, target] of redirects) if (target === id) add(name, literal(redirect, redirect.record.label));
|
|
755
|
+
}
|
|
756
|
+
}
|
|
757
|
+
const top = !values.has("skos:broader");
|
|
758
|
+
if (top) tops.push({ iri: `#${id}` });
|
|
759
|
+
nodes.push({
|
|
760
|
+
id: `#${id}`,
|
|
761
|
+
type: "skos:Concept",
|
|
762
|
+
properties: [
|
|
763
|
+
["skos:inScheme", [{ iri: SCHEME_ID }]],
|
|
764
|
+
...top ? [["skos:topConceptOf", [{ iri: SCHEME_ID }]]] : [],
|
|
765
|
+
...SKOS_PROPERTIES.flatMap(({ property }) => {
|
|
766
|
+
const list = values.get(`skos:${property}`);
|
|
767
|
+
return list === void 0 ? [] : [[`skos:${property}`, list]];
|
|
768
|
+
})
|
|
769
|
+
]
|
|
770
|
+
});
|
|
771
|
+
}
|
|
772
|
+
const scheme = {
|
|
773
|
+
id: SCHEME_ID,
|
|
774
|
+
type: "skos:ConceptScheme",
|
|
775
|
+
properties: [["dcterms:description", [{ text: DESCRIPTION }]], ...tops.length === 0 ? [] : [["skos:hasTopConcept", tops]]]
|
|
776
|
+
};
|
|
777
|
+
const dropped = terms.flatMap((t) => droppedFields([t], redirects.has(t) ? REDIRECT_HOLDS : HOLDS2));
|
|
778
|
+
return { nodes: [scheme, ...nodes], dropped, conflicts };
|
|
779
|
+
}
|
|
780
|
+
function jsonValue(value) {
|
|
781
|
+
if ("iri" in value) return { "@id": value.iri };
|
|
782
|
+
return value.language === void 0 ? value.text : { "@value": value.text, "@language": value.language };
|
|
783
|
+
}
|
|
784
|
+
function jsonLd(nodes) {
|
|
785
|
+
const graph = nodes.map((node) => {
|
|
786
|
+
const out = { "@id": node.id, "@type": node.type };
|
|
787
|
+
for (const [property, values] of node.properties) {
|
|
788
|
+
const [only] = values;
|
|
789
|
+
out[property] = SINGLE.has(property) && values.length === 1 && only !== void 0 ? jsonValue(only) : values.map(jsonValue);
|
|
790
|
+
}
|
|
791
|
+
return out;
|
|
792
|
+
});
|
|
793
|
+
return `${JSON.stringify({ "@context": PREFIXES, "@graph": graph }, null, 2)}
|
|
592
794
|
`;
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
795
|
+
}
|
|
796
|
+
function expand(name) {
|
|
797
|
+
const [prefix = "", local = ""] = name.split(":");
|
|
798
|
+
if (!Object.hasOwn(PREFIXES, prefix)) throw new Error(`skos writer: unknown prefix "${prefix}" in ${name}`);
|
|
799
|
+
return `${PREFIXES[prefix]}${local}`;
|
|
800
|
+
}
|
|
801
|
+
function turtle(nodes) {
|
|
802
|
+
const iri = (value) => DataFactory.namedNode(value);
|
|
803
|
+
const writer = new Writer({ prefixes: PREFIXES });
|
|
804
|
+
for (const node of nodes) {
|
|
805
|
+
const subject = iri(node.id);
|
|
806
|
+
writer.addQuad(DataFactory.quad(subject, iri(RDF_TYPE), iri(expand(node.type))));
|
|
807
|
+
for (const [property, values] of node.properties) {
|
|
808
|
+
for (const value of values) {
|
|
809
|
+
const object = "iri" in value ? iri(value.iri) : DataFactory.literal(value.text, value.language);
|
|
810
|
+
writer.addQuad(DataFactory.quad(subject, iri(expand(property)), object));
|
|
811
|
+
}
|
|
812
|
+
}
|
|
599
813
|
}
|
|
600
|
-
|
|
814
|
+
let content = "";
|
|
815
|
+
writer.end((_error, result) => {
|
|
816
|
+
content = result;
|
|
817
|
+
});
|
|
818
|
+
return content;
|
|
819
|
+
}
|
|
820
|
+
function skosWriterFor(format, serialize) {
|
|
821
|
+
return {
|
|
822
|
+
format,
|
|
823
|
+
shapes: ["file"],
|
|
824
|
+
holds: (_shape) => HOLDS2,
|
|
825
|
+
render(terms, target) {
|
|
826
|
+
requireShape(format, target, "file");
|
|
827
|
+
const { nodes, dropped, conflicts } = graphOf(terms);
|
|
828
|
+
return {
|
|
829
|
+
files: [{ path: target.path, content: serialize(nodes) }],
|
|
830
|
+
removals: [],
|
|
831
|
+
dropped,
|
|
832
|
+
skipped: [],
|
|
833
|
+
...conflicts.length === 0 ? {} : { conflicts }
|
|
834
|
+
};
|
|
835
|
+
}
|
|
836
|
+
};
|
|
837
|
+
}
|
|
838
|
+
var skosWriter = skosWriterFor("skos", jsonLd);
|
|
839
|
+
var skosTtlWriter = skosWriterFor("skos-ttl", turtle);
|
|
601
840
|
|
|
602
841
|
// src/term/core/writers/tbx.ts
|
|
603
|
-
var NOT_HELD = [
|
|
842
|
+
var NOT_HELD = [
|
|
843
|
+
"abstract",
|
|
844
|
+
"broader",
|
|
845
|
+
"narrower",
|
|
846
|
+
"related-terms",
|
|
847
|
+
"see",
|
|
848
|
+
"scope-note",
|
|
849
|
+
"notation",
|
|
850
|
+
...TERM_MATCH_FIELDS
|
|
851
|
+
];
|
|
604
852
|
var HOLDS3 = TERM_FIELDS.filter((field) => !NOT_HELD.includes(field));
|
|
605
853
|
var LINGUIST_FIELDS = ["register", "reading", "reading-note", "grammatical-number", "transfer-comments"];
|
|
606
854
|
var ENTRY_INDENT = " ";
|
|
@@ -902,11 +1150,514 @@ var valeWriter = {
|
|
|
902
1150
|
};
|
|
903
1151
|
|
|
904
1152
|
// src/term/core/writers/interchange.ts
|
|
905
|
-
var INTERCHANGE_WRITERS = [tbxWriter, tbx3Writer, skosWriter, csvWriter, jsonWriter, valeWriter];
|
|
1153
|
+
var INTERCHANGE_WRITERS = [tbxWriter, tbx3Writer, skosWriter, skosTtlWriter, csvWriter, jsonWriter, valeWriter];
|
|
906
1154
|
|
|
907
1155
|
// src/term/core/writers/index.ts
|
|
908
1156
|
var TERM_WRITERS = [...DOCUMENT_WRITERS, ...INTERCHANGE_WRITERS];
|
|
909
1157
|
|
|
1158
|
+
// src/term/commands/fill.ts
|
|
1159
|
+
var FILL_FORMATS = ["pretty", "json"];
|
|
1160
|
+
var TURN_BUDGET_REASON = "turn budget";
|
|
1161
|
+
var PROMPT_VERSION = 1;
|
|
1162
|
+
var META_PROVENANCE_KEY = "meta-provenance";
|
|
1163
|
+
var DEFINITION_SYSTEM = [
|
|
1164
|
+
"You write glossary definitions for a documentation set's termbase.",
|
|
1165
|
+
"Define the term in one sentence, as the pages quoted use it.",
|
|
1166
|
+
"Give your confidence, from 0 to 1, that the definition is right for these pages.",
|
|
1167
|
+
"When the context is too thin to be sure, say so with a low confidence rather than guessing."
|
|
1168
|
+
].join(" ");
|
|
1169
|
+
var DEFINITION_SCHEMA = {
|
|
1170
|
+
type: "object",
|
|
1171
|
+
additionalProperties: false,
|
|
1172
|
+
required: ["definition", "confidence"],
|
|
1173
|
+
properties: { definition: { type: "string" }, confidence: { type: "number" } }
|
|
1174
|
+
};
|
|
1175
|
+
var CRAWL_SYSTEM = [
|
|
1176
|
+
"You find the domain terms a documentation page uses: product concepts, technical terms and jargon a glossary should define.",
|
|
1177
|
+
"Leave out everyday words, people, and code identifiers.",
|
|
1178
|
+
"For each term give its label in singular form, any synonyms the page uses, a one-sentence definition from the page's context,",
|
|
1179
|
+
"and your confidence, from 0 to 1, that it belongs in a glossary and that the definition is right."
|
|
1180
|
+
].join(" ");
|
|
1181
|
+
var CRAWL_SCHEMA = {
|
|
1182
|
+
type: "object",
|
|
1183
|
+
additionalProperties: false,
|
|
1184
|
+
required: ["terms"],
|
|
1185
|
+
properties: {
|
|
1186
|
+
terms: {
|
|
1187
|
+
type: "array",
|
|
1188
|
+
items: {
|
|
1189
|
+
type: "object",
|
|
1190
|
+
additionalProperties: false,
|
|
1191
|
+
required: ["label", "alt-labels", "definition", "confidence"],
|
|
1192
|
+
properties: {
|
|
1193
|
+
label: { type: "string" },
|
|
1194
|
+
"alt-labels": { type: "array", items: { type: "string" } },
|
|
1195
|
+
definition: { type: "string" },
|
|
1196
|
+
confidence: { type: "number" }
|
|
1197
|
+
}
|
|
1198
|
+
}
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
};
|
|
1202
|
+
var validateDefinition = validatorFor(DEFINITION_SCHEMA);
|
|
1203
|
+
var validateCrawl = validatorFor(CRAWL_SCHEMA);
|
|
1204
|
+
function score(value) {
|
|
1205
|
+
return typeof value === "number" && value >= 0 && value <= 1 ? Math.round(value * 100) / 100 : 0;
|
|
1206
|
+
}
|
|
1207
|
+
function nonEmpty(value) {
|
|
1208
|
+
return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
|
|
1209
|
+
}
|
|
1210
|
+
function strings(value) {
|
|
1211
|
+
return Array.isArray(value) ? value.map(nonEmpty).filter((v) => v !== void 0) : [];
|
|
1212
|
+
}
|
|
1213
|
+
function keywordsOf(value) {
|
|
1214
|
+
return typeof value === "string" ? strings([value]) : strings(value);
|
|
1215
|
+
}
|
|
1216
|
+
function wholeWord(label) {
|
|
1217
|
+
const escaped = label.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
1218
|
+
return new RegExp(`(?<![\\p{L}\\p{N}])${escaped}(?![\\p{L}\\p{N}])`, "iu");
|
|
1219
|
+
}
|
|
1220
|
+
function lineOf(content, label) {
|
|
1221
|
+
const match = wholeWord(label).exec(content);
|
|
1222
|
+
return match === null ? void 0 : content.slice(0, match.index).split("\n").length;
|
|
1223
|
+
}
|
|
1224
|
+
function fromList(from, cwd) {
|
|
1225
|
+
return from.map((at) => {
|
|
1226
|
+
const file = displayPath(at.file, cwd);
|
|
1227
|
+
return at.line === void 0 ? file : `${file}:${String(at.line)}`;
|
|
1228
|
+
});
|
|
1229
|
+
}
|
|
1230
|
+
var toTermError = (message) => new TermError(message);
|
|
1231
|
+
async function resolveModel(opts, run) {
|
|
1232
|
+
const injected = (provider) => ({
|
|
1233
|
+
provider,
|
|
1234
|
+
identity: { provider: provider.provider(), model: provider.modelName() }
|
|
1235
|
+
});
|
|
1236
|
+
const offline = opts.offline === true;
|
|
1237
|
+
if (opts.providerInstance !== void 0 && !offline) return injected(opts.providerInstance);
|
|
1238
|
+
const flags = {
|
|
1239
|
+
...opts.provider === void 0 ? {} : { provider: opts.provider },
|
|
1240
|
+
...opts.model === void 0 ? {} : { model: opts.model },
|
|
1241
|
+
...opts.local === true ? { local: true } : {},
|
|
1242
|
+
...offline ? { offline: true } : {}
|
|
1243
|
+
};
|
|
1244
|
+
assertLocalFlag(flags, toTermError);
|
|
1245
|
+
const family = run.configFile?.providers ?? {};
|
|
1246
|
+
const selection = selectProvider(flags, [
|
|
1247
|
+
{
|
|
1248
|
+
...run.config?.provider === void 0 ? {} : { provider: run.config.provider },
|
|
1249
|
+
...run.config?.model === void 0 ? {} : { model: run.config.model },
|
|
1250
|
+
origin: "term.provider"
|
|
1251
|
+
},
|
|
1252
|
+
{
|
|
1253
|
+
...family.provider === void 0 ? {} : { provider: family.provider },
|
|
1254
|
+
...family.model === void 0 ? {} : { model: family.model },
|
|
1255
|
+
origin: "providers.provider"
|
|
1256
|
+
}
|
|
1257
|
+
]);
|
|
1258
|
+
const { provider: name, model: chosen } = selection;
|
|
1259
|
+
assertKnownProvider(name, toTermError);
|
|
1260
|
+
assertModelHasProvider(name, chosen, "term.provider", toTermError);
|
|
1261
|
+
const named = [flags.provider, flags.model, run.config?.provider, run.config?.model, family.provider, family.model].some(
|
|
1262
|
+
(value) => value !== void 0 && value !== DEFAULT_PROVIDER
|
|
1263
|
+
);
|
|
1264
|
+
const notice2 = localNotice(selection, flags);
|
|
1265
|
+
if (notice2 !== void 0) opts.onNotice?.(notice2);
|
|
1266
|
+
try {
|
|
1267
|
+
const spec = providerSpecFor(family, { provider: name, model: chosen ?? null });
|
|
1268
|
+
const identity = offline ? await offlineIdentity(spec, toTermError) : await resolveIdentity(spec, toTermError);
|
|
1269
|
+
if (identity === void 0) return void 0;
|
|
1270
|
+
if (opts.providerInstance !== void 0) return injected(opts.providerInstance);
|
|
1271
|
+
return { provider: makeInferenceProvider(providerSpecFor(family, identity)), identity };
|
|
1272
|
+
} catch (error) {
|
|
1273
|
+
if (named) opts.onNotice?.(`the configured provider "${name}" could not run: ${errorMessage(error)}`);
|
|
1274
|
+
return void 0;
|
|
1275
|
+
}
|
|
1276
|
+
}
|
|
1277
|
+
async function runFill(opts) {
|
|
1278
|
+
const cwd = resolve2(opts.cwd ?? process.cwd());
|
|
1279
|
+
const run = await resolveTermRun({
|
|
1280
|
+
cwd,
|
|
1281
|
+
inputs: opts.inputs,
|
|
1282
|
+
...opts.configPath === void 0 ? {} : { configPath: opts.configPath },
|
|
1283
|
+
...opts.collection === void 0 ? {} : { collection: opts.collection }
|
|
1284
|
+
});
|
|
1285
|
+
const pages = [];
|
|
1286
|
+
const onPage = (input) => {
|
|
1287
|
+
const language = input.metadata["language"];
|
|
1288
|
+
const keywordsLine = input.lineFor("/keywords");
|
|
1289
|
+
pages.push({
|
|
1290
|
+
file: input.file,
|
|
1291
|
+
...input.path === void 0 ? {} : { path: input.path },
|
|
1292
|
+
content: input.content,
|
|
1293
|
+
metadata: input.metadata,
|
|
1294
|
+
...typeof language === "string" && language !== "" ? { language } : {},
|
|
1295
|
+
...keywordsLine === void 0 ? {} : { keywordsLine }
|
|
1296
|
+
});
|
|
1297
|
+
};
|
|
1298
|
+
const set = await loadSet(run, { ...opts, cwd, allowEmpty: true, onPage });
|
|
1299
|
+
const fillConfig = run.config?.fill ?? {};
|
|
1300
|
+
const configDir = run.configDir ?? cwd;
|
|
1301
|
+
const threshold = opts.confidence ?? fillConfig.confidenceThreshold ?? DEFAULT_FILL_CONFIDENCE;
|
|
1302
|
+
const maxTurns = opts.maxTurns ?? fillConfig.maxTurns ?? null;
|
|
1303
|
+
const minPages = fillConfig.crawl?.minPages ?? DEFAULT_CRAWL_MIN_PAGES;
|
|
1304
|
+
const chunkChars = opts.chunkChars ?? DEFAULT_CHUNK_CHARS;
|
|
1305
|
+
const crawl = opts.crawl === true;
|
|
1306
|
+
const dryRun = opts.dryRun === true;
|
|
1307
|
+
const plan = planFromMetadata(set);
|
|
1308
|
+
const needsDir = crawl || plan.create.length > 0;
|
|
1309
|
+
const outDir = !needsDir ? void 0 : opts.out !== void 0 ? resolve2(cwd, opts.out) : fillConfig.out !== void 0 ? resolve2(configDir, fillConfig.out) : sharedTermDirectory(set.terms);
|
|
1310
|
+
if (needsDir && outDir === void 0) {
|
|
1311
|
+
throw new TermError("new term pages need a directory; pass -o or set term.fill.out.");
|
|
1312
|
+
}
|
|
1313
|
+
const ext = outDir === void 0 ? ".md" : pageExtension(set.terms, outDir, pages.map((p) => p.file));
|
|
1314
|
+
const format = FILL_PAGE_FORMATS[ext] ?? "markdown";
|
|
1315
|
+
const wantsModel = crawl || plan.create.some((c) => c.definition === void 0) || plan.missing.some((m) => m.carried === void 0);
|
|
1316
|
+
let model;
|
|
1317
|
+
if (wantsModel) {
|
|
1318
|
+
model = await resolveModel(opts, run);
|
|
1319
|
+
if (model === void 0) {
|
|
1320
|
+
if (crawl) {
|
|
1321
|
+
throw new TermError(
|
|
1322
|
+
opts.offline === true ? "--crawl needs a model, and none is available offline; drop --offline, or download a local model first." : "--crawl needs a model, and no provider is configured; pass --provider or set providers:."
|
|
1323
|
+
);
|
|
1324
|
+
}
|
|
1325
|
+
warn(
|
|
1326
|
+
opts.offline === true ? noOfflineModel("new terms have no definition") : "no model provider is configured, so new terms have no definition; pass --provider or --local."
|
|
1327
|
+
);
|
|
1328
|
+
}
|
|
1329
|
+
}
|
|
1330
|
+
const modelName = model === void 0 ? void 0 : `${model.identity.provider}/${model.identity.model}`;
|
|
1331
|
+
const cache = new JsonCache(
|
|
1332
|
+
resolve2(configDir, fillConfig.cacheDir ?? DEFAULT_FILL_CACHE_DIR),
|
|
1333
|
+
opts.noCache !== true,
|
|
1334
|
+
"manni"
|
|
1335
|
+
);
|
|
1336
|
+
let turns = 0;
|
|
1337
|
+
const ask = async (m, kind, system, user, schema, validate) => {
|
|
1338
|
+
const key = buildCacheKey([m.identity.provider, m.identity.model, `v${String(PROMPT_VERSION)}`, kind, sha256(user)]);
|
|
1339
|
+
const cached = cache.get(key);
|
|
1340
|
+
if (cached !== void 0 && validate(cached)) return cached;
|
|
1341
|
+
if (maxTurns !== null && turns >= maxTurns) return void 0;
|
|
1342
|
+
turns++;
|
|
1343
|
+
const answer = await completeValidatedJSON({ provider: m.provider, system, user, schema, validate });
|
|
1344
|
+
if (answer.result === void 0) throw new TermError(answer.error ?? "the model returned no answer.");
|
|
1345
|
+
cache.set(key, answer.result);
|
|
1346
|
+
return answer.result;
|
|
1347
|
+
};
|
|
1348
|
+
const pageByFile = new Map(pages.map((p) => [p.file, p]));
|
|
1349
|
+
const definitionPrompt = (label, language, record, from) => {
|
|
1350
|
+
const lines = [`Term: ${label}`];
|
|
1351
|
+
if (language !== void 0) lines.push(`Language: ${language}`);
|
|
1352
|
+
const lists = [
|
|
1353
|
+
["Also called", record["alt-labels"]],
|
|
1354
|
+
["Broader", record.broader],
|
|
1355
|
+
["Narrower", record.narrower],
|
|
1356
|
+
["Related", record["related-terms"]]
|
|
1357
|
+
];
|
|
1358
|
+
for (const [name, values] of lists) if (values !== void 0 && values.length > 0) lines.push(`${name}: ${values.join(", ")}`);
|
|
1359
|
+
const files = [...new Set(from.map((f) => f.file))].slice(0, 3);
|
|
1360
|
+
for (const file of files) {
|
|
1361
|
+
const page = pageByFile.get(file);
|
|
1362
|
+
if (page === void 0) continue;
|
|
1363
|
+
lines.push("", `Page ${file}`);
|
|
1364
|
+
for (const key of ["title", "description"]) {
|
|
1365
|
+
const value = nonEmpty(page.metadata[key]);
|
|
1366
|
+
if (value !== void 0) lines.push(`${key}: ${value}`);
|
|
1367
|
+
}
|
|
1368
|
+
const word = wholeWord(label);
|
|
1369
|
+
const uses = page.content.split("\n").filter((line) => word.test(line)).slice(0, 3);
|
|
1370
|
+
for (const use of uses) lines.push(`> ${use.trim()}`);
|
|
1371
|
+
}
|
|
1372
|
+
return lines.join("\n");
|
|
1373
|
+
};
|
|
1374
|
+
const draft = async (label, language, record, from) => {
|
|
1375
|
+
if (model === void 0) return void 0;
|
|
1376
|
+
let answer;
|
|
1377
|
+
try {
|
|
1378
|
+
answer = await ask(model, "definition", DEFINITION_SYSTEM, definitionPrompt(label, language, record, from), DEFINITION_SCHEMA, validateDefinition);
|
|
1379
|
+
} catch (error) {
|
|
1380
|
+
return { skip: `model error: ${errorMessage(error)}` };
|
|
1381
|
+
}
|
|
1382
|
+
if (answer === void 0) return { skip: TURN_BUDGET_REASON };
|
|
1383
|
+
const definition = nonEmpty(answer["definition"]);
|
|
1384
|
+
const confidence = score(answer["confidence"]);
|
|
1385
|
+
if (definition === void 0) return { skip: "the model gave no definition" };
|
|
1386
|
+
return { status: confidence >= threshold ? "drafted" : "below-threshold", definition, confidence };
|
|
1387
|
+
};
|
|
1388
|
+
const entries2 = [];
|
|
1389
|
+
const writes = [];
|
|
1390
|
+
const planned = /* @__PURE__ */ new Set();
|
|
1391
|
+
const known = new Set(termIndex(set.terms).keys());
|
|
1392
|
+
const render = (term, provenance) => {
|
|
1393
|
+
const writer = TERM_WRITERS.find((w) => w.format === format);
|
|
1394
|
+
const target = { path: outDir ?? cwd, shape: "directory" };
|
|
1395
|
+
const content = writer?.render([term], target, { existing: /* @__PURE__ */ new Map() }).files[0]?.content;
|
|
1396
|
+
if (content === void 0) throw new TermError(`manni cannot write a ${format} term page.`);
|
|
1397
|
+
if (provenance === void 0 || model === void 0) return content;
|
|
1398
|
+
const merged = mergeMetaProvenance(
|
|
1399
|
+
void 0,
|
|
1400
|
+
model.identity.model,
|
|
1401
|
+
"fields",
|
|
1402
|
+
provenance.fields.map((name) => ({ name, confidence: provenance.confidence }))
|
|
1403
|
+
);
|
|
1404
|
+
const extractor = extractorForExtension(ext);
|
|
1405
|
+
if (merged === void 0 || extractor?.apply === void 0) return content;
|
|
1406
|
+
return extractor.apply(content, { [META_PROVENANCE_KEY]: merged.list }, { filePath: join3(target.path, `x${ext}`) });
|
|
1407
|
+
};
|
|
1408
|
+
const create = async (concept, source, definition) => {
|
|
1409
|
+
const id = slugOf(concept.label);
|
|
1410
|
+
const path = join3(outDir ?? cwd, `${id}${ext}`);
|
|
1411
|
+
const base = {
|
|
1412
|
+
file: displayPath(path, cwd),
|
|
1413
|
+
id,
|
|
1414
|
+
label: concept.label,
|
|
1415
|
+
...concept.language === void 0 ? {} : { language: concept.language },
|
|
1416
|
+
source,
|
|
1417
|
+
from: fromList(concept.from, cwd)
|
|
1418
|
+
};
|
|
1419
|
+
if (planned.has(path) || existsSync(path)) {
|
|
1420
|
+
entries2.push({ action: "exists", ...base, definition: { status: "missing" } });
|
|
1421
|
+
return;
|
|
1422
|
+
}
|
|
1423
|
+
const record = { label: concept.label };
|
|
1424
|
+
const lists = [
|
|
1425
|
+
["alt-labels", concept.altLabels],
|
|
1426
|
+
["broader", concept.broader],
|
|
1427
|
+
["narrower", concept.narrower],
|
|
1428
|
+
["related-terms", concept.related]
|
|
1429
|
+
];
|
|
1430
|
+
for (const [field, values] of lists) if (values !== void 0 && values.length > 0) record[field] = values;
|
|
1431
|
+
let status = "missing";
|
|
1432
|
+
let confidence;
|
|
1433
|
+
let fields;
|
|
1434
|
+
if (definition.carried !== void 0) {
|
|
1435
|
+
record.definition = definition.carried;
|
|
1436
|
+
status = "carried";
|
|
1437
|
+
} else {
|
|
1438
|
+
const got = definition.drafted ?? await draft(concept.label, concept.language, record, concept.from);
|
|
1439
|
+
if (got !== void 0 && "skip" in got) {
|
|
1440
|
+
entries2.push({ action: "skip", ...base, definition: { status: "missing" }, reason: got.skip });
|
|
1441
|
+
return;
|
|
1442
|
+
}
|
|
1443
|
+
if (got !== void 0) {
|
|
1444
|
+
confidence = got.confidence;
|
|
1445
|
+
const below = "status" in got ? got.status === "below-threshold" : got.confidence < threshold;
|
|
1446
|
+
if (below) {
|
|
1447
|
+
status = "below-threshold";
|
|
1448
|
+
} else {
|
|
1449
|
+
record.definition = got.definition;
|
|
1450
|
+
status = "drafted";
|
|
1451
|
+
fields = definition.fields ?? ["/definition"];
|
|
1452
|
+
}
|
|
1453
|
+
}
|
|
1454
|
+
}
|
|
1455
|
+
const term = {
|
|
1456
|
+
id,
|
|
1457
|
+
record,
|
|
1458
|
+
...concept.language === void 0 ? {} : { language: concept.language },
|
|
1459
|
+
location: { file: base.file, path, construct: "page", line: 1, fieldLines: {} }
|
|
1460
|
+
};
|
|
1461
|
+
planned.add(path);
|
|
1462
|
+
known.add(fold(concept.label));
|
|
1463
|
+
for (const alt of concept.altLabels) known.add(fold(alt));
|
|
1464
|
+
writes.push({ path, content: render(term, fields === void 0 || confidence === void 0 ? void 0 : { fields, confidence }) });
|
|
1465
|
+
entries2.push({
|
|
1466
|
+
action: "create",
|
|
1467
|
+
...base,
|
|
1468
|
+
definition: {
|
|
1469
|
+
status,
|
|
1470
|
+
...confidence === void 0 ? {} : { confidence },
|
|
1471
|
+
...modelName === void 0 || confidence === void 0 ? {} : { model: modelName }
|
|
1472
|
+
}
|
|
1473
|
+
});
|
|
1474
|
+
};
|
|
1475
|
+
for (const concept of plan.create) {
|
|
1476
|
+
await create(concept, "metadata", concept.definition === void 0 ? {} : { carried: concept.definition });
|
|
1477
|
+
}
|
|
1478
|
+
for (const { term, carried: carried2 } of plan.missing) {
|
|
1479
|
+
if (carried2 === void 0 && model === void 0) continue;
|
|
1480
|
+
const path = term.location.path;
|
|
1481
|
+
const base = {
|
|
1482
|
+
file: displayPath(term.location.file, cwd),
|
|
1483
|
+
id: term.id,
|
|
1484
|
+
label: term.record.label,
|
|
1485
|
+
...term.language === void 0 ? {} : { language: term.language },
|
|
1486
|
+
source: "metadata",
|
|
1487
|
+
from: [`${displayPath(term.location.file, cwd)}:${String(term.location.line)}`]
|
|
1488
|
+
};
|
|
1489
|
+
if (term.location.construct !== "page" || path === void 0) {
|
|
1490
|
+
entries2.push({ action: "skip", ...base, definition: { status: "missing" }, reason: "not a term page" });
|
|
1491
|
+
continue;
|
|
1492
|
+
}
|
|
1493
|
+
let definition;
|
|
1494
|
+
let provenance;
|
|
1495
|
+
if (carried2 !== void 0) {
|
|
1496
|
+
definition = carried2;
|
|
1497
|
+
} else {
|
|
1498
|
+
const got = await draft(term.record.label, term.language, term.record, [{ file: term.location.file }]);
|
|
1499
|
+
if (got === void 0) continue;
|
|
1500
|
+
if ("skip" in got) {
|
|
1501
|
+
entries2.push({ action: "skip", ...base, definition: { status: "missing" }, reason: got.skip });
|
|
1502
|
+
continue;
|
|
1503
|
+
}
|
|
1504
|
+
if (got.status === "below-threshold") {
|
|
1505
|
+
entries2.push({
|
|
1506
|
+
action: "skip",
|
|
1507
|
+
...base,
|
|
1508
|
+
definition: { status: "below-threshold", confidence: got.confidence, ...modelName === void 0 ? {} : { model: modelName } }
|
|
1509
|
+
});
|
|
1510
|
+
continue;
|
|
1511
|
+
}
|
|
1512
|
+
definition = got.definition;
|
|
1513
|
+
provenance = { confidence: got.confidence };
|
|
1514
|
+
}
|
|
1515
|
+
writes.push({ path, content: await fillInPlace(path, term.location.file, definition, provenance, model) });
|
|
1516
|
+
entries2.push({
|
|
1517
|
+
action: "fill",
|
|
1518
|
+
...base,
|
|
1519
|
+
definition: provenance === void 0 ? { status: "carried" } : { status: "drafted", confidence: provenance.confidence, ...modelName === void 0 ? {} : { model: modelName } }
|
|
1520
|
+
});
|
|
1521
|
+
}
|
|
1522
|
+
if (crawl && model !== void 0) {
|
|
1523
|
+
const found = [];
|
|
1524
|
+
let spent = false;
|
|
1525
|
+
for (const page of pages) {
|
|
1526
|
+
const type = page.metadata["type"];
|
|
1527
|
+
if (type === "term" || type === "term-set") continue;
|
|
1528
|
+
for (const keyword of keywordsOf(page.metadata["keywords"])) {
|
|
1529
|
+
found.push({
|
|
1530
|
+
file: page.file,
|
|
1531
|
+
label: keyword,
|
|
1532
|
+
...page.keywordsLine === void 0 ? {} : { line: page.keywordsLine },
|
|
1533
|
+
...page.language === void 0 ? {} : { language: page.language }
|
|
1534
|
+
});
|
|
1535
|
+
}
|
|
1536
|
+
if (spent) continue;
|
|
1537
|
+
const chunks = splitBody(page.content, chunkChars);
|
|
1538
|
+
for (const [i, chunk] of chunks.entries()) {
|
|
1539
|
+
const user = `Page ${page.file}${chunks.length > 1 ? ` (part ${String(i + 1)} of ${String(chunks.length)})` : ""}
|
|
1540
|
+
|
|
1541
|
+
${chunk}`;
|
|
1542
|
+
let answer;
|
|
1543
|
+
try {
|
|
1544
|
+
answer = await ask(model, "crawl", CRAWL_SYSTEM, user, CRAWL_SCHEMA, validateCrawl);
|
|
1545
|
+
} catch (error) {
|
|
1546
|
+
opts.onNotice?.(`${page.file}: the model could not read it: ${errorMessage(error)}`);
|
|
1547
|
+
continue;
|
|
1548
|
+
}
|
|
1549
|
+
if (answer === void 0) {
|
|
1550
|
+
spent = true;
|
|
1551
|
+
opts.onNotice?.(`--max-turns reached (${String(maxTurns)}); some pages were not crawled.`);
|
|
1552
|
+
break;
|
|
1553
|
+
}
|
|
1554
|
+
const terms = Array.isArray(answer["terms"]) ? answer["terms"] : [];
|
|
1555
|
+
for (const item of terms) {
|
|
1556
|
+
if (typeof item !== "object" || item === null) continue;
|
|
1557
|
+
const t = item;
|
|
1558
|
+
const label = nonEmpty(t["label"]);
|
|
1559
|
+
if (label === void 0) continue;
|
|
1560
|
+
const definition = nonEmpty(t["definition"]);
|
|
1561
|
+
const line = lineOf(page.content, label);
|
|
1562
|
+
found.push({
|
|
1563
|
+
file: page.file,
|
|
1564
|
+
label,
|
|
1565
|
+
altLabels: strings(t["alt-labels"]),
|
|
1566
|
+
...definition === void 0 ? {} : { definition },
|
|
1567
|
+
confidence: score(t["confidence"]),
|
|
1568
|
+
...line === void 0 ? {} : { line },
|
|
1569
|
+
...page.language === void 0 ? {} : { language: page.language }
|
|
1570
|
+
});
|
|
1571
|
+
}
|
|
1572
|
+
}
|
|
1573
|
+
}
|
|
1574
|
+
for (const candidate of newCandidates(mergeFound(found), known, minPages)) {
|
|
1575
|
+
const concept = { label: candidate.label, from: candidate.from, altLabels: candidate.altLabels, ...candidate.language === void 0 ? {} : { language: candidate.language } };
|
|
1576
|
+
const fields = ["/label", ...candidate.altLabels.length > 0 ? ["/alt-labels"] : [], "/definition"];
|
|
1577
|
+
if (candidate.confidence === void 0 || candidate.definition === void 0) {
|
|
1578
|
+
const got = await draft(candidate.label, candidate.language, {}, candidate.from);
|
|
1579
|
+
if (got === void 0 || "skip" in got || got.status === "below-threshold") {
|
|
1580
|
+
entries2.push({
|
|
1581
|
+
action: "skip",
|
|
1582
|
+
file: displayPath(join3(outDir ?? cwd, `${slugOf(candidate.label)}${ext}`), cwd),
|
|
1583
|
+
id: slugOf(candidate.label),
|
|
1584
|
+
label: candidate.label,
|
|
1585
|
+
...candidate.language === void 0 ? {} : { language: candidate.language },
|
|
1586
|
+
source: "crawl",
|
|
1587
|
+
from: fromList(candidate.from, cwd),
|
|
1588
|
+
...got !== void 0 && "skip" in got ? { definition: { status: "missing" }, reason: got.skip } : {
|
|
1589
|
+
definition: {
|
|
1590
|
+
status: "below-threshold",
|
|
1591
|
+
...got === void 0 ? {} : { confidence: got.confidence },
|
|
1592
|
+
...modelName === void 0 ? {} : { model: modelName }
|
|
1593
|
+
}
|
|
1594
|
+
}
|
|
1595
|
+
});
|
|
1596
|
+
continue;
|
|
1597
|
+
}
|
|
1598
|
+
await create(concept, "crawl", { drafted: got, fields });
|
|
1599
|
+
continue;
|
|
1600
|
+
}
|
|
1601
|
+
if (candidate.confidence < threshold) {
|
|
1602
|
+
entries2.push({
|
|
1603
|
+
action: "skip",
|
|
1604
|
+
file: displayPath(join3(outDir ?? cwd, `${slugOf(candidate.label)}${ext}`), cwd),
|
|
1605
|
+
id: slugOf(candidate.label),
|
|
1606
|
+
label: candidate.label,
|
|
1607
|
+
...candidate.language === void 0 ? {} : { language: candidate.language },
|
|
1608
|
+
source: "crawl",
|
|
1609
|
+
from: fromList(candidate.from, cwd),
|
|
1610
|
+
definition: { status: "below-threshold", confidence: candidate.confidence, ...modelName === void 0 ? {} : { model: modelName } }
|
|
1611
|
+
});
|
|
1612
|
+
continue;
|
|
1613
|
+
}
|
|
1614
|
+
await create(concept, "crawl", { drafted: { definition: candidate.definition, confidence: candidate.confidence }, fields });
|
|
1615
|
+
}
|
|
1616
|
+
}
|
|
1617
|
+
if (!dryRun) {
|
|
1618
|
+
for (const { path, content } of writes) {
|
|
1619
|
+
await mkdir(dirname2(path), { recursive: true });
|
|
1620
|
+
await writeFile(path, content, "utf8");
|
|
1621
|
+
}
|
|
1622
|
+
}
|
|
1623
|
+
const count = (action) => entries2.filter((e) => e.action === action).length;
|
|
1624
|
+
return {
|
|
1625
|
+
entries: entries2,
|
|
1626
|
+
summary: {
|
|
1627
|
+
created: count("create"),
|
|
1628
|
+
filled: count("fill"),
|
|
1629
|
+
skipped: count("skip"),
|
|
1630
|
+
withoutDefinition: entries2.filter(
|
|
1631
|
+
(e) => (e.action === "create" || e.action === "skip") && e.definition.status !== "drafted" && e.definition.status !== "carried"
|
|
1632
|
+
).length,
|
|
1633
|
+
turns
|
|
1634
|
+
},
|
|
1635
|
+
dryRun,
|
|
1636
|
+
threshold
|
|
1637
|
+
};
|
|
1638
|
+
}
|
|
1639
|
+
async function fillInPlace(path, file, definition, provenance, model) {
|
|
1640
|
+
let content;
|
|
1641
|
+
try {
|
|
1642
|
+
content = await readFile(path, "utf8");
|
|
1643
|
+
} catch (error) {
|
|
1644
|
+
throw new TermError(`${file}: could not be read: ${errorMessage(error)}`);
|
|
1645
|
+
}
|
|
1646
|
+
const extractor = extractorForExtension(extname2(path)) ?? extractorByName("markdown");
|
|
1647
|
+
if (extractor?.apply === void 0) throw new TermError(`${file}: manni cannot write its metadata.`);
|
|
1648
|
+
const patch = { definition };
|
|
1649
|
+
if (provenance !== void 0 && model !== void 0) {
|
|
1650
|
+
const held = extractor.extract(content, path).data[META_PROVENANCE_KEY];
|
|
1651
|
+
const merged = mergeMetaProvenance(held, model.identity.model, "fields", [{ name: "/definition", confidence: provenance.confidence }]);
|
|
1652
|
+
if (merged !== void 0) patch[META_PROVENANCE_KEY] = merged.list;
|
|
1653
|
+
}
|
|
1654
|
+
try {
|
|
1655
|
+
return extractor.apply(content, patch, { filePath: path });
|
|
1656
|
+
} catch (error) {
|
|
1657
|
+
throw new TermError(`${file}: ${errorMessage(error)}`);
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
|
|
910
1661
|
// src/term/commands/formats.ts
|
|
911
1662
|
var FORMATS_FORMATS = ["pretty", "json"];
|
|
912
1663
|
var DOCUMENT_RENDERS = {
|
|
@@ -922,12 +1673,14 @@ var INTERCHANGE_LABELS = {
|
|
|
922
1673
|
tbx: "TBX v2",
|
|
923
1674
|
tbx3: "TBX v3",
|
|
924
1675
|
skos: "JSON-LD",
|
|
1676
|
+
"skos-ttl": "Turtle",
|
|
925
1677
|
vale: "style"
|
|
926
1678
|
};
|
|
927
1679
|
function rendered(writers, format, construct) {
|
|
928
1680
|
return writers.some((writer) => {
|
|
929
1681
|
const render = DOCUMENT_RENDERS[writer.format];
|
|
930
|
-
if (render
|
|
1682
|
+
if (render === void 0) return writer.format === format;
|
|
1683
|
+
if (render.input !== format) return false;
|
|
931
1684
|
return writer.shapes.some((shape) => render.shapes[shape] === construct);
|
|
932
1685
|
});
|
|
933
1686
|
}
|
|
@@ -1001,9 +1754,9 @@ async function runGet(opts) {
|
|
|
1001
1754
|
}
|
|
1002
1755
|
|
|
1003
1756
|
// src/term/core/lint.ts
|
|
1004
|
-
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
1757
|
+
import { mkdtemp, rm, writeFile as writeFile2 } from "node:fs/promises";
|
|
1005
1758
|
import { tmpdir } from "node:os";
|
|
1006
|
-
import { join as
|
|
1759
|
+
import { join as join4 } from "node:path";
|
|
1007
1760
|
|
|
1008
1761
|
// src/term/core/vale.ts
|
|
1009
1762
|
import { execFile } from "node:child_process";
|
|
@@ -1191,9 +1944,9 @@ async function lintTermSet(set, opts = {}) {
|
|
|
1191
1944
|
}
|
|
1192
1945
|
if (files.length === 0) return [];
|
|
1193
1946
|
const runVale = opts.runVale ?? runValeJson;
|
|
1194
|
-
const dir = await mkdtemp(
|
|
1947
|
+
const dir = await mkdtemp(join4(tmpdir(), "manni-term-lint-"));
|
|
1195
1948
|
try {
|
|
1196
|
-
for (const file of files) await
|
|
1949
|
+
for (const file of files) await writeFile2(join4(dir, file.name), file.content, "utf8");
|
|
1197
1950
|
const alerts = await runVale([dir], { config: opts.valeConfig, cwd: opts.cwd });
|
|
1198
1951
|
const findings = [];
|
|
1199
1952
|
for (const [path, list] of Object.entries(alerts)) {
|
|
@@ -1243,9 +1996,9 @@ async function runLint(opts) {
|
|
|
1243
1996
|
}
|
|
1244
1997
|
|
|
1245
1998
|
// src/term/commands/write.ts
|
|
1246
|
-
import { existsSync, statSync } from "node:fs";
|
|
1247
|
-
import { lstat, mkdir, readdir, readFile, rm as rm2, writeFile as
|
|
1248
|
-
import { dirname, extname, join as
|
|
1999
|
+
import { existsSync as existsSync2, statSync } from "node:fs";
|
|
2000
|
+
import { lstat, mkdir as mkdir2, readdir, readFile as readFile2, rm as rm2, writeFile as writeFile3 } from "node:fs/promises";
|
|
2001
|
+
import { dirname as dirname3, extname as extname3, join as join5, resolve as resolve3 } from "node:path";
|
|
1249
2002
|
var SUGGESTED_SECTION = "*.md";
|
|
1250
2003
|
var STYLE2 = "Terms";
|
|
1251
2004
|
function writeFormats(writers = TERM_WRITERS) {
|
|
@@ -1267,11 +2020,11 @@ async function filesUnder(dir, into) {
|
|
|
1267
2020
|
return;
|
|
1268
2021
|
}
|
|
1269
2022
|
for (const entry of entries2) {
|
|
1270
|
-
const path =
|
|
2023
|
+
const path = join5(dir, entry.name);
|
|
1271
2024
|
if (entry.isDirectory()) await filesUnder(path, into);
|
|
1272
2025
|
else if (entry.isFile()) {
|
|
1273
2026
|
const { size } = await lstat(path);
|
|
1274
|
-
into.set(path, size > MAX_EXISTING_FILE_BYTES ? "" : await
|
|
2027
|
+
into.set(path, size > MAX_EXISTING_FILE_BYTES ? "" : await readFile2(path, "utf8"));
|
|
1275
2028
|
}
|
|
1276
2029
|
}
|
|
1277
2030
|
}
|
|
@@ -1279,8 +2032,8 @@ async function existingFor(target) {
|
|
|
1279
2032
|
const existing = /* @__PURE__ */ new Map();
|
|
1280
2033
|
if (target.shape === "directory") {
|
|
1281
2034
|
await filesUnder(target.path, existing);
|
|
1282
|
-
} else if (
|
|
1283
|
-
existing.set(target.path, await
|
|
2035
|
+
} else if (existsSync2(target.path) && !isDirectory(target.path)) {
|
|
2036
|
+
existing.set(target.path, await readFile2(target.path, "utf8"));
|
|
1284
2037
|
}
|
|
1285
2038
|
return existing;
|
|
1286
2039
|
}
|
|
@@ -1299,23 +2052,23 @@ function droppedFrom(format, shape, readers) {
|
|
|
1299
2052
|
async function applyChanges(files, removals, existing, cwd, write) {
|
|
1300
2053
|
const changes = [];
|
|
1301
2054
|
for (const file of files) {
|
|
1302
|
-
const before = existing.get(file.path) ?? (
|
|
2055
|
+
const before = existing.get(file.path) ?? (existsSync2(file.path) ? await readFile2(file.path, "utf8") : void 0);
|
|
1303
2056
|
if (before === file.content) continue;
|
|
1304
2057
|
changes.push({ path: displayPath(file.path, cwd), action: before === void 0 ? "create" : "change" });
|
|
1305
2058
|
if (write) {
|
|
1306
|
-
await
|
|
1307
|
-
await
|
|
2059
|
+
await mkdir2(dirname3(file.path), { recursive: true });
|
|
2060
|
+
await writeFile3(file.path, file.content, "utf8");
|
|
1308
2061
|
}
|
|
1309
2062
|
}
|
|
1310
2063
|
for (const path of removals) {
|
|
1311
|
-
if (!
|
|
2064
|
+
if (!existsSync2(path)) continue;
|
|
1312
2065
|
changes.push({ path: displayPath(path, cwd), action: "remove" });
|
|
1313
2066
|
if (write) await rm2(path, { force: true });
|
|
1314
2067
|
}
|
|
1315
2068
|
return changes;
|
|
1316
2069
|
}
|
|
1317
2070
|
async function runWrite(opts) {
|
|
1318
|
-
const cwd =
|
|
2071
|
+
const cwd = resolve3(opts.cwd ?? process.cwd());
|
|
1319
2072
|
const writers = opts.writers ?? TERM_WRITERS;
|
|
1320
2073
|
const readers = opts.readers ?? TERM_READERS;
|
|
1321
2074
|
const check = opts.check === true;
|
|
@@ -1343,19 +2096,19 @@ async function runWrite(opts) {
|
|
|
1343
2096
|
"Vale found no config file. Set tools.vale.config in manni.config.yaml, or pass -o <styles directory>."
|
|
1344
2097
|
);
|
|
1345
2098
|
}
|
|
1346
|
-
targetPath =
|
|
2099
|
+
targetPath = resolve3(cwd, resolved.stylesPath);
|
|
1347
2100
|
if (!Object.values(resolved.baseStyles).some((styles) => styles.includes(STYLE2))) {
|
|
1348
2101
|
const first = Object.entries(resolved.baseStyles)[0];
|
|
1349
2102
|
const [section, styles] = first ?? [SUGGESTED_SECTION, []];
|
|
1350
2103
|
wiring = {
|
|
1351
|
-
rootIni: displayPath(
|
|
2104
|
+
rootIni: displayPath(resolve3(cwd, resolved.rootIni), cwd),
|
|
1352
2105
|
section,
|
|
1353
2106
|
styles: [...styles, STYLE2],
|
|
1354
2107
|
addSection: first === void 0
|
|
1355
2108
|
};
|
|
1356
2109
|
}
|
|
1357
2110
|
} else {
|
|
1358
|
-
targetPath =
|
|
2111
|
+
targetPath = resolve3(cwd, opts.out);
|
|
1359
2112
|
}
|
|
1360
2113
|
const shape = format === "vale" || /[\\/]$/.test(opts.out ?? "") || isDirectory(targetPath) ? "directory" : "file";
|
|
1361
2114
|
const target = { path: targetPath, shape };
|
|
@@ -1368,7 +2121,7 @@ async function runWrite(opts) {
|
|
|
1368
2121
|
throw error;
|
|
1369
2122
|
}
|
|
1370
2123
|
const changes = await applyChanges(render.files, render.removals, existing, cwd, !check && !dryRun);
|
|
1371
|
-
const shown = format === "vale" ? displayPath(
|
|
2124
|
+
const shown = format === "vale" ? displayPath(join5(targetPath, STYLE2), cwd) : opts.out ?? displayPath(targetPath, cwd);
|
|
1372
2125
|
return {
|
|
1373
2126
|
mode: "render",
|
|
1374
2127
|
format,
|
|
@@ -1395,7 +2148,7 @@ function inputFor(content, path, construct, file) {
|
|
|
1395
2148
|
return { content, file, path, format: MANIFEST_FORMAT, metadata: {}, lineFor: () => void 0 };
|
|
1396
2149
|
}
|
|
1397
2150
|
if (construct === "tbx-entry") return tbxInput(content, file, path);
|
|
1398
|
-
const extractor = extractorForExtension(
|
|
2151
|
+
const extractor = extractorForExtension(extname3(path));
|
|
1399
2152
|
if (extractor === void 0) throw new TermError(`${file}: no reader for its extension.`);
|
|
1400
2153
|
return extractInput(content, file, path, extractor.name);
|
|
1401
2154
|
}
|
|
@@ -1428,6 +2181,11 @@ async function writeInPlace(opts, check, dryRun) {
|
|
|
1428
2181
|
if (path === void 0) {
|
|
1429
2182
|
throw new TermError(`${term.location.file} has nowhere to write back to. Pass -f <format> -o <path>.`);
|
|
1430
2183
|
}
|
|
2184
|
+
if (construct === "skos") {
|
|
2185
|
+
throw new TermError(
|
|
2186
|
+
`${displayPath(term.location.file, cwd)} is SKOS and is not rewritten in place; render it with -f skos or -f skos-ttl.`
|
|
2187
|
+
);
|
|
2188
|
+
}
|
|
1431
2189
|
const reader = readerForConstruct(construct, readers);
|
|
1432
2190
|
if (reader?.apply === void 0) {
|
|
1433
2191
|
const name = reader?.label ?? construct;
|
|
@@ -1445,7 +2203,7 @@ async function writeInPlace(opts, check, dryRun) {
|
|
|
1445
2203
|
for (const [path, { file, constructs }] of byPath) {
|
|
1446
2204
|
let original;
|
|
1447
2205
|
try {
|
|
1448
|
-
original = await
|
|
2206
|
+
original = await readFile2(path, "utf8");
|
|
1449
2207
|
} catch (error) {
|
|
1450
2208
|
throw new TermError(`${file}: could not be read: ${errorMessage(error)}`);
|
|
1451
2209
|
}
|
|
@@ -1489,16 +2247,28 @@ function renderListCsv(terms) {
|
|
|
1489
2247
|
var INFORMATION_URI = "https://hawkeyexl.github.io/manni/term/";
|
|
1490
2248
|
var RULES_URI = "https://hawkeyexl.github.io/manni/term/reference/rules/";
|
|
1491
2249
|
var RULE_DESCRIPTIONS = {
|
|
1492
|
-
"undefined-term": "A page's concepts: names
|
|
2250
|
+
"undefined-term": "A page's concepts: names no entry, by label, id or alt-label.",
|
|
1493
2251
|
"duplicate-id": "Two entries share an id.",
|
|
1494
2252
|
"label-collision": "Two entries claim the same preferred label, ignoring case.",
|
|
1495
2253
|
"alt-label-collision": "An entry's alt-label is another entry's preferred label, ignoring case.",
|
|
1496
2254
|
"dangling-reference": "A value of broader, narrower, related-terms or see names no entry, by label or by id.",
|
|
1497
2255
|
"broader-cycle": "A chain of broader returns to where it started.",
|
|
1498
2256
|
"see-not-empty": "An entry with see also carries a definition.",
|
|
2257
|
+
"missing-definition": "An entry has neither a definition nor see.",
|
|
2258
|
+
"conflicting-matches": "One IRI is listed under two of an entry's match kinds.",
|
|
1499
2259
|
"asymmetric-hierarchy": "A names B as broader, and B omits A from narrower, or the reverse.",
|
|
2260
|
+
"alt-label-reference": "A page's concepts: names an entry by one of its alt-labels.",
|
|
1500
2261
|
"abstract-too-long": "An abstract is longer than term.abstractMaxLength.",
|
|
1501
|
-
"unused-term": "No page's concepts: names the entry
|
|
2262
|
+
"unused-term": "No page's concepts: names the entry.",
|
|
2263
|
+
"hierarchy-outside-termbase": "A page's graph: block gives a term a broader, narrower or related concept its own entry does not list.",
|
|
2264
|
+
"label-overlap": "A hidden-label or alt-label repeats one of the entry's own names, or a hidden-label is another entry's label or alt-label.",
|
|
2265
|
+
"asymmetric-related": "A names B in related-terms, and B omits A.",
|
|
2266
|
+
"related-in-hierarchy": "A related term is also broader or narrower than the entry, at any depth.",
|
|
2267
|
+
"ambiguous-alt-label": "Two entries share an alt-label, ignoring case.",
|
|
2268
|
+
"deprecated-label": "The entry's label is deprecated or superseded in its designations.",
|
|
2269
|
+
"related-siblings": "Two related terms share a broader term.",
|
|
2270
|
+
"orphan-term": "An entry has no broader, narrower or related term, in a termbase with a hierarchy.",
|
|
2271
|
+
"keyword-candidate": "A free keyword is on several pages and names no term."
|
|
1502
2272
|
};
|
|
1503
2273
|
var PROSE_PREFIX = `${RULE_ID_PREFIX}/prose/`;
|
|
1504
2274
|
var FIELD_LABEL = new RegExp(`^(?:\\(root\\)|/(?:${TERM_FIELDS.join("|")})) `);
|
|
@@ -1535,21 +2305,53 @@ function renderFindingsJunit(report) {
|
|
|
1535
2305
|
);
|
|
1536
2306
|
}
|
|
1537
2307
|
|
|
1538
|
-
// src/term/
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
2308
|
+
// src/term/reporters/fill.ts
|
|
2309
|
+
var DONE = { create: "created", fill: "filled", skip: "skipped", exists: "exists" };
|
|
2310
|
+
var WOULD = { create: "would create", fill: "would fill", skip: "skipped", exists: "exists" };
|
|
2311
|
+
function detail(entry, threshold) {
|
|
2312
|
+
if (entry.reason !== void 0) return entry.reason;
|
|
2313
|
+
const { status, confidence } = entry.definition;
|
|
2314
|
+
if (entry.action === "exists") return "the file is already there";
|
|
2315
|
+
switch (status) {
|
|
2316
|
+
case "carried":
|
|
2317
|
+
return "definition from graph: block";
|
|
2318
|
+
case "drafted":
|
|
2319
|
+
return `definition drafted (${(confidence ?? 0).toFixed(2)})`;
|
|
2320
|
+
case "below-threshold": {
|
|
2321
|
+
const under = `confidence ${(confidence ?? 0).toFixed(2)} is under ${String(threshold)}`;
|
|
2322
|
+
return entry.action === "create" ? `stub, ${under}` : under;
|
|
2323
|
+
}
|
|
2324
|
+
case "missing":
|
|
2325
|
+
return "stub, no definition";
|
|
2326
|
+
}
|
|
2327
|
+
}
|
|
2328
|
+
function renderFillPretty(report) {
|
|
2329
|
+
const words = report.dryRun ? WOULD : DONE;
|
|
2330
|
+
const actionWidth = Math.max(0, ...report.entries.map((e) => words[e.action].length));
|
|
2331
|
+
const fileWidth = Math.max(0, ...report.entries.map((e) => e.file.length)) + 3;
|
|
2332
|
+
const labelWidth = Math.max(0, ...report.entries.map((e) => e.label.length)) + 3;
|
|
2333
|
+
const lines = report.entries.map(
|
|
2334
|
+
(e) => `${words[e.action].padEnd(actionWidth)} ${e.file.padEnd(fileWidth)}${e.label.padEnd(labelWidth)}${detail(e, report.threshold)}`
|
|
2335
|
+
);
|
|
2336
|
+
const { created, filled, skipped, withoutDefinition } = report.summary;
|
|
2337
|
+
const skips = skipped > 0 ? `, ${String(skipped)} skipped` : "";
|
|
2338
|
+
lines.push(
|
|
2339
|
+
report.dryRun ? `${plural(created, "term")} would be created, ${String(filled)} would be filled, ${String(withoutDefinition)} left without a definition${skips}` : `${plural(created, "term")} created, ${String(filled)} filled, ${String(withoutDefinition)} left without a definition${skips}`
|
|
2340
|
+
);
|
|
2341
|
+
return lines.join("\n");
|
|
2342
|
+
}
|
|
2343
|
+
function renderFillJson(report) {
|
|
2344
|
+
return JSON.stringify({ entries: report.entries, summary: report.summary }, null, 2);
|
|
1549
2345
|
}
|
|
1550
2346
|
|
|
1551
2347
|
// src/term/cli.ts
|
|
1552
|
-
|
|
2348
|
+
function numeric(name, value, min, max, integer = false) {
|
|
2349
|
+
if (value === void 0) return;
|
|
2350
|
+
if (!Number.isFinite(value) || value < min || value > max || integer && !Number.isInteger(value)) {
|
|
2351
|
+
const kind = integer ? "a whole number" : "a number";
|
|
2352
|
+
throw new TermError(`${name} must be ${kind} between ${String(min)} and ${String(max)}, got ${String(value)}.`);
|
|
2353
|
+
}
|
|
2354
|
+
}
|
|
1553
2355
|
function colorFor(options) {
|
|
1554
2356
|
return shouldColor({ noColor: !options.color, isTTY: process.stdout.isTTY });
|
|
1555
2357
|
}
|
|
@@ -1574,11 +2376,11 @@ function print(text) {
|
|
|
1574
2376
|
process.stdout.write(`${text}
|
|
1575
2377
|
`);
|
|
1576
2378
|
}
|
|
1577
|
-
function renderFindings(report, format, options,
|
|
2379
|
+
function renderFindings(report, format, options, references) {
|
|
1578
2380
|
let text;
|
|
1579
2381
|
switch (format) {
|
|
1580
2382
|
case "pretty":
|
|
1581
|
-
text = renderFindingsPretty(report, { color: colorFor(options), references
|
|
2383
|
+
text = renderFindingsPretty(report, { color: colorFor(options), references });
|
|
1582
2384
|
break;
|
|
1583
2385
|
case "json":
|
|
1584
2386
|
text = renderFindingsJson(report);
|
|
@@ -1703,6 +2505,44 @@ function buildProgram() {
|
|
|
1703
2505
|
fail(err);
|
|
1704
2506
|
}
|
|
1705
2507
|
});
|
|
2508
|
+
withInputs(
|
|
2509
|
+
program.command("fill").description("Create term pages for the concepts pages name, and draft missing definitions").argument("[paths...]", "files, directories, or globs to read (use - for stdin)")
|
|
2510
|
+
).option("-o, --out <dir>", "directory for new term pages").option("--crawl", "also ask the model for terms that page bodies and keywords use").option("--offline", "no network egress: only a model already downloaded, never a remote provider").option("--provider <name>", "provider: auto (default), anthropic, openai, claude-cli, llama-cpp").option("--model <model>", "model override; needs a named provider, from here or config").option("--local", LOCAL_FLAG_HELP).option("--confidence <n>", "minimum confidence to write a definition (0-1)", parseFloat).option("--max-turns <n>", "stop after this many inference calls", parseFloat).option("--chunk-chars <n>", "characters of page per call under --crawl (default 12000)", parseFloat).option("--no-cache", "bypass the answer cache").option("--dry-run", "write nothing; print what would change").option("-f, --format <format>", `output: ${FILL_FORMATS.join(" | ")}`, "pretty").addHelpText(
|
|
2511
|
+
"after",
|
|
2512
|
+
[
|
|
2513
|
+
"",
|
|
2514
|
+
"Examples:",
|
|
2515
|
+
" manni term fill --offline --dry-run # what is missing, nothing sent",
|
|
2516
|
+
" manni term fill # pages and drafted definitions",
|
|
2517
|
+
" manni term fill --crawl -o docs/glossary/ # terms no metadata named",
|
|
2518
|
+
" manni term fill --dry-run -f json # for a script"
|
|
2519
|
+
].join("\n")
|
|
2520
|
+
).action(async (paths, options) => {
|
|
2521
|
+
try {
|
|
2522
|
+
const format = formatChoice(options.format, FILL_FORMATS);
|
|
2523
|
+
numeric("--confidence", options.confidence, 0, 1);
|
|
2524
|
+
numeric("--max-turns", options.maxTurns, 1, Number.MAX_SAFE_INTEGER, true);
|
|
2525
|
+
numeric("--chunk-chars", options.chunkChars, 1, Number.MAX_SAFE_INTEGER, true);
|
|
2526
|
+
const report = await runFill({
|
|
2527
|
+
...await coreOptions(paths, options),
|
|
2528
|
+
...options.out === void 0 ? {} : { out: options.out },
|
|
2529
|
+
...options.crawl === true ? { crawl: true } : {},
|
|
2530
|
+
...options.offline === true ? { offline: true } : {},
|
|
2531
|
+
...options.provider === void 0 ? {} : { provider: options.provider },
|
|
2532
|
+
...options.model === void 0 ? {} : { model: options.model },
|
|
2533
|
+
...options.local === true ? { local: true } : {},
|
|
2534
|
+
...options.confidence === void 0 ? {} : { confidence: options.confidence },
|
|
2535
|
+
...options.maxTurns === void 0 ? {} : { maxTurns: options.maxTurns },
|
|
2536
|
+
...options.chunkChars === void 0 ? {} : { chunkChars: options.chunkChars },
|
|
2537
|
+
...options.cache ? {} : { noCache: true },
|
|
2538
|
+
...options.dryRun === true ? { dryRun: true } : {}
|
|
2539
|
+
});
|
|
2540
|
+
print(format === "json" ? renderFillJson(report) : renderFillPretty(report));
|
|
2541
|
+
process.exitCode = 0;
|
|
2542
|
+
} catch (err) {
|
|
2543
|
+
fail(err);
|
|
2544
|
+
}
|
|
2545
|
+
});
|
|
1706
2546
|
program.command("formats").description("List the constructs read and written, per format").option("-f, --format <format>", `output: ${FORMATS_FORMATS.join(" | ")}`, "pretty").action((options) => {
|
|
1707
2547
|
try {
|
|
1708
2548
|
const format = formatChoice(options.format, FORMATS_FORMATS);
|
|
@@ -1720,4 +2560,4 @@ export {
|
|
|
1720
2560
|
TermError,
|
|
1721
2561
|
buildProgram
|
|
1722
2562
|
};
|
|
1723
|
-
//# sourceMappingURL=term-
|
|
2563
|
+
//# sourceMappingURL=term-D2N7UN4P.js.map
|