@hawkeyexl/manni 4.10.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-EFSFG6GC.js +46 -0
- 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-NLL4NRYA.js → check-Y62BJNC4.js} +35 -31
- package/dist/{check-NLL4NRYA.js.map → check-Y62BJNC4.js.map} +1 -1
- package/dist/{check-7B77ZD2N.js → check-ZMO3ZLMW.js} +19 -15
- package/dist/{chunk-PK7EKJ5T.js → chunk-24AJK2RG.js} +5 -10
- package/dist/chunk-24AJK2RG.js.map +1 -0
- package/dist/chunk-2OZF2VUB.js +164 -0
- package/dist/chunk-2OZF2VUB.js.map +1 -0
- package/dist/chunk-2UJZXVHR.js +1868 -0
- package/dist/chunk-2UJZXVHR.js.map +1 -0
- package/dist/{chunk-DNZUBCGZ.js → chunk-3BRJCQPY.js} +36 -7
- package/dist/chunk-3BRJCQPY.js.map +1 -0
- package/dist/{chunk-D2UW3ZCK.js → chunk-42VFJOAF.js} +13 -11
- package/dist/{chunk-D2UW3ZCK.js.map → chunk-42VFJOAF.js.map} +1 -1
- package/dist/{chunk-LQZQ5KGG.js → chunk-4Q24OYI3.js} +7 -7
- package/dist/{chunk-XU73V5XT.js → chunk-4WJTURRO.js} +15 -15
- package/dist/{chunk-WN47MNSK.js → chunk-5SID2SVL.js} +4 -4
- package/dist/{chunk-5REEVKGH.js → chunk-AANUY4BH.js} +2 -2
- package/dist/chunk-ANPIIYRH.js +2272 -0
- package/dist/chunk-ANPIIYRH.js.map +1 -0
- package/dist/{chunk-RZVCWX5R.js → chunk-AYVKN3PG.js} +4 -4
- package/dist/{chunk-2UCC26MO.js → chunk-CH6IOGXV.js} +9 -9
- package/dist/{chunk-RODZ7MB7.js → chunk-D5Z6B4M7.js} +6 -6
- package/dist/{chunk-IJ62BB2T.js → chunk-D6SELXQ2.js} +7 -7
- package/dist/{chunk-2JV7C4YV.js → chunk-DDILEF5F.js} +890 -1399
- package/dist/chunk-DDILEF5F.js.map +1 -0
- package/dist/{chunk-3E2X2RBU.js → chunk-DGRLHDM4.js} +9 -9
- package/dist/{chunk-2BV4FBC7.js → chunk-DHGB4JBG.js} +4 -3
- package/dist/chunk-DHGB4JBG.js.map +1 -0
- package/dist/{chunk-6LR73NMO.js → chunk-DLU5FCFT.js} +30 -28
- 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-BD7IXBWE.js → chunk-F564FHMQ.js} +8 -8
- package/dist/{chunk-ABHG6I3G.js → chunk-FKAZUZQU.js} +469 -85
- package/dist/chunk-FKAZUZQU.js.map +1 -0
- package/dist/{chunk-DFCQ6BMI.js → chunk-G3MBUL5M.js} +4 -4
- package/dist/{chunk-SUTMSDQ2.js → chunk-GQ3KRY3B.js} +3 -3
- package/dist/chunk-HDPN46JP.js +393 -0
- package/dist/chunk-HDPN46JP.js.map +1 -0
- package/dist/{chunk-EAUIQADY.js → chunk-IQQAJROD.js} +6 -6
- package/dist/{chunk-ZHRPH52H.js → chunk-IZXN3WI6.js} +2 -2
- package/dist/{chunk-NCPWXHDO.js → chunk-JEUFYSFQ.js} +4 -4
- package/dist/{chunk-G6FNWRAI.js → chunk-JSSM7VVV.js} +4 -4
- package/dist/{chunk-CCWMACJL.js → chunk-KFGZPVFA.js} +229 -821
- package/dist/chunk-KFGZPVFA.js.map +1 -0
- package/dist/{chunk-H26VDFDS.js → chunk-KGFSPJLD.js} +2 -2
- package/dist/{chunk-AO5TSDKT.js → chunk-KMORGMCW.js} +7 -7
- package/dist/{chunk-WQWKYAAK.js → chunk-NUQF5F5J.js} +2 -2
- package/dist/{chunk-2YJ5H5E6.js → chunk-NZ6KSHFD.js} +23 -21
- package/dist/{chunk-2YJ5H5E6.js.map → chunk-NZ6KSHFD.js.map} +1 -1
- package/dist/{chunk-7Y3N4Y72.js → chunk-OHUDZRLK.js} +3 -3
- package/dist/{chunk-GCKHSBEN.js → chunk-OKMTUAWO.js} +4 -4
- package/dist/{chunk-6M5VJOC2.js → chunk-OTJOBZJ5.js} +167 -166
- package/dist/chunk-OTJOBZJ5.js.map +1 -0
- package/dist/{chunk-2W34HX2U.js → chunk-PS257NIU.js} +288 -373
- 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-QEAGL4V5.js +3185 -0
- package/dist/chunk-QEAGL4V5.js.map +1 -0
- package/dist/{chunk-GB2XPITA.js → chunk-QMY57PVW.js} +2 -2
- package/dist/{chunk-55GMOVKW.js → chunk-QNDDPXFR.js} +2 -2
- package/dist/{chunk-GXN7RRHR.js → chunk-QSIXNTRV.js} +4 -4
- package/dist/{chunk-G7XD4QH5.js → chunk-RGLFV4KO.js} +11372 -10218
- package/dist/chunk-RGLFV4KO.js.map +1 -0
- package/dist/{chunk-QBVP3SQP.js → chunk-SGR7ZAVE.js} +13 -7
- package/dist/chunk-SGR7ZAVE.js.map +1 -0
- package/dist/{chunk-KBG463UK.js → chunk-SMHAYK6I.js} +2409 -5243
- package/dist/chunk-SMHAYK6I.js.map +1 -0
- package/dist/{chunk-XG6PVB5S.js → chunk-SSQZB5SQ.js} +1 -11
- package/dist/chunk-SSQZB5SQ.js.map +1 -0
- package/dist/{chunk-GDLHTI5R.js → chunk-STPGIKPY.js} +8 -2
- package/dist/chunk-STPGIKPY.js.map +1 -0
- package/dist/{chunk-QJRQ4BRC.js → chunk-U22TOL5Y.js} +17 -17
- package/dist/{chunk-NGTVREIH.js → chunk-U6IHLEWT.js} +2 -2
- package/dist/{chunk-Z5YHMRLF.js → chunk-UUCCV3SI.js} +2 -2
- package/dist/{chunk-ZXXFP2LA.js → chunk-UXMCHBOJ.js} +2 -2
- package/dist/{chunk-VZVEP2OZ.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/chunk-ZPLVANY2.js +15 -0
- package/dist/chunk-ZPLVANY2.js.map +1 -0
- package/dist/{cli-BIIUKPTE.js → cli-4CR7QIOK.js} +26 -22
- package/dist/{cli-BIIUKPTE.js.map → cli-4CR7QIOK.js.map} +1 -1
- package/dist/{cli-V2DI3K2R.js → cli-6R4W3HAH.js} +37 -33
- package/dist/{cli-V2DI3K2R.js.map → cli-6R4W3HAH.js.map} +1 -1
- package/dist/{cli-HO62TOM2.js → cli-BOMA2FMP.js} +14 -11
- package/dist/{cli-EH3I4IUX.js → cli-EDQPQOCE.js} +47 -41
- package/dist/cli-EDQPQOCE.js.map +1 -0
- package/dist/{cli-P2X7PNY6.js → cli-GBF76EXT.js} +25 -20
- package/dist/{cli-P2X7PNY6.js.map → cli-GBF76EXT.js.map} +1 -1
- package/dist/{cli-4YYC6LCY.js → cli-MQYCF3SR.js} +27 -23
- package/dist/{cli-4YYC6LCY.js.map → cli-MQYCF3SR.js.map} +1 -1
- package/dist/{cli-UETKXHJN.js → cli-OJKFXQOM.js} +9 -9
- package/dist/{cli-LWST5FQH.js → cli-PHZAO4LZ.js} +4 -4
- package/dist/{cli-TELPAMJO.js → cli-PTKFFNOW.js} +59 -35
- package/dist/cli-PTKFFNOW.js.map +1 -0
- package/dist/{cli-SGVFZOAW.js → cli-UW2K5Z5J.js} +34 -29
- package/dist/{cli-SGVFZOAW.js.map → cli-UW2K5Z5J.js.map} +1 -1
- package/dist/cli-XXTNPPKB.js +83 -0
- package/dist/cli-XXTNPPKB.js.map +1 -0
- package/dist/cli.js +24 -12
- package/dist/cli.js.map +1 -1
- package/dist/{config-TYXYQK3I.js → config-JJW75SBX.js} +5 -5
- package/dist/docmeta.js +13 -10
- 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 +1214 -940
- package/dist/index.js +190 -160
- package/dist/index.js.map +1 -1
- package/dist/{json-QR4G35KA.js → json-PU2HLHDQ.js} +18 -14
- 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-FSXDXCDD.js → page-UMAA3NCM.js} +18 -13
- package/dist/{prepare-UPIBTFNS.js → prepare-3I3LOXXD.js} +24 -20
- package/dist/{prepare-UPIBTFNS.js.map → prepare-3I3LOXXD.js.map} +1 -1
- package/dist/{pretty-4IONWSEP.js → pretty-ANLRHU4O.js} +18 -14
- package/dist/{pretty-R4BQD2VH.js → pretty-Q3ZFKOR7.js} +18 -14
- 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-DHO2BXAD.js → reporters-ILT36CIH.js} +7 -7
- package/dist/{reporters-FPP6JNDP.js → reporters-PNDLWT6K.js} +16 -12
- package/dist/run-QXCK33Z4.js +37 -0
- package/dist/{term-ASM4LVYC.js → term-D2N7UN4P.js} +981 -138
- package/dist/term-D2N7UN4P.js.map +1 -0
- package/dist/validate-BRUCOT2O.js +19 -0
- package/dist/validate-BRUCOT2O.js.map +1 -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/batch-6NICDKRE.js +0 -41
- package/dist/build-3KP2K3XN.js +0 -32
- package/dist/calibrate-LUA3DWKD.js +0 -36
- package/dist/capture-NETOHCB4.js +0 -34
- package/dist/check-E4QCB7LS.js +0 -20
- package/dist/check-PTECPIIB.js +0 -26
- package/dist/chunk-2BV4FBC7.js.map +0 -1
- package/dist/chunk-2JV7C4YV.js.map +0 -1
- package/dist/chunk-2W34HX2U.js.map +0 -1
- package/dist/chunk-4DLF5SA4.js +0 -392
- package/dist/chunk-4DLF5SA4.js.map +0 -1
- package/dist/chunk-6AGESHHM.js +0 -387
- package/dist/chunk-6AGESHHM.js.map +0 -1
- package/dist/chunk-6LR73NMO.js.map +0 -1
- package/dist/chunk-6M5VJOC2.js.map +0 -1
- package/dist/chunk-ABHG6I3G.js.map +0 -1
- package/dist/chunk-CCWMACJL.js.map +0 -1
- package/dist/chunk-DNZUBCGZ.js.map +0 -1
- package/dist/chunk-G7XD4QH5.js.map +0 -1
- package/dist/chunk-GDLHTI5R.js.map +0 -1
- package/dist/chunk-KBG463UK.js.map +0 -1
- package/dist/chunk-PK7EKJ5T.js.map +0 -1
- package/dist/chunk-QBVP3SQP.js.map +0 -1
- package/dist/chunk-QCHVR4ZM.js.map +0 -1
- package/dist/chunk-VVVKBUBO.js +0 -818
- package/dist/chunk-VVVKBUBO.js.map +0 -1
- package/dist/chunk-XG6PVB5S.js.map +0 -1
- package/dist/cli-EH3I4IUX.js.map +0 -1
- package/dist/cli-TELPAMJO.js.map +0 -1
- package/dist/github-ESK45CEZ.js +0 -26
- package/dist/github-WER7JUTN.js +0 -31
- package/dist/lint-QTI7XK2A.js +0 -30
- package/dist/list-JO4G3TS3.js +0 -30
- package/dist/list-O2MJUP5V.js +0 -28
- package/dist/run-YH5Z7RJ7.js +0 -32
- package/dist/term-ASM4LVYC.js.map +0 -1
- package/dist/validate-7JI3H57P.js +0 -17
- /package/dist/{batch-6NICDKRE.js.map → batch-EFSFG6GC.js.map} +0 -0
- /package/dist/{build-3KP2K3XN.js.map → build-NIO3UIWJ.js.map} +0 -0
- /package/dist/{calibrate-LUA3DWKD.js.map → calibrate-6VO7URRV.js.map} +0 -0
- /package/dist/{capture-NETOHCB4.js.map → capture-NMBVJO3C.js.map} +0 -0
- /package/dist/{check-7B77ZD2N.js.map → check-SHOYX2B5.js.map} +0 -0
- /package/dist/{check-E4QCB7LS.js.map → check-XMJKH3KV.js.map} +0 -0
- /package/dist/{check-PTECPIIB.js.map → check-ZMO3ZLMW.js.map} +0 -0
- /package/dist/{chunk-LQZQ5KGG.js.map → chunk-4Q24OYI3.js.map} +0 -0
- /package/dist/{chunk-XU73V5XT.js.map → chunk-4WJTURRO.js.map} +0 -0
- /package/dist/{chunk-WN47MNSK.js.map → chunk-5SID2SVL.js.map} +0 -0
- /package/dist/{chunk-5REEVKGH.js.map → chunk-AANUY4BH.js.map} +0 -0
- /package/dist/{chunk-RZVCWX5R.js.map → chunk-AYVKN3PG.js.map} +0 -0
- /package/dist/{chunk-2UCC26MO.js.map → chunk-CH6IOGXV.js.map} +0 -0
- /package/dist/{chunk-RODZ7MB7.js.map → chunk-D5Z6B4M7.js.map} +0 -0
- /package/dist/{chunk-IJ62BB2T.js.map → chunk-D6SELXQ2.js.map} +0 -0
- /package/dist/{chunk-3E2X2RBU.js.map → chunk-DGRLHDM4.js.map} +0 -0
- /package/dist/{chunk-BD7IXBWE.js.map → chunk-F564FHMQ.js.map} +0 -0
- /package/dist/{chunk-DFCQ6BMI.js.map → chunk-G3MBUL5M.js.map} +0 -0
- /package/dist/{chunk-SUTMSDQ2.js.map → chunk-GQ3KRY3B.js.map} +0 -0
- /package/dist/{chunk-EAUIQADY.js.map → chunk-IQQAJROD.js.map} +0 -0
- /package/dist/{chunk-ZHRPH52H.js.map → chunk-IZXN3WI6.js.map} +0 -0
- /package/dist/{chunk-NCPWXHDO.js.map → chunk-JEUFYSFQ.js.map} +0 -0
- /package/dist/{chunk-G6FNWRAI.js.map → chunk-JSSM7VVV.js.map} +0 -0
- /package/dist/{chunk-H26VDFDS.js.map → chunk-KGFSPJLD.js.map} +0 -0
- /package/dist/{chunk-AO5TSDKT.js.map → chunk-KMORGMCW.js.map} +0 -0
- /package/dist/{chunk-WQWKYAAK.js.map → chunk-NUQF5F5J.js.map} +0 -0
- /package/dist/{chunk-7Y3N4Y72.js.map → chunk-OHUDZRLK.js.map} +0 -0
- /package/dist/{chunk-GCKHSBEN.js.map → chunk-OKMTUAWO.js.map} +0 -0
- /package/dist/{chunk-GB2XPITA.js.map → chunk-QMY57PVW.js.map} +0 -0
- /package/dist/{chunk-55GMOVKW.js.map → chunk-QNDDPXFR.js.map} +0 -0
- /package/dist/{chunk-GXN7RRHR.js.map → chunk-QSIXNTRV.js.map} +0 -0
- /package/dist/{chunk-QJRQ4BRC.js.map → chunk-U22TOL5Y.js.map} +0 -0
- /package/dist/{chunk-NGTVREIH.js.map → chunk-U6IHLEWT.js.map} +0 -0
- /package/dist/{chunk-Z5YHMRLF.js.map → chunk-UUCCV3SI.js.map} +0 -0
- /package/dist/{chunk-ZXXFP2LA.js.map → chunk-UXMCHBOJ.js.map} +0 -0
- /package/dist/{chunk-VZVEP2OZ.js.map → chunk-VFAKGIDG.js.map} +0 -0
- /package/dist/{chunk-VQK4VHLF.js.map → chunk-YQV75FIL.js.map} +0 -0
- /package/dist/{cli-HO62TOM2.js.map → chunk-YUTVAMWW.js.map} +0 -0
- /package/dist/{config-TYXYQK3I.js.map → cli-BOMA2FMP.js.map} +0 -0
- /package/dist/{cli-UETKXHJN.js.map → cli-OJKFXQOM.js.map} +0 -0
- /package/dist/{cli-LWST5FQH.js.map → cli-PHZAO4LZ.js.map} +0 -0
- /package/dist/{github-ESK45CEZ.js.map → config-JJW75SBX.js.map} +0 -0
- /package/dist/{github-WER7JUTN.js.map → github-6VQKSB67.js.map} +0 -0
- /package/dist/{host-6GURH5HE.js.map → github-RBSEM7ZK.js.map} +0 -0
- /package/dist/{json-QR4G35KA.js.map → host-YSTYO5DX.js.map} +0 -0
- /package/dist/{lint-QTI7XK2A.js.map → json-PU2HLHDQ.js.map} +0 -0
- /package/dist/{list-JO4G3TS3.js.map → lint-KIVTHLGU.js.map} +0 -0
- /package/dist/{list-O2MJUP5V.js.map → list-RDEJDDJF.js.map} +0 -0
- /package/dist/{page-FSXDXCDD.js.map → list-SUTDWL2J.js.map} +0 -0
- /package/dist/{pretty-4IONWSEP.js.map → page-UMAA3NCM.js.map} +0 -0
- /package/dist/{pretty-R4BQD2VH.js.map → pretty-ANLRHU4O.js.map} +0 -0
- /package/dist/{provider-527CO4DM.js.map → pretty-Q3ZFKOR7.js.map} +0 -0
- /package/dist/{reporters-DHO2BXAD.js.map → provider-LBX4IXGX.js.map} +0 -0
- /package/dist/{release-3D5PK6M7.js.map → release-VV3UTKE5.js.map} +0 -0
- /package/dist/{reporters-FPP6JNDP.js.map → reporters-26H3N2KW.js.map} +0 -0
- /package/dist/{reporters-M6LJ2IYU.js.map → reporters-ILT36CIH.js.map} +0 -0
- /package/dist/{run-YH5Z7RJ7.js.map → reporters-PNDLWT6K.js.map} +0 -0
- /package/dist/{validate-7JI3H57P.js.map → run-QXCK33Z4.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-55GMOVKW.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,49 +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-
|
|
88
|
+
import "./chunk-YUTVAMWW.js";
|
|
89
|
+
import "./chunk-JSSM7VVV.js";
|
|
83
90
|
import {
|
|
84
|
-
|
|
85
|
-
|
|
91
|
+
DEFAULT_CHUNK_CHARS,
|
|
92
|
+
splitBody
|
|
93
|
+
} from "./chunk-PS257NIU.js";
|
|
86
94
|
import {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
splitList
|
|
90
|
-
} from "./chunk-KBG463UK.js";
|
|
95
|
+
mergeMetaProvenance
|
|
96
|
+
} from "./chunk-2OZF2VUB.js";
|
|
91
97
|
import {
|
|
92
98
|
OMITTED_WHEN_CLEAN,
|
|
93
99
|
renderJunit,
|
|
94
100
|
renderSarif
|
|
95
|
-
} 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";
|
|
96
109
|
import {
|
|
97
110
|
STDIN_TOKEN,
|
|
98
111
|
extractorByName,
|
|
99
112
|
extractorForExtension
|
|
100
|
-
} from "./chunk-
|
|
101
|
-
import
|
|
102
|
-
|
|
103
|
-
} from "./chunk-YEUYKR62.js";
|
|
113
|
+
} from "./chunk-RGLFV4KO.js";
|
|
114
|
+
import "./chunk-77AINBYM.js";
|
|
115
|
+
import "./chunk-MNH7QO4Z.js";
|
|
104
116
|
import {
|
|
105
117
|
shouldColor
|
|
106
118
|
} from "./chunk-RNVYGWIC.js";
|
|
107
|
-
import "./chunk-MNH7QO4Z.js";
|
|
108
|
-
import "./chunk-6M5VJOC2.js";
|
|
109
119
|
import {
|
|
110
|
-
|
|
120
|
+
fail
|
|
121
|
+
} from "./chunk-YEUYKR62.js";
|
|
122
|
+
import "./chunk-OTJOBZJ5.js";
|
|
123
|
+
import {
|
|
124
|
+
notice,
|
|
125
|
+
warn
|
|
111
126
|
} from "./chunk-HX44GB4Z.js";
|
|
112
|
-
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";
|
|
113
140
|
import {
|
|
114
141
|
package_default
|
|
115
|
-
} from "./chunk-
|
|
142
|
+
} from "./chunk-DHGB4JBG.js";
|
|
116
143
|
import "./chunk-OWBRDNRZ.js";
|
|
117
144
|
import {
|
|
118
145
|
errorMessage
|
|
@@ -122,6 +149,143 @@ import "./chunk-2H7UOFLK.js";
|
|
|
122
149
|
// src/term/cli.ts
|
|
123
150
|
import { Command } from "commander";
|
|
124
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
|
+
|
|
125
289
|
// src/term/core/writers/documents.ts
|
|
126
290
|
import { join } from "node:path";
|
|
127
291
|
|
|
@@ -512,92 +676,179 @@ var jsonWriter = {
|
|
|
512
676
|
};
|
|
513
677
|
|
|
514
678
|
// src/term/core/writers/skos.ts
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
"narrower",
|
|
522
|
-
"related-terms",
|
|
523
|
-
"scope-note"
|
|
524
|
-
];
|
|
525
|
-
var CONTEXT = {
|
|
526
|
-
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,
|
|
527
685
|
dcterms: "http://purl.org/dc/terms/"
|
|
528
686
|
};
|
|
529
687
|
var SCHEME_ID = "";
|
|
530
|
-
|
|
531
|
-
|
|
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 };
|
|
532
700
|
}
|
|
533
701
|
function resolve(terms, self, value) {
|
|
534
702
|
const wanted = value.toLowerCase();
|
|
535
|
-
const others = terms.filter((t) => t !== self);
|
|
703
|
+
const others = terms.filter((t) => t.id !== self);
|
|
536
704
|
return others.find((t) => t.record.label.toLowerCase() === wanted) ?? others.find((t) => t.id.toLowerCase() === wanted);
|
|
537
705
|
}
|
|
538
|
-
function
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
const target = resolve(terms, self, value);
|
|
542
|
-
if (target !== void 0 && !ids.includes(target.id)) ids.push(target.id);
|
|
543
|
-
}
|
|
544
|
-
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;
|
|
545
709
|
}
|
|
546
|
-
function
|
|
547
|
-
|
|
548
|
-
const node = {
|
|
549
|
-
"@id": `#${term.id}`,
|
|
550
|
-
"@type": "skos:Concept",
|
|
551
|
-
"skos:inScheme": { "@id": SCHEME_ID },
|
|
552
|
-
"skos:prefLabel": literal(term, record.label)
|
|
553
|
-
};
|
|
554
|
-
if (record["alt-labels"] !== void 0) node["skos:altLabel"] = record["alt-labels"].map((v) => literal(term, v));
|
|
555
|
-
if (record["hidden-labels"] !== void 0) {
|
|
556
|
-
node["skos:hiddenLabel"] = record["hidden-labels"].map((v) => literal(term, v));
|
|
557
|
-
}
|
|
558
|
-
if (record.definition !== void 0) node["skos:definition"] = literal(term, record.definition);
|
|
559
|
-
if (record["scope-note"] !== void 0) node["skos:scopeNote"] = literal(term, record["scope-note"]);
|
|
560
|
-
const relations = [
|
|
561
|
-
["skos:broader", record.broader],
|
|
562
|
-
["skos:narrower", record.narrower],
|
|
563
|
-
["skos:related", record["related-terms"]]
|
|
564
|
-
];
|
|
565
|
-
for (const [key, values] of relations) {
|
|
566
|
-
const refs = references(terms, term, values);
|
|
567
|
-
if (refs.length > 0) node[key] = refs;
|
|
568
|
-
}
|
|
569
|
-
return node;
|
|
710
|
+
function pushUnique(values, value) {
|
|
711
|
+
if (!values.some((v) => sameValue(v, value))) values.push(value);
|
|
570
712
|
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
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);
|
|
587
732
|
};
|
|
588
|
-
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)}
|
|
589
794
|
`;
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
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
|
+
}
|
|
596
813
|
}
|
|
597
|
-
|
|
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);
|
|
598
840
|
|
|
599
841
|
// src/term/core/writers/tbx.ts
|
|
600
|
-
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
|
+
];
|
|
601
852
|
var HOLDS3 = TERM_FIELDS.filter((field) => !NOT_HELD.includes(field));
|
|
602
853
|
var LINGUIST_FIELDS = ["register", "reading", "reading-note", "grammatical-number", "transfer-comments"];
|
|
603
854
|
var ENTRY_INDENT = " ";
|
|
@@ -899,11 +1150,514 @@ var valeWriter = {
|
|
|
899
1150
|
};
|
|
900
1151
|
|
|
901
1152
|
// src/term/core/writers/interchange.ts
|
|
902
|
-
var INTERCHANGE_WRITERS = [tbxWriter, tbx3Writer, skosWriter, csvWriter, jsonWriter, valeWriter];
|
|
1153
|
+
var INTERCHANGE_WRITERS = [tbxWriter, tbx3Writer, skosWriter, skosTtlWriter, csvWriter, jsonWriter, valeWriter];
|
|
903
1154
|
|
|
904
1155
|
// src/term/core/writers/index.ts
|
|
905
1156
|
var TERM_WRITERS = [...DOCUMENT_WRITERS, ...INTERCHANGE_WRITERS];
|
|
906
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
|
+
|
|
907
1661
|
// src/term/commands/formats.ts
|
|
908
1662
|
var FORMATS_FORMATS = ["pretty", "json"];
|
|
909
1663
|
var DOCUMENT_RENDERS = {
|
|
@@ -919,12 +1673,14 @@ var INTERCHANGE_LABELS = {
|
|
|
919
1673
|
tbx: "TBX v2",
|
|
920
1674
|
tbx3: "TBX v3",
|
|
921
1675
|
skos: "JSON-LD",
|
|
1676
|
+
"skos-ttl": "Turtle",
|
|
922
1677
|
vale: "style"
|
|
923
1678
|
};
|
|
924
1679
|
function rendered(writers, format, construct) {
|
|
925
1680
|
return writers.some((writer) => {
|
|
926
1681
|
const render = DOCUMENT_RENDERS[writer.format];
|
|
927
|
-
if (render
|
|
1682
|
+
if (render === void 0) return writer.format === format;
|
|
1683
|
+
if (render.input !== format) return false;
|
|
928
1684
|
return writer.shapes.some((shape) => render.shapes[shape] === construct);
|
|
929
1685
|
});
|
|
930
1686
|
}
|
|
@@ -998,9 +1754,9 @@ async function runGet(opts) {
|
|
|
998
1754
|
}
|
|
999
1755
|
|
|
1000
1756
|
// src/term/core/lint.ts
|
|
1001
|
-
import { mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
1757
|
+
import { mkdtemp, rm, writeFile as writeFile2 } from "node:fs/promises";
|
|
1002
1758
|
import { tmpdir } from "node:os";
|
|
1003
|
-
import { join as
|
|
1759
|
+
import { join as join4 } from "node:path";
|
|
1004
1760
|
|
|
1005
1761
|
// src/term/core/vale.ts
|
|
1006
1762
|
import { execFile } from "node:child_process";
|
|
@@ -1188,9 +1944,9 @@ async function lintTermSet(set, opts = {}) {
|
|
|
1188
1944
|
}
|
|
1189
1945
|
if (files.length === 0) return [];
|
|
1190
1946
|
const runVale = opts.runVale ?? runValeJson;
|
|
1191
|
-
const dir = await mkdtemp(
|
|
1947
|
+
const dir = await mkdtemp(join4(tmpdir(), "manni-term-lint-"));
|
|
1192
1948
|
try {
|
|
1193
|
-
for (const file of files) await
|
|
1949
|
+
for (const file of files) await writeFile2(join4(dir, file.name), file.content, "utf8");
|
|
1194
1950
|
const alerts = await runVale([dir], { config: opts.valeConfig, cwd: opts.cwd });
|
|
1195
1951
|
const findings = [];
|
|
1196
1952
|
for (const [path, list] of Object.entries(alerts)) {
|
|
@@ -1240,9 +1996,9 @@ async function runLint(opts) {
|
|
|
1240
1996
|
}
|
|
1241
1997
|
|
|
1242
1998
|
// src/term/commands/write.ts
|
|
1243
|
-
import { existsSync, statSync } from "node:fs";
|
|
1244
|
-
import { lstat, mkdir, readdir, readFile, rm as rm2, writeFile as
|
|
1245
|
-
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";
|
|
1246
2002
|
var SUGGESTED_SECTION = "*.md";
|
|
1247
2003
|
var STYLE2 = "Terms";
|
|
1248
2004
|
function writeFormats(writers = TERM_WRITERS) {
|
|
@@ -1264,11 +2020,11 @@ async function filesUnder(dir, into) {
|
|
|
1264
2020
|
return;
|
|
1265
2021
|
}
|
|
1266
2022
|
for (const entry of entries2) {
|
|
1267
|
-
const path =
|
|
2023
|
+
const path = join5(dir, entry.name);
|
|
1268
2024
|
if (entry.isDirectory()) await filesUnder(path, into);
|
|
1269
2025
|
else if (entry.isFile()) {
|
|
1270
2026
|
const { size } = await lstat(path);
|
|
1271
|
-
into.set(path, size > MAX_EXISTING_FILE_BYTES ? "" : await
|
|
2027
|
+
into.set(path, size > MAX_EXISTING_FILE_BYTES ? "" : await readFile2(path, "utf8"));
|
|
1272
2028
|
}
|
|
1273
2029
|
}
|
|
1274
2030
|
}
|
|
@@ -1276,8 +2032,8 @@ async function existingFor(target) {
|
|
|
1276
2032
|
const existing = /* @__PURE__ */ new Map();
|
|
1277
2033
|
if (target.shape === "directory") {
|
|
1278
2034
|
await filesUnder(target.path, existing);
|
|
1279
|
-
} else if (
|
|
1280
|
-
existing.set(target.path, await
|
|
2035
|
+
} else if (existsSync2(target.path) && !isDirectory(target.path)) {
|
|
2036
|
+
existing.set(target.path, await readFile2(target.path, "utf8"));
|
|
1281
2037
|
}
|
|
1282
2038
|
return existing;
|
|
1283
2039
|
}
|
|
@@ -1296,23 +2052,23 @@ function droppedFrom(format, shape, readers) {
|
|
|
1296
2052
|
async function applyChanges(files, removals, existing, cwd, write) {
|
|
1297
2053
|
const changes = [];
|
|
1298
2054
|
for (const file of files) {
|
|
1299
|
-
const before = existing.get(file.path) ?? (
|
|
2055
|
+
const before = existing.get(file.path) ?? (existsSync2(file.path) ? await readFile2(file.path, "utf8") : void 0);
|
|
1300
2056
|
if (before === file.content) continue;
|
|
1301
2057
|
changes.push({ path: displayPath(file.path, cwd), action: before === void 0 ? "create" : "change" });
|
|
1302
2058
|
if (write) {
|
|
1303
|
-
await
|
|
1304
|
-
await
|
|
2059
|
+
await mkdir2(dirname3(file.path), { recursive: true });
|
|
2060
|
+
await writeFile3(file.path, file.content, "utf8");
|
|
1305
2061
|
}
|
|
1306
2062
|
}
|
|
1307
2063
|
for (const path of removals) {
|
|
1308
|
-
if (!
|
|
2064
|
+
if (!existsSync2(path)) continue;
|
|
1309
2065
|
changes.push({ path: displayPath(path, cwd), action: "remove" });
|
|
1310
2066
|
if (write) await rm2(path, { force: true });
|
|
1311
2067
|
}
|
|
1312
2068
|
return changes;
|
|
1313
2069
|
}
|
|
1314
2070
|
async function runWrite(opts) {
|
|
1315
|
-
const cwd =
|
|
2071
|
+
const cwd = resolve3(opts.cwd ?? process.cwd());
|
|
1316
2072
|
const writers = opts.writers ?? TERM_WRITERS;
|
|
1317
2073
|
const readers = opts.readers ?? TERM_READERS;
|
|
1318
2074
|
const check = opts.check === true;
|
|
@@ -1340,19 +2096,19 @@ async function runWrite(opts) {
|
|
|
1340
2096
|
"Vale found no config file. Set tools.vale.config in manni.config.yaml, or pass -o <styles directory>."
|
|
1341
2097
|
);
|
|
1342
2098
|
}
|
|
1343
|
-
targetPath =
|
|
2099
|
+
targetPath = resolve3(cwd, resolved.stylesPath);
|
|
1344
2100
|
if (!Object.values(resolved.baseStyles).some((styles) => styles.includes(STYLE2))) {
|
|
1345
2101
|
const first = Object.entries(resolved.baseStyles)[0];
|
|
1346
2102
|
const [section, styles] = first ?? [SUGGESTED_SECTION, []];
|
|
1347
2103
|
wiring = {
|
|
1348
|
-
rootIni: displayPath(
|
|
2104
|
+
rootIni: displayPath(resolve3(cwd, resolved.rootIni), cwd),
|
|
1349
2105
|
section,
|
|
1350
2106
|
styles: [...styles, STYLE2],
|
|
1351
2107
|
addSection: first === void 0
|
|
1352
2108
|
};
|
|
1353
2109
|
}
|
|
1354
2110
|
} else {
|
|
1355
|
-
targetPath =
|
|
2111
|
+
targetPath = resolve3(cwd, opts.out);
|
|
1356
2112
|
}
|
|
1357
2113
|
const shape = format === "vale" || /[\\/]$/.test(opts.out ?? "") || isDirectory(targetPath) ? "directory" : "file";
|
|
1358
2114
|
const target = { path: targetPath, shape };
|
|
@@ -1365,7 +2121,7 @@ async function runWrite(opts) {
|
|
|
1365
2121
|
throw error;
|
|
1366
2122
|
}
|
|
1367
2123
|
const changes = await applyChanges(render.files, render.removals, existing, cwd, !check && !dryRun);
|
|
1368
|
-
const shown = format === "vale" ? displayPath(
|
|
2124
|
+
const shown = format === "vale" ? displayPath(join5(targetPath, STYLE2), cwd) : opts.out ?? displayPath(targetPath, cwd);
|
|
1369
2125
|
return {
|
|
1370
2126
|
mode: "render",
|
|
1371
2127
|
format,
|
|
@@ -1392,7 +2148,7 @@ function inputFor(content, path, construct, file) {
|
|
|
1392
2148
|
return { content, file, path, format: MANIFEST_FORMAT, metadata: {}, lineFor: () => void 0 };
|
|
1393
2149
|
}
|
|
1394
2150
|
if (construct === "tbx-entry") return tbxInput(content, file, path);
|
|
1395
|
-
const extractor = extractorForExtension(
|
|
2151
|
+
const extractor = extractorForExtension(extname3(path));
|
|
1396
2152
|
if (extractor === void 0) throw new TermError(`${file}: no reader for its extension.`);
|
|
1397
2153
|
return extractInput(content, file, path, extractor.name);
|
|
1398
2154
|
}
|
|
@@ -1425,6 +2181,11 @@ async function writeInPlace(opts, check, dryRun) {
|
|
|
1425
2181
|
if (path === void 0) {
|
|
1426
2182
|
throw new TermError(`${term.location.file} has nowhere to write back to. Pass -f <format> -o <path>.`);
|
|
1427
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
|
+
}
|
|
1428
2189
|
const reader = readerForConstruct(construct, readers);
|
|
1429
2190
|
if (reader?.apply === void 0) {
|
|
1430
2191
|
const name = reader?.label ?? construct;
|
|
@@ -1442,7 +2203,7 @@ async function writeInPlace(opts, check, dryRun) {
|
|
|
1442
2203
|
for (const [path, { file, constructs }] of byPath) {
|
|
1443
2204
|
let original;
|
|
1444
2205
|
try {
|
|
1445
|
-
original = await
|
|
2206
|
+
original = await readFile2(path, "utf8");
|
|
1446
2207
|
} catch (error) {
|
|
1447
2208
|
throw new TermError(`${file}: could not be read: ${errorMessage(error)}`);
|
|
1448
2209
|
}
|
|
@@ -1486,16 +2247,28 @@ function renderListCsv(terms) {
|
|
|
1486
2247
|
var INFORMATION_URI = "https://hawkeyexl.github.io/manni/term/";
|
|
1487
2248
|
var RULES_URI = "https://hawkeyexl.github.io/manni/term/reference/rules/";
|
|
1488
2249
|
var RULE_DESCRIPTIONS = {
|
|
1489
|
-
"undefined-term": "A page's concepts: names
|
|
2250
|
+
"undefined-term": "A page's concepts: names no entry, by label, id or alt-label.",
|
|
1490
2251
|
"duplicate-id": "Two entries share an id.",
|
|
1491
2252
|
"label-collision": "Two entries claim the same preferred label, ignoring case.",
|
|
1492
2253
|
"alt-label-collision": "An entry's alt-label is another entry's preferred label, ignoring case.",
|
|
1493
2254
|
"dangling-reference": "A value of broader, narrower, related-terms or see names no entry, by label or by id.",
|
|
1494
2255
|
"broader-cycle": "A chain of broader returns to where it started.",
|
|
1495
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.",
|
|
1496
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.",
|
|
1497
2261
|
"abstract-too-long": "An abstract is longer than term.abstractMaxLength.",
|
|
1498
|
-
"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."
|
|
1499
2272
|
};
|
|
1500
2273
|
var PROSE_PREFIX = `${RULE_ID_PREFIX}/prose/`;
|
|
1501
2274
|
var FIELD_LABEL = new RegExp(`^(?:\\(root\\)|/(?:${TERM_FIELDS.join("|")})) `);
|
|
@@ -1532,21 +2305,53 @@ function renderFindingsJunit(report) {
|
|
|
1532
2305
|
);
|
|
1533
2306
|
}
|
|
1534
2307
|
|
|
1535
|
-
// src/term/
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
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);
|
|
1546
2345
|
}
|
|
1547
2346
|
|
|
1548
2347
|
// src/term/cli.ts
|
|
1549
|
-
|
|
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
|
+
}
|
|
1550
2355
|
function colorFor(options) {
|
|
1551
2356
|
return shouldColor({ noColor: !options.color, isTTY: process.stdout.isTTY });
|
|
1552
2357
|
}
|
|
@@ -1571,11 +2376,11 @@ function print(text) {
|
|
|
1571
2376
|
process.stdout.write(`${text}
|
|
1572
2377
|
`);
|
|
1573
2378
|
}
|
|
1574
|
-
function renderFindings(report, format, options,
|
|
2379
|
+
function renderFindings(report, format, options, references) {
|
|
1575
2380
|
let text;
|
|
1576
2381
|
switch (format) {
|
|
1577
2382
|
case "pretty":
|
|
1578
|
-
text = renderFindingsPretty(report, { color: colorFor(options), references
|
|
2383
|
+
text = renderFindingsPretty(report, { color: colorFor(options), references });
|
|
1579
2384
|
break;
|
|
1580
2385
|
case "json":
|
|
1581
2386
|
text = renderFindingsJson(report);
|
|
@@ -1700,6 +2505,44 @@ function buildProgram() {
|
|
|
1700
2505
|
fail(err);
|
|
1701
2506
|
}
|
|
1702
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
|
+
});
|
|
1703
2546
|
program.command("formats").description("List the constructs read and written, per format").option("-f, --format <format>", `output: ${FORMATS_FORMATS.join(" | ")}`, "pretty").action((options) => {
|
|
1704
2547
|
try {
|
|
1705
2548
|
const format = formatChoice(options.format, FORMATS_FORMATS);
|
|
@@ -1717,4 +2560,4 @@ export {
|
|
|
1717
2560
|
TermError,
|
|
1718
2561
|
buildProgram
|
|
1719
2562
|
};
|
|
1720
|
-
//# sourceMappingURL=term-
|
|
2563
|
+
//# sourceMappingURL=term-D2N7UN4P.js.map
|