@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.
Files changed (243) hide show
  1. package/README.md +1 -1
  2. package/dist/batch-EFSFG6GC.js +46 -0
  3. package/dist/build-NIO3UIWJ.js +36 -0
  4. package/dist/calibrate-6VO7URRV.js +41 -0
  5. package/dist/capture-NMBVJO3C.js +38 -0
  6. package/dist/check-SHOYX2B5.js +30 -0
  7. package/dist/check-XMJKH3KV.js +34 -0
  8. package/dist/{check-NLL4NRYA.js → check-Y62BJNC4.js} +35 -31
  9. package/dist/{check-NLL4NRYA.js.map → check-Y62BJNC4.js.map} +1 -1
  10. package/dist/{check-7B77ZD2N.js → check-ZMO3ZLMW.js} +19 -15
  11. package/dist/{chunk-PK7EKJ5T.js → chunk-24AJK2RG.js} +5 -10
  12. package/dist/chunk-24AJK2RG.js.map +1 -0
  13. package/dist/chunk-2OZF2VUB.js +164 -0
  14. package/dist/chunk-2OZF2VUB.js.map +1 -0
  15. package/dist/chunk-2UJZXVHR.js +1868 -0
  16. package/dist/chunk-2UJZXVHR.js.map +1 -0
  17. package/dist/{chunk-DNZUBCGZ.js → chunk-3BRJCQPY.js} +36 -7
  18. package/dist/chunk-3BRJCQPY.js.map +1 -0
  19. package/dist/{chunk-D2UW3ZCK.js → chunk-42VFJOAF.js} +13 -11
  20. package/dist/{chunk-D2UW3ZCK.js.map → chunk-42VFJOAF.js.map} +1 -1
  21. package/dist/{chunk-LQZQ5KGG.js → chunk-4Q24OYI3.js} +7 -7
  22. package/dist/{chunk-XU73V5XT.js → chunk-4WJTURRO.js} +15 -15
  23. package/dist/{chunk-WN47MNSK.js → chunk-5SID2SVL.js} +4 -4
  24. package/dist/{chunk-5REEVKGH.js → chunk-AANUY4BH.js} +2 -2
  25. package/dist/chunk-ANPIIYRH.js +2272 -0
  26. package/dist/chunk-ANPIIYRH.js.map +1 -0
  27. package/dist/{chunk-RZVCWX5R.js → chunk-AYVKN3PG.js} +4 -4
  28. package/dist/{chunk-2UCC26MO.js → chunk-CH6IOGXV.js} +9 -9
  29. package/dist/{chunk-RODZ7MB7.js → chunk-D5Z6B4M7.js} +6 -6
  30. package/dist/{chunk-IJ62BB2T.js → chunk-D6SELXQ2.js} +7 -7
  31. package/dist/{chunk-2JV7C4YV.js → chunk-DDILEF5F.js} +890 -1399
  32. package/dist/chunk-DDILEF5F.js.map +1 -0
  33. package/dist/{chunk-3E2X2RBU.js → chunk-DGRLHDM4.js} +9 -9
  34. package/dist/{chunk-2BV4FBC7.js → chunk-DHGB4JBG.js} +4 -3
  35. package/dist/chunk-DHGB4JBG.js.map +1 -0
  36. package/dist/{chunk-6LR73NMO.js → chunk-DLU5FCFT.js} +30 -28
  37. package/dist/chunk-DLU5FCFT.js.map +1 -0
  38. package/dist/chunk-DSWKBZWW.js +16 -0
  39. package/dist/chunk-DSWKBZWW.js.map +1 -0
  40. package/dist/{chunk-BD7IXBWE.js → chunk-F564FHMQ.js} +8 -8
  41. package/dist/{chunk-ABHG6I3G.js → chunk-FKAZUZQU.js} +469 -85
  42. package/dist/chunk-FKAZUZQU.js.map +1 -0
  43. package/dist/{chunk-DFCQ6BMI.js → chunk-G3MBUL5M.js} +4 -4
  44. package/dist/{chunk-SUTMSDQ2.js → chunk-GQ3KRY3B.js} +3 -3
  45. package/dist/chunk-HDPN46JP.js +393 -0
  46. package/dist/chunk-HDPN46JP.js.map +1 -0
  47. package/dist/{chunk-EAUIQADY.js → chunk-IQQAJROD.js} +6 -6
  48. package/dist/{chunk-ZHRPH52H.js → chunk-IZXN3WI6.js} +2 -2
  49. package/dist/{chunk-NCPWXHDO.js → chunk-JEUFYSFQ.js} +4 -4
  50. package/dist/{chunk-G6FNWRAI.js → chunk-JSSM7VVV.js} +4 -4
  51. package/dist/{chunk-CCWMACJL.js → chunk-KFGZPVFA.js} +229 -821
  52. package/dist/chunk-KFGZPVFA.js.map +1 -0
  53. package/dist/{chunk-H26VDFDS.js → chunk-KGFSPJLD.js} +2 -2
  54. package/dist/{chunk-AO5TSDKT.js → chunk-KMORGMCW.js} +7 -7
  55. package/dist/{chunk-WQWKYAAK.js → chunk-NUQF5F5J.js} +2 -2
  56. package/dist/{chunk-2YJ5H5E6.js → chunk-NZ6KSHFD.js} +23 -21
  57. package/dist/{chunk-2YJ5H5E6.js.map → chunk-NZ6KSHFD.js.map} +1 -1
  58. package/dist/{chunk-7Y3N4Y72.js → chunk-OHUDZRLK.js} +3 -3
  59. package/dist/{chunk-GCKHSBEN.js → chunk-OKMTUAWO.js} +4 -4
  60. package/dist/{chunk-6M5VJOC2.js → chunk-OTJOBZJ5.js} +167 -166
  61. package/dist/chunk-OTJOBZJ5.js.map +1 -0
  62. package/dist/{chunk-2W34HX2U.js → chunk-PS257NIU.js} +288 -373
  63. package/dist/chunk-PS257NIU.js.map +1 -0
  64. package/dist/chunk-QDC7JPFG.js +685 -0
  65. package/dist/chunk-QDC7JPFG.js.map +1 -0
  66. package/dist/chunk-QEAGL4V5.js +3185 -0
  67. package/dist/chunk-QEAGL4V5.js.map +1 -0
  68. package/dist/{chunk-GB2XPITA.js → chunk-QMY57PVW.js} +2 -2
  69. package/dist/{chunk-55GMOVKW.js → chunk-QNDDPXFR.js} +2 -2
  70. package/dist/{chunk-GXN7RRHR.js → chunk-QSIXNTRV.js} +4 -4
  71. package/dist/{chunk-G7XD4QH5.js → chunk-RGLFV4KO.js} +11372 -10218
  72. package/dist/chunk-RGLFV4KO.js.map +1 -0
  73. package/dist/{chunk-QBVP3SQP.js → chunk-SGR7ZAVE.js} +13 -7
  74. package/dist/chunk-SGR7ZAVE.js.map +1 -0
  75. package/dist/{chunk-KBG463UK.js → chunk-SMHAYK6I.js} +2409 -5243
  76. package/dist/chunk-SMHAYK6I.js.map +1 -0
  77. package/dist/{chunk-XG6PVB5S.js → chunk-SSQZB5SQ.js} +1 -11
  78. package/dist/chunk-SSQZB5SQ.js.map +1 -0
  79. package/dist/{chunk-GDLHTI5R.js → chunk-STPGIKPY.js} +8 -2
  80. package/dist/chunk-STPGIKPY.js.map +1 -0
  81. package/dist/{chunk-QJRQ4BRC.js → chunk-U22TOL5Y.js} +17 -17
  82. package/dist/{chunk-NGTVREIH.js → chunk-U6IHLEWT.js} +2 -2
  83. package/dist/{chunk-Z5YHMRLF.js → chunk-UUCCV3SI.js} +2 -2
  84. package/dist/{chunk-ZXXFP2LA.js → chunk-UXMCHBOJ.js} +2 -2
  85. package/dist/{chunk-VZVEP2OZ.js → chunk-VFAKGIDG.js} +2 -2
  86. package/dist/{chunk-QCHVR4ZM.js → chunk-VM7VAFJW.js} +33 -7
  87. package/dist/chunk-VM7VAFJW.js.map +1 -0
  88. package/dist/{chunk-VQK4VHLF.js → chunk-YQV75FIL.js} +2 -2
  89. package/dist/chunk-YUTVAMWW.js +2 -0
  90. package/dist/chunk-ZPLVANY2.js +15 -0
  91. package/dist/chunk-ZPLVANY2.js.map +1 -0
  92. package/dist/{cli-BIIUKPTE.js → cli-4CR7QIOK.js} +26 -22
  93. package/dist/{cli-BIIUKPTE.js.map → cli-4CR7QIOK.js.map} +1 -1
  94. package/dist/{cli-V2DI3K2R.js → cli-6R4W3HAH.js} +37 -33
  95. package/dist/{cli-V2DI3K2R.js.map → cli-6R4W3HAH.js.map} +1 -1
  96. package/dist/{cli-HO62TOM2.js → cli-BOMA2FMP.js} +14 -11
  97. package/dist/{cli-EH3I4IUX.js → cli-EDQPQOCE.js} +47 -41
  98. package/dist/cli-EDQPQOCE.js.map +1 -0
  99. package/dist/{cli-P2X7PNY6.js → cli-GBF76EXT.js} +25 -20
  100. package/dist/{cli-P2X7PNY6.js.map → cli-GBF76EXT.js.map} +1 -1
  101. package/dist/{cli-4YYC6LCY.js → cli-MQYCF3SR.js} +27 -23
  102. package/dist/{cli-4YYC6LCY.js.map → cli-MQYCF3SR.js.map} +1 -1
  103. package/dist/{cli-UETKXHJN.js → cli-OJKFXQOM.js} +9 -9
  104. package/dist/{cli-LWST5FQH.js → cli-PHZAO4LZ.js} +4 -4
  105. package/dist/{cli-TELPAMJO.js → cli-PTKFFNOW.js} +59 -35
  106. package/dist/cli-PTKFFNOW.js.map +1 -0
  107. package/dist/{cli-SGVFZOAW.js → cli-UW2K5Z5J.js} +34 -29
  108. package/dist/{cli-SGVFZOAW.js.map → cli-UW2K5Z5J.js.map} +1 -1
  109. package/dist/cli-XXTNPPKB.js +83 -0
  110. package/dist/cli-XXTNPPKB.js.map +1 -0
  111. package/dist/cli.js +24 -12
  112. package/dist/cli.js.map +1 -1
  113. package/dist/{config-TYXYQK3I.js → config-JJW75SBX.js} +5 -5
  114. package/dist/docmeta.js +13 -10
  115. package/dist/docmeta.js.map +1 -1
  116. package/dist/github-6VQKSB67.js +35 -0
  117. package/dist/github-RBSEM7ZK.js +30 -0
  118. package/dist/graph/runtime.d.ts +4 -1
  119. package/dist/graph/runtime.js +20 -9
  120. package/dist/graph/runtime.js.map +1 -1
  121. package/dist/{host-6GURH5HE.js → host-YSTYO5DX.js} +3 -3
  122. package/dist/index.d.ts +1214 -940
  123. package/dist/index.js +190 -160
  124. package/dist/index.js.map +1 -1
  125. package/dist/{json-QR4G35KA.js → json-PU2HLHDQ.js} +18 -14
  126. package/dist/labels-SJNSOPBI.js +73 -0
  127. package/dist/labels-SJNSOPBI.js.map +1 -0
  128. package/dist/lint-KIVTHLGU.js +34 -0
  129. package/dist/list-RDEJDDJF.js +32 -0
  130. package/dist/list-SUTDWL2J.js +35 -0
  131. package/dist/{page-FSXDXCDD.js → page-UMAA3NCM.js} +18 -13
  132. package/dist/{prepare-UPIBTFNS.js → prepare-3I3LOXXD.js} +24 -20
  133. package/dist/{prepare-UPIBTFNS.js.map → prepare-3I3LOXXD.js.map} +1 -1
  134. package/dist/{pretty-4IONWSEP.js → pretty-ANLRHU4O.js} +18 -14
  135. package/dist/{pretty-R4BQD2VH.js → pretty-Q3ZFKOR7.js} +18 -14
  136. package/dist/{provider-527CO4DM.js → provider-LBX4IXGX.js} +3 -3
  137. package/dist/{release-3D5PK6M7.js → release-VV3UTKE5.js} +3 -3
  138. package/dist/{reporters-M6LJ2IYU.js → reporters-26H3N2KW.js} +3 -3
  139. package/dist/{reporters-DHO2BXAD.js → reporters-ILT36CIH.js} +7 -7
  140. package/dist/{reporters-FPP6JNDP.js → reporters-PNDLWT6K.js} +16 -12
  141. package/dist/run-QXCK33Z4.js +37 -0
  142. package/dist/{term-ASM4LVYC.js → term-D2N7UN4P.js} +981 -138
  143. package/dist/term-D2N7UN4P.js.map +1 -0
  144. package/dist/validate-BRUCOT2O.js +19 -0
  145. package/dist/validate-BRUCOT2O.js.map +1 -0
  146. package/package.json +3 -2
  147. package/plugin/manni/.claude-plugin/plugin.json +1 -1
  148. package/shapes/graph/shapes-1.1.0.ttl +785 -0
  149. package/dist/batch-6NICDKRE.js +0 -41
  150. package/dist/build-3KP2K3XN.js +0 -32
  151. package/dist/calibrate-LUA3DWKD.js +0 -36
  152. package/dist/capture-NETOHCB4.js +0 -34
  153. package/dist/check-E4QCB7LS.js +0 -20
  154. package/dist/check-PTECPIIB.js +0 -26
  155. package/dist/chunk-2BV4FBC7.js.map +0 -1
  156. package/dist/chunk-2JV7C4YV.js.map +0 -1
  157. package/dist/chunk-2W34HX2U.js.map +0 -1
  158. package/dist/chunk-4DLF5SA4.js +0 -392
  159. package/dist/chunk-4DLF5SA4.js.map +0 -1
  160. package/dist/chunk-6AGESHHM.js +0 -387
  161. package/dist/chunk-6AGESHHM.js.map +0 -1
  162. package/dist/chunk-6LR73NMO.js.map +0 -1
  163. package/dist/chunk-6M5VJOC2.js.map +0 -1
  164. package/dist/chunk-ABHG6I3G.js.map +0 -1
  165. package/dist/chunk-CCWMACJL.js.map +0 -1
  166. package/dist/chunk-DNZUBCGZ.js.map +0 -1
  167. package/dist/chunk-G7XD4QH5.js.map +0 -1
  168. package/dist/chunk-GDLHTI5R.js.map +0 -1
  169. package/dist/chunk-KBG463UK.js.map +0 -1
  170. package/dist/chunk-PK7EKJ5T.js.map +0 -1
  171. package/dist/chunk-QBVP3SQP.js.map +0 -1
  172. package/dist/chunk-QCHVR4ZM.js.map +0 -1
  173. package/dist/chunk-VVVKBUBO.js +0 -818
  174. package/dist/chunk-VVVKBUBO.js.map +0 -1
  175. package/dist/chunk-XG6PVB5S.js.map +0 -1
  176. package/dist/cli-EH3I4IUX.js.map +0 -1
  177. package/dist/cli-TELPAMJO.js.map +0 -1
  178. package/dist/github-ESK45CEZ.js +0 -26
  179. package/dist/github-WER7JUTN.js +0 -31
  180. package/dist/lint-QTI7XK2A.js +0 -30
  181. package/dist/list-JO4G3TS3.js +0 -30
  182. package/dist/list-O2MJUP5V.js +0 -28
  183. package/dist/run-YH5Z7RJ7.js +0 -32
  184. package/dist/term-ASM4LVYC.js.map +0 -1
  185. package/dist/validate-7JI3H57P.js +0 -17
  186. /package/dist/{batch-6NICDKRE.js.map → batch-EFSFG6GC.js.map} +0 -0
  187. /package/dist/{build-3KP2K3XN.js.map → build-NIO3UIWJ.js.map} +0 -0
  188. /package/dist/{calibrate-LUA3DWKD.js.map → calibrate-6VO7URRV.js.map} +0 -0
  189. /package/dist/{capture-NETOHCB4.js.map → capture-NMBVJO3C.js.map} +0 -0
  190. /package/dist/{check-7B77ZD2N.js.map → check-SHOYX2B5.js.map} +0 -0
  191. /package/dist/{check-E4QCB7LS.js.map → check-XMJKH3KV.js.map} +0 -0
  192. /package/dist/{check-PTECPIIB.js.map → check-ZMO3ZLMW.js.map} +0 -0
  193. /package/dist/{chunk-LQZQ5KGG.js.map → chunk-4Q24OYI3.js.map} +0 -0
  194. /package/dist/{chunk-XU73V5XT.js.map → chunk-4WJTURRO.js.map} +0 -0
  195. /package/dist/{chunk-WN47MNSK.js.map → chunk-5SID2SVL.js.map} +0 -0
  196. /package/dist/{chunk-5REEVKGH.js.map → chunk-AANUY4BH.js.map} +0 -0
  197. /package/dist/{chunk-RZVCWX5R.js.map → chunk-AYVKN3PG.js.map} +0 -0
  198. /package/dist/{chunk-2UCC26MO.js.map → chunk-CH6IOGXV.js.map} +0 -0
  199. /package/dist/{chunk-RODZ7MB7.js.map → chunk-D5Z6B4M7.js.map} +0 -0
  200. /package/dist/{chunk-IJ62BB2T.js.map → chunk-D6SELXQ2.js.map} +0 -0
  201. /package/dist/{chunk-3E2X2RBU.js.map → chunk-DGRLHDM4.js.map} +0 -0
  202. /package/dist/{chunk-BD7IXBWE.js.map → chunk-F564FHMQ.js.map} +0 -0
  203. /package/dist/{chunk-DFCQ6BMI.js.map → chunk-G3MBUL5M.js.map} +0 -0
  204. /package/dist/{chunk-SUTMSDQ2.js.map → chunk-GQ3KRY3B.js.map} +0 -0
  205. /package/dist/{chunk-EAUIQADY.js.map → chunk-IQQAJROD.js.map} +0 -0
  206. /package/dist/{chunk-ZHRPH52H.js.map → chunk-IZXN3WI6.js.map} +0 -0
  207. /package/dist/{chunk-NCPWXHDO.js.map → chunk-JEUFYSFQ.js.map} +0 -0
  208. /package/dist/{chunk-G6FNWRAI.js.map → chunk-JSSM7VVV.js.map} +0 -0
  209. /package/dist/{chunk-H26VDFDS.js.map → chunk-KGFSPJLD.js.map} +0 -0
  210. /package/dist/{chunk-AO5TSDKT.js.map → chunk-KMORGMCW.js.map} +0 -0
  211. /package/dist/{chunk-WQWKYAAK.js.map → chunk-NUQF5F5J.js.map} +0 -0
  212. /package/dist/{chunk-7Y3N4Y72.js.map → chunk-OHUDZRLK.js.map} +0 -0
  213. /package/dist/{chunk-GCKHSBEN.js.map → chunk-OKMTUAWO.js.map} +0 -0
  214. /package/dist/{chunk-GB2XPITA.js.map → chunk-QMY57PVW.js.map} +0 -0
  215. /package/dist/{chunk-55GMOVKW.js.map → chunk-QNDDPXFR.js.map} +0 -0
  216. /package/dist/{chunk-GXN7RRHR.js.map → chunk-QSIXNTRV.js.map} +0 -0
  217. /package/dist/{chunk-QJRQ4BRC.js.map → chunk-U22TOL5Y.js.map} +0 -0
  218. /package/dist/{chunk-NGTVREIH.js.map → chunk-U6IHLEWT.js.map} +0 -0
  219. /package/dist/{chunk-Z5YHMRLF.js.map → chunk-UUCCV3SI.js.map} +0 -0
  220. /package/dist/{chunk-ZXXFP2LA.js.map → chunk-UXMCHBOJ.js.map} +0 -0
  221. /package/dist/{chunk-VZVEP2OZ.js.map → chunk-VFAKGIDG.js.map} +0 -0
  222. /package/dist/{chunk-VQK4VHLF.js.map → chunk-YQV75FIL.js.map} +0 -0
  223. /package/dist/{cli-HO62TOM2.js.map → chunk-YUTVAMWW.js.map} +0 -0
  224. /package/dist/{config-TYXYQK3I.js.map → cli-BOMA2FMP.js.map} +0 -0
  225. /package/dist/{cli-UETKXHJN.js.map → cli-OJKFXQOM.js.map} +0 -0
  226. /package/dist/{cli-LWST5FQH.js.map → cli-PHZAO4LZ.js.map} +0 -0
  227. /package/dist/{github-ESK45CEZ.js.map → config-JJW75SBX.js.map} +0 -0
  228. /package/dist/{github-WER7JUTN.js.map → github-6VQKSB67.js.map} +0 -0
  229. /package/dist/{host-6GURH5HE.js.map → github-RBSEM7ZK.js.map} +0 -0
  230. /package/dist/{json-QR4G35KA.js.map → host-YSTYO5DX.js.map} +0 -0
  231. /package/dist/{lint-QTI7XK2A.js.map → json-PU2HLHDQ.js.map} +0 -0
  232. /package/dist/{list-JO4G3TS3.js.map → lint-KIVTHLGU.js.map} +0 -0
  233. /package/dist/{list-O2MJUP5V.js.map → list-RDEJDDJF.js.map} +0 -0
  234. /package/dist/{page-FSXDXCDD.js.map → list-SUTDWL2J.js.map} +0 -0
  235. /package/dist/{pretty-4IONWSEP.js.map → page-UMAA3NCM.js.map} +0 -0
  236. /package/dist/{pretty-R4BQD2VH.js.map → pretty-ANLRHU4O.js.map} +0 -0
  237. /package/dist/{provider-527CO4DM.js.map → pretty-Q3ZFKOR7.js.map} +0 -0
  238. /package/dist/{reporters-DHO2BXAD.js.map → provider-LBX4IXGX.js.map} +0 -0
  239. /package/dist/{release-3D5PK6M7.js.map → release-VV3UTKE5.js.map} +0 -0
  240. /package/dist/{reporters-FPP6JNDP.js.map → reporters-26H3N2KW.js.map} +0 -0
  241. /package/dist/{reporters-M6LJ2IYU.js.map → reporters-ILT36CIH.js.map} +0 -0
  242. /package/dist/{run-YH5Z7RJ7.js.map → reporters-PNDLWT6K.js.map} +0 -0
  243. /package/dist/{validate-7JI3H57P.js.map → run-QXCK33Z4.js.map} +0 -0
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/lint/cli.ts"],"sourcesContent":["/**\n * The lint program. Named `lint` because that is where it is mounted\n * (`manni lint …`); `src/cli.ts` adds it to the umbrella and runs it. Thin\n * commander wrapper over the command cores. Follows clig.dev: primary output to\n * stdout, diagnostics to stderr, color only on a TTY (and never under\n * NO_COLOR/--no-color), meaningful exit codes.\n *\n * Grammar per proposal 0034: the verbs are `check`, `structure`, `templates`\n * and `tools`, and there is no default subcommand, so a bare `manni lint` is a\n * usage error that lists them. `check` runs every configured job; `structure`\n * runs one of them, and carries the options that belong to the tool performing\n * it.\n *\n * Exit codes are the contract CI reads:\n * 0 every file linted clean\n * 1 the run produced findings\n * 2 the tool could not do its job - bad usage, missing template, unreadable\n * input. A LintError is always this, never a lint failure.\n *\n * The 1/2 split is what lets a workflow tell \"the docs are wrong\" apart from\n * \"the linter is misconfigured\", which a single non-zero exit cannot.\n */\nimport { Command } from \"commander\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\nimport {\n collect,\n configOption,\n explicitFalse,\n readStdin,\n reportConfig,\n splitList,\n} from \"../shared/cli-options.js\";\nimport { shouldColor } from \"../shared/color.js\";\nimport { fail } from \"../shared/run.js\";\nimport { notice } from \"../shared/warn.js\";\nimport {\n OMITTED_WHEN_CLEAN,\n REPORT_FORMAT_LIST,\n STDIN_TOKEN,\n} from \"../meta/internal.js\";\nimport {\n REPORT_FORMATS,\n isReportFormat,\n type ReportFormat as FamilyFormat,\n} from \"../meta/index.js\";\nimport { LintError } from \"./types.js\";\nimport { runLint } from \"./commands/lint.js\";\nimport { runTemplates, runTemplatesInfer } from \"./commands/templates.js\";\nimport { runTools } from \"./commands/tools.js\";\nimport { INFER_FORMATS, isInferFormat, type InferFormat } from \"./core/infer.js\";\nimport {\n LINT_JOBS,\n TOOLS_BY_JOB,\n loadConfig,\n rebaseConfig,\n} from \"./core/config.js\";\nimport { resolveStructureTool } from \"./tools/index.js\";\nimport {\n render,\n renderTemplates,\n renderTools,\n type ListFormat,\n type ReportFormat,\n} from \"./reporters/index.js\";\n\n/** The options `check` and `structure` share, in the family's spelling. */\ninterface InputCliOptions {\n /** `--collection <name>`, repeatable; commander's default value is `[]`. */\n collection: string[];\n /** `--ext <list>`; the command splits it. */\n ext?: string;\n /** `--exclude <glob>`, repeatable; commander's default value is `[]`. */\n exclude: string[];\n /** `--as <format>`: force a parser. */\n as?: string;\n /**\n * `-c, --config <path>` and `--no-config` share one commander attribute:\n * `undefined` with neither flag, the path with `-c`, `false` with\n * `--no-config`. Split by `configOption`.\n */\n config?: string | boolean;\n allowEmpty?: boolean;\n /** `--no-gitignore`. */\n gitignore: boolean;\n /** `-f, --format <format>`. Always a string: the declaration has a default. */\n format: string;\n}\n\n/** `structure` adds the options of the tool that performs the job. */\ninterface StructureCliOptions extends InputCliOptions {\n tool?: string;\n template?: string;\n /** `--templates <path>`, repeatable; commander's default value is `[]`. */\n templates: string[];\n explain?: boolean;\n}\n\n/** What commander parses for `templates`. */\ninterface TemplatesCommandOptions {\n templates: string[];\n config?: string | boolean;\n format: string;\n}\n\n/** What commander parses for `templates infer`. */\ninterface TemplatesInferCliOptions {\n as?: string;\n name?: string;\n config?: string | boolean;\n format: string;\n out?: string;\n force?: boolean;\n}\n\n/** What commander parses for `tools`. */\ninterface ToolsCommandOptions {\n config?: string | boolean;\n format: string;\n}\n\n// `explain` is reachable through `--explain`, not `-f`: it reports on\n// configuration rather than on documents, and offering it as a format would\n// invite `-f explain` alongside a lint that then never happens. The `-f` set\n// itself is the family's, from meta, rather than a fourth hand-kept copy of\n// the same five words.\nconst LIST_FORMATS = new Set<string>([\"pretty\", \"json\"]);\n\n/** The heading the tool's own options print under, after the shared ones. */\nconst TOOL_OPTIONS_GROUP = \"Tool options:\";\n\nfunction resolveColor(program: Command): boolean {\n // commander maps --no-color to opts.color === false.\n const noColor = program.opts().color === false;\n return shouldColor({ noColor, isTTY: process.stdout.isTTY });\n}\n\nfunction reportFormat(value: unknown): FamilyFormat {\n const format = String(value);\n if (!isReportFormat(format)) {\n throw new LintError(\n `Unknown --format \"${format}\". Use ${REPORT_FORMAT_LIST}.`,\n );\n }\n return format;\n}\n\n/**\n * Whether a clean run may print nothing at all in this format.\n *\n * Only `github` may: an empty annotation stream is a clean check. Every other\n * format owes its envelope - an empty JSON array, a SARIF log with no results,\n * a JUnit suite of passing testcases - because a consumer parsing stdout must\n * not have to treat \"no output\" as a third outcome. `explain` is never clean\n * or dirty; it always has something to say.\n */\nfunction omittedWhenClean(format: ReportFormat): boolean {\n return format !== \"explain\" && OMITTED_WHEN_CLEAN.has(format);\n}\n\nfunction listFormat(value: unknown): ListFormat {\n const format = String(value);\n if (!LIST_FORMATS.has(format)) {\n throw new LintError(\n `Unknown --format \"${format}\". Use pretty or json.`,\n );\n }\n return format as ListFormat;\n}\n\n/**\n * `templates infer -f`: the format a *template file* is written in, which is\n * not the set a report is rendered in. A template is YAML or JSON because those\n * are the two the loader reads back, and `pretty` would name a third thing the\n * tool cannot then load.\n */\nfunction inferFormat(value: unknown): InferFormat {\n const format = String(value);\n if (!isInferFormat(format)) {\n throw new LintError(`Unknown --format \"${format}\". Use yaml or json.`);\n }\n return format;\n}\n\n/**\n * `--tool <name>`: which tool performs the structure job. Refused by name\n * rather than ignored, because falling through to manni's engine would lint\n * with something other than what was asked for and say nothing.\n *\n * The refusal is the registry's, not a second copy of it here. `runLint`\n * refuses the same name with the same sentence for a caller that never touches\n * commander; this one fires first, so a bad `--tool` is reported before the\n * run asks what it was pointed at.\n */\nfunction assertStructureTool(value: string | undefined): void {\n if (value === undefined) return;\n resolveStructureTool(value);\n}\n\n/**\n * `-c/--config` and `--no-config`, in one place.\n *\n * Every verb here takes them, and they had been written out three times. A flag\n * two commands both have carries the same name *and* the same description, so\n * the declaration is shared rather than copied - which is what kept the fourth\n * copy, on `templates infer`, from spelling either of them slightly differently.\n */\nfunction withConfigOptions(command: Command): Command {\n return command\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\");\n}\n\n/**\n * The value of a flag a command and its parent both declare.\n *\n * Commander keeps parsing a parent's options past a subcommand name unless\n * `enablePositionalOptions()` is on, so `templates infer page.md -f json` sets\n * `format` on `templates` and leaves `infer` holding its own default. Both\n * commands declare `-f`, `-c` and `--no-config`, because \"commands must have\n * parallel behaviors\" and `infer` must list them in its own `--help`.\n *\n * Turning positional options on would fix it and move every other flag in this\n * program with it: `manni lint structure docs/ --no-color` is a root option\n * written after its command, and there are three more like it. So the lookup\n * changes instead. The nearest command actually *given* the flag wins, and the\n * subcommand's own default is the fallback - which is the reading a person\n * typing the line already has.\n */\nfunction optionValue(command: Command, key: string): unknown {\n for (\n let cmd: Command | null = command;\n cmd !== null;\n cmd = cmd.parent ?? null\n ) {\n if (cmd.getOptionValueSource(key) === \"cli\") return cmd.getOptionValue(key);\n }\n return command.getOptionValue(key);\n}\n\n/** The options every job verb takes, in one place so the two cannot drift. */\nfunction withInputOptions(command: Command): Command {\n command\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to lint (use - for stdin)\",\n )\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format (e.g. markdown, mdx)\")\n .option(\n \"-f, --format <format>\",\n `output: ${REPORT_FORMATS.join(\" | \")}`,\n \"pretty\",\n );\n return withConfigOptions(command)\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"lint files .gitignore covers\");\n}\n\n/** The lint options every job verb turns its shared flags into. */\nfunction inputOptions(\n paths: string[],\n options: InputCliOptions,\n): {\n inputs: string[];\n collection: string[];\n exts?: string[];\n exclude: string[];\n as?: string;\n configPath?: string;\n noConfig?: boolean;\n allowEmpty?: boolean;\n respectGitignore?: boolean;\n onNotice: (message: string) => void;\n} {\n return {\n inputs: paths,\n collection: options.collection,\n ...(options.ext ? { exts: splitList(options.ext) } : {}),\n exclude: options.exclude,\n ...(options.as === undefined ? {} : { as: options.as }),\n ...configOption(options.config),\n // `undefined` rather than `false` when absent, so config still wins.\n ...(options.allowEmpty ? { allowEmpty: true } : {}),\n respectGitignore: explicitFalse(options.gitignore),\n onNotice: notice,\n };\n}\n\nexport function buildProgram(): Command {\n const program = new Command();\n program\n .name(\"lint\")\n .description(\n \"Validate document structure against doctype templates. Deterministic, CI-friendly.\",\n )\n .version(pkg.version, \"-V, --version\")\n .option(\"--no-color\", \"disable colored output\")\n .showHelpAfterError()\n // Exit code 1 is reserved for \"the docs are wrong\". Commander exits 1 on a\n // usage error by default, which would make a typo'd flag look exactly like\n // a failing lint to a workflow. With no callback, commander throws the\n // CommanderError instead, and the umbrella's runner maps it: help and\n // --version stay 0, every other usage error becomes 2. Commander has\n // already written its own message. This has to precede .command(), which\n // copies the callback into each subcommand.\n .exitOverride();\n\n /** Run one lint, render it, and settle the exit code. Both job verbs share it. */\n const lint = async (\n paths: string[],\n options: StructureCliOptions | InputCliOptions,\n command: Command,\n job: { tool?: StructureCliOptions } = {},\n ): Promise<void> => {\n const tool = job.tool;\n const format = reportFormat(options.format);\n const explain = tool?.explain === true;\n const stdinContent = paths.includes(STDIN_TOKEN) ? await readStdin() : undefined;\n const cwd = process.cwd();\n\n const run = await runLint({\n ...inputOptions(paths, options),\n ...(tool?.tool === undefined ? {} : { tool: tool.tool }),\n ...(tool?.template === undefined ? {} : { template: tool.template }),\n ...(tool && tool.templates.length > 0 ? { templates: tool.templates } : {}),\n ...(explain ? { explain: true } : {}),\n ...(stdinContent === undefined ? {} : { stdinContent }),\n // Which config governed the run, said where a report cannot be parsed\n // around: discovery walks up to the project boundary, so an unexpected\n // ancestor config is the difference between a five-minute diagnosis and\n // an hour of confusion.\n onConfigLoaded: reportConfig(format === \"pretty\", cwd),\n });\n\n const color = resolveColor(command.parent ?? command);\n const chosen: ReportFormat = explain ? \"explain\" : format;\n const text = render(run, chosen, { color });\n if (text.length > 0 || !omittedWhenClean(chosen)) {\n process.stdout.write(`${text}\\n`);\n }\n // `--explain` answers a question about configuration, so its exit code\n // reports whether it could answer it - not whether the docs are clean.\n //\n // That covers routing failures too: a page whose `type` matches no\n // template is a answered question, not an unanswered one, so it exits 0\n // like everything else here. Automation must not read this code as\n // \"everything routed\" - the ordinary run is what reports that, with exit\n // 1. Said in `--help` and the README, because the distinction is invisible\n // from the exit code alone.\n process.exitCode = explain ? 0 : run.summary.failed > 0 ? 1 : 0;\n };\n\n withInputOptions(\n program\n .command(\"check\")\n .description(\"Run every configured lint job over the given files/dirs/globs\"),\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Jobs: structure.\",\n \"\",\n \"Examples:\",\n \" manni lint check docs/ # every configured job\",\n \" manni lint check # targets from collections:\",\n \" manni lint check --collection guides\",\n ' manni lint check \"**/*.md\" -f github # CI annotations',\n \" cat page.md | manni lint check - --as markdown\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: InputCliOptions, command: Command) => {\n try {\n // Which jobs this run covered, said once, beside the config line. The\n // full form also names the jobs that exist and are not configured;\n // `structure` is the only job there is, so today it is one word.\n if (options.format === \"pretty\") {\n process.stderr.write(`Checked: ${LINT_JOBS.join(\", \")}.\\n`);\n }\n await lint(paths, options, command);\n } catch (err) {\n fail(err);\n }\n });\n\n const structure = withInputOptions(\n program\n .command(\"structure\")\n .description(\n \"Lint document structure against doctype templates, routing each page by its `type`\",\n ),\n );\n structure\n .optionsGroup(TOOL_OPTIONS_GROUP)\n .option(\n \"--tool <name>\",\n `tool that performs the job: ${TOOLS_BY_JOB.structure.join(\", \")}`,\n )\n .option(\n \"-t, --template <ref>\",\n \"apply this template to every file, overriding type routing\",\n )\n .option(\n \"--templates <path>\",\n \"template file to route by: its `types:` win over built-ins; repeatable\",\n collect,\n [],\n )\n .option(\n \"--explain\",\n \"print how each file's template was chosen, and lint nothing (always exits 0, unrouted pages included)\",\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni lint structure docs/ # route each page by its `type`\",\n \" manni lint structure docs/ --templates ./templates.yaml # add your own templates\",\n \" manni lint structure # targets from collections:\",\n \" manni lint structure docs/ --explain # show why each page routed where\",\n \" manni lint structure page.md -t tgdp:how-to:1.6 # force one template\",\n ' manni lint structure \"**/*.md\" -f github # CI annotations',\n \" manni lint structure docs/ --exclude '**/drafts/**'\",\n \" cat page.md | manni lint structure - -t tgdp:how-to:1.6 --as markdown\",\n ].join(\"\\n\"),\n )\n .action(\n async (paths: string[], options: StructureCliOptions, command: Command) => {\n try {\n assertStructureTool(options.tool);\n await lint(paths, options, command, { tool: options });\n } catch (err) {\n fail(err);\n }\n },\n );\n\n const templates = program\n .command(\"templates\")\n .description(\"List the templates that can be applied, and the types they serve\")\n .option(\n \"--templates <path>\",\n \"also list the templates in this file; repeatable\",\n collect,\n [],\n );\n withConfigOptions(templates)\n .option(\"-f, --format <format>\", \"output: pretty | json\", \"pretty\")\n .action(async (options: TemplatesCommandOptions, command: Command) => {\n try {\n const format = listFormat(options.format);\n // The listing answers \"what could route a page?\", so it has to see the\n // same template files a lint would - rebased the same way, or it would\n // answer for a different set of files depending on where it was run.\n const { configPath, noConfig } = configOption(options.config);\n const found = noConfig ? null : await loadConfig(configPath);\n const info = await runTemplates({\n templates:\n options.templates.length > 0\n ? options.templates\n : rebaseConfig(found).templates,\n });\n const color = resolveColor(command.parent ?? command);\n process.stdout.write(`${renderTemplates(info, format, { color })}\\n`);\n } catch (err) {\n fail(err);\n }\n });\n\n const inferCommand = templates\n .command(\"infer\")\n .description(\"Write a first template from a page that already has the shape you want\")\n .argument(\"<page>\", \"one file to infer from (use - for stdin)\")\n .option(\"--as <format>\", \"force an input format (e.g. markdown, mdx)\")\n .option(\n \"--name <name>\",\n \"name for the template; defaults to the page's `type`, else its filename\",\n )\n .option(\"-f, --format <format>\", `output: ${INFER_FORMATS.join(\" | \")}`, \"yaml\")\n .option(\"-o, --out <path>\", \"write the template here instead of to stdout\")\n .option(\"--force\", \"overwrite the --out path\");\n withConfigOptions(inferCommand)\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni lint templates infer docs/guides/install.md\",\n \" manni lint templates infer docs/guides/install.md --name how-to\",\n \" manni lint templates infer page.mdx -f json\",\n \" manni lint templates infer page.md -o ./templates.yaml\",\n \" manni lint templates infer page.md -o ./templates.yaml --force\",\n \" cat page.md | manni lint templates infer - --as markdown\",\n \"\",\n \"One page, and every rule it writes is exactly one occurrence: a single\",\n \"page cannot show what varies. Loosening a heading into a list or a\",\n \"pattern, setting `min: 0`, and adding a trailing rule with no heading\",\n \"for the sections that may follow are your edits to make.\",\n ].join(\"\\n\"),\n )\n .action(\n async (\n page: string,\n options: TemplatesInferCliOptions,\n command: Command,\n ) => {\n try {\n // `-f`, `-c` and `--no-config` are read through `optionValue`: the\n // parent `templates` declares all three, and commander hands it any\n // of them typed after `infer`.\n const format = inferFormat(optionValue(command, \"format\"));\n const { configPath, noConfig } = configOption(\n optionValue(command, \"config\"),\n );\n const stdinContent =\n page === STDIN_TOKEN ? await readStdin() : undefined;\n const result = await runTemplatesInfer({\n page,\n format,\n ...(options.as === undefined ? {} : { as: options.as }),\n ...(options.name === undefined ? {} : { name: options.name }),\n ...(options.out === undefined ? {} : { out: options.out }),\n ...(options.force === undefined ? {} : { force: options.force }),\n ...(configPath === undefined ? {} : { configPath }),\n ...(noConfig === undefined ? {} : { noConfig }),\n ...(stdinContent === undefined ? {} : { stdinContent }),\n // The template is the primary output, so with no --out it owns\n // stdout and the config line goes to stderr beside it. With --out\n // stdout is free, and the line still belongs on stderr: a reader\n // piping nothing is not a reason to move a diagnostic.\n onConfigLoaded: reportConfig(false, process.cwd()),\n });\n\n if (result.written === undefined) {\n process.stdout.write(result.text);\n return;\n }\n // Said on stderr, so `-o` leaves stdout empty for a shell that is\n // watching it, and the template file is the whole output.\n process.stderr.write(\n `Wrote template \"${result.name}\" to ${result.written}\\n`,\n );\n } catch (err) {\n fail(err);\n }\n },\n );\n\n withConfigOptions(\n program\n .command(\"tools\")\n .description(\n \"List the lint jobs, the tool that performs each, and what it reads\",\n ),\n )\n .option(\"-f, --format <format>\", \"output: pretty | json\", \"pretty\")\n .action(async (options: ToolsCommandOptions, command: Command) => {\n try {\n const format = listFormat(options.format);\n const tools = await runTools(configOption(options.config));\n const color = resolveColor(command.parent ?? command);\n process.stdout.write(`${renderTools(tools, format, { color })}\\n`);\n } catch (err) {\n fail(err);\n }\n });\n\n return program;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/lint/cli.ts"],"sourcesContent":["/**\n * The lint program. Named `lint` because that is where it is mounted\n * (`manni lint …`); `src/cli.ts` adds it to the umbrella and runs it. Thin\n * commander wrapper over the command cores. Follows clig.dev: primary output to\n * stdout, diagnostics to stderr, color only on a TTY (and never under\n * NO_COLOR/--no-color), meaningful exit codes.\n *\n * Grammar per proposal 0034: the verbs are `check`, `structure`, `templates`\n * and `tools`, and there is no default subcommand, so a bare `manni lint` is a\n * usage error that lists them. `check` runs every configured job; `structure`\n * runs one of them, and carries the options that belong to the tool performing\n * it.\n *\n * Exit codes are the contract CI reads:\n * 0 every file linted clean\n * 1 the run produced findings\n * 2 the tool could not do its job - bad usage, missing template, unreadable\n * input. A LintError is always this, never a lint failure.\n *\n * The 1/2 split is what lets a workflow tell \"the docs are wrong\" apart from\n * \"the linter is misconfigured\", which a single non-zero exit cannot.\n */\nimport { Command } from \"commander\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\nimport {\n collect,\n configOption,\n explicitFalse,\n readStdin,\n reportConfig,\n splitList,\n} from \"../shared/cli-options.js\";\nimport { shouldColor } from \"../shared/color.js\";\nimport { fail } from \"../shared/run.js\";\nimport { notice } from \"../shared/warn.js\";\nimport {\n OMITTED_WHEN_CLEAN,\n REPORT_FORMAT_LIST,\n STDIN_TOKEN,\n} from \"../meta/internal.js\";\nimport {\n REPORT_FORMATS,\n isReportFormat,\n type ReportFormat as FamilyFormat,\n} from \"../meta/index.js\";\nimport { LintError } from \"./types.js\";\nimport { runLint } from \"./commands/lint.js\";\nimport { runTemplates, runTemplatesInfer } from \"./commands/templates.js\";\nimport { runTools } from \"./commands/tools.js\";\nimport { INFER_FORMATS, isInferFormat, type InferFormat } from \"./core/infer.js\";\nimport {\n LINT_JOBS,\n TOOLS_BY_JOB,\n loadConfig,\n rebaseConfig,\n} from \"./core/config.js\";\nimport { resolveStructureTool } from \"./tools/index.js\";\nimport {\n render,\n renderTemplates,\n renderTools,\n type ListFormat,\n type ReportFormat,\n} from \"./reporters/index.js\";\n\n/** The options `check` and `structure` share, in the family's spelling. */\ninterface InputCliOptions {\n /** `--collection <name>`, repeatable; commander's default value is `[]`. */\n collection: string[];\n /** `--ext <list>`; the command splits it. */\n ext?: string;\n /** `--exclude <glob>`, repeatable; commander's default value is `[]`. */\n exclude: string[];\n /** `--as <format>`: force a parser. */\n as?: string;\n /**\n * `-c, --config <path>` and `--no-config` share one commander attribute:\n * `undefined` with neither flag, the path with `-c`, `false` with\n * `--no-config`. Split by `configOption`.\n */\n config?: string | boolean;\n allowEmpty?: boolean;\n /** `--no-gitignore`. */\n gitignore: boolean;\n /** `-f, --format <format>`. Always a string: the declaration has a default. */\n format: string;\n}\n\n/** `structure` adds the options of the tool that performs the job. */\ninterface StructureCliOptions extends InputCliOptions {\n tool?: string;\n template?: string;\n /** `--templates <path>`, repeatable; commander's default value is `[]`. */\n templates: string[];\n explain?: boolean;\n}\n\n/** What commander parses for `templates`. */\ninterface TemplatesCommandOptions {\n templates: string[];\n config?: string | boolean;\n format: string;\n}\n\n/** What commander parses for `templates infer`. */\ninterface TemplatesInferCliOptions {\n as?: string;\n name?: string;\n config?: string | boolean;\n format: string;\n out?: string;\n force?: boolean;\n}\n\n/** What commander parses for `tools`. */\ninterface ToolsCommandOptions {\n config?: string | boolean;\n format: string;\n}\n\n// `explain` is reachable through `--explain`, not `-f`: it reports on\n// configuration rather than on documents, and offering it as a format would\n// invite `-f explain` alongside a lint that then never happens. The `-f` set\n// itself is the family's, from meta, rather than a fourth hand-kept copy of\n// the same five words.\nconst LIST_FORMATS = new Set<string>([\"pretty\", \"json\"]);\n\n/** The heading the tool's own options print under, after the shared ones. */\nconst TOOL_OPTIONS_GROUP = \"Tool options:\";\n\nfunction resolveColor(program: Command): boolean {\n // commander maps --no-color to opts.color === false.\n const noColor = program.opts().color === false;\n return shouldColor({ noColor, isTTY: process.stdout.isTTY });\n}\n\nfunction reportFormat(value: unknown): FamilyFormat {\n const format = String(value);\n if (!isReportFormat(format)) {\n throw new LintError(\n `Unknown --format \"${format}\". Use ${REPORT_FORMAT_LIST}.`,\n );\n }\n return format;\n}\n\n/**\n * Whether a clean run may print nothing at all in this format.\n *\n * Only `github` may: an empty annotation stream is a clean check. Every other\n * format owes its envelope - an empty JSON array, a SARIF log with no results,\n * a JUnit suite of passing testcases - because a consumer parsing stdout must\n * not have to treat \"no output\" as a third outcome. `explain` is never clean\n * or dirty; it always has something to say.\n */\nfunction omittedWhenClean(format: ReportFormat): boolean {\n return format !== \"explain\" && OMITTED_WHEN_CLEAN.has(format);\n}\n\nfunction listFormat(value: unknown): ListFormat {\n const format = String(value);\n if (!LIST_FORMATS.has(format)) {\n throw new LintError(\n `Unknown --format \"${format}\". Use pretty or json.`,\n );\n }\n return format as ListFormat;\n}\n\n/**\n * `templates infer -f`: the format a *template file* is written in, which is\n * not the set a report is rendered in. A template is YAML or JSON because those\n * are the two the loader reads back, and `pretty` would name a third thing the\n * tool cannot then load.\n */\nfunction inferFormat(value: unknown): InferFormat {\n const format = String(value);\n if (!isInferFormat(format)) {\n throw new LintError(`Unknown --format \"${format}\". Use yaml or json.`);\n }\n return format;\n}\n\n/**\n * `--tool <name>`: which tool performs the structure job. Refused by name\n * rather than ignored, because falling through to manni's engine would lint\n * with something other than what was asked for and say nothing.\n *\n * The refusal is the registry's, not a second copy of it here. `runLint`\n * refuses the same name with the same sentence for a caller that never touches\n * commander; this one fires first, so a bad `--tool` is reported before the\n * run asks what it was pointed at.\n */\nfunction assertStructureTool(value: string | undefined): void {\n if (value === undefined) return;\n resolveStructureTool(value);\n}\n\n/**\n * `-c/--config` and `--no-config`, in one place.\n *\n * Every verb here takes them, and they had been written out three times. A flag\n * two commands both have carries the same name *and* the same description, so\n * the declaration is shared rather than copied - which is what kept the fourth\n * copy, on `templates infer`, from spelling either of them slightly differently.\n */\nfunction withConfigOptions(command: Command): Command {\n return command\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\");\n}\n\n/**\n * The value of a flag a command and its parent both declare.\n *\n * Commander keeps parsing a parent's options past a subcommand name unless\n * `enablePositionalOptions()` is on, so `templates infer page.md -f json` sets\n * `format` on `templates` and leaves `infer` holding its own default. Both\n * commands declare `-f`, `-c` and `--no-config`, because \"commands must have\n * parallel behaviors\" and `infer` must list them in its own `--help`.\n *\n * Turning positional options on would fix it and move every other flag in this\n * program with it: `manni lint structure docs/ --no-color` is a root option\n * written after its command, and there are three more like it. So the lookup\n * changes instead. The nearest command actually *given* the flag wins, and the\n * subcommand's own default is the fallback - which is the reading a person\n * typing the line already has.\n */\nfunction optionValue(command: Command, key: string): unknown {\n for (\n let cmd: Command | null = command;\n cmd !== null;\n cmd = cmd.parent ?? null\n ) {\n if (cmd.getOptionValueSource(key) === \"cli\") return cmd.getOptionValue(key);\n }\n return command.getOptionValue(key);\n}\n\n/** The options every job verb takes, in one place so the two cannot drift. */\nfunction withInputOptions(command: Command): Command {\n command\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to lint (use - for stdin)\",\n )\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format (e.g. markdown, mdx)\")\n .option(\n \"-f, --format <format>\",\n `output: ${REPORT_FORMATS.join(\" | \")}`,\n \"pretty\",\n );\n return withConfigOptions(command)\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"lint files .gitignore covers\");\n}\n\n/** The lint options every job verb turns its shared flags into. */\nfunction inputOptions(\n paths: string[],\n options: InputCliOptions,\n): {\n inputs: string[];\n collection: string[];\n exts?: string[];\n exclude: string[];\n as?: string;\n configPath?: string;\n noConfig?: boolean;\n allowEmpty?: boolean;\n respectGitignore?: boolean;\n onNotice: (message: string) => void;\n} {\n return {\n inputs: paths,\n collection: options.collection,\n ...(options.ext ? { exts: splitList(options.ext) } : {}),\n exclude: options.exclude,\n ...(options.as === undefined ? {} : { as: options.as }),\n ...configOption(options.config),\n // `undefined` rather than `false` when absent, so config still wins.\n ...(options.allowEmpty ? { allowEmpty: true } : {}),\n respectGitignore: explicitFalse(options.gitignore),\n onNotice: notice,\n };\n}\n\nexport function buildProgram(): Command {\n const program = new Command();\n program\n .name(\"lint\")\n .description(\n \"Validate document structure against doctype templates. Deterministic, CI-friendly.\",\n )\n .version(pkg.version, \"-V, --version\")\n .option(\"--no-color\", \"disable colored output\")\n .showHelpAfterError()\n // Exit code 1 is reserved for \"the docs are wrong\". Commander exits 1 on a\n // usage error by default, which would make a typo'd flag look exactly like\n // a failing lint to a workflow. With no callback, commander throws the\n // CommanderError instead, and the umbrella's runner maps it: help and\n // --version stay 0, every other usage error becomes 2. Commander has\n // already written its own message. This has to precede .command(), which\n // copies the callback into each subcommand.\n .exitOverride();\n\n /** Run one lint, render it, and settle the exit code. Both job verbs share it. */\n const lint = async (\n paths: string[],\n options: StructureCliOptions | InputCliOptions,\n command: Command,\n job: { tool?: StructureCliOptions } = {},\n ): Promise<void> => {\n const tool = job.tool;\n const format = reportFormat(options.format);\n const explain = tool?.explain === true;\n const stdinContent = paths.includes(STDIN_TOKEN) ? await readStdin() : undefined;\n const cwd = process.cwd();\n\n const run = await runLint({\n ...inputOptions(paths, options),\n ...(tool?.tool === undefined ? {} : { tool: tool.tool }),\n ...(tool?.template === undefined ? {} : { template: tool.template }),\n ...(tool && tool.templates.length > 0 ? { templates: tool.templates } : {}),\n ...(explain ? { explain: true } : {}),\n ...(stdinContent === undefined ? {} : { stdinContent }),\n // Which config governed the run, said where a report cannot be parsed\n // around: discovery walks up to the project boundary, so an unexpected\n // ancestor config is the difference between a five-minute diagnosis and\n // an hour of confusion.\n onConfigLoaded: reportConfig(format === \"pretty\", cwd),\n });\n\n const color = resolveColor(command.parent ?? command);\n const chosen: ReportFormat = explain ? \"explain\" : format;\n const text = render(run, chosen, { color });\n if (text.length > 0 || !omittedWhenClean(chosen)) {\n process.stdout.write(`${text}\\n`);\n }\n // `--explain` answers a question about configuration, so its exit code\n // reports whether it could answer it - not whether the docs are clean.\n //\n // That covers routing failures too: a page whose `type` matches no\n // template is a answered question, not an unanswered one, so it exits 0\n // like everything else here. Automation must not read this code as\n // \"everything routed\" - the ordinary run is what reports that, with exit\n // 1. Said in `--help` and the README, because the distinction is invisible\n // from the exit code alone.\n process.exitCode = explain ? 0 : run.summary.failed > 0 ? 1 : 0;\n };\n\n withInputOptions(\n program\n .command(\"check\")\n .description(\"Run every configured lint job over the given files/dirs/globs\"),\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Jobs: structure.\",\n \"\",\n \"Examples:\",\n \" manni lint check docs/ # every configured job\",\n \" manni lint check # targets from collections:\",\n \" manni lint check --collection guides\",\n ' manni lint check \"**/*.md\" -f github # CI annotations',\n \" cat page.md | manni lint check - --as markdown\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: InputCliOptions, command: Command) => {\n try {\n // Which jobs this run covered, said once, beside the config line. The\n // full form also names the jobs that exist and are not configured;\n // `structure` is the only job there is, so today it is one word.\n if (options.format === \"pretty\") {\n process.stderr.write(`Checked: ${LINT_JOBS.join(\", \")}.\\n`);\n }\n await lint(paths, options, command);\n } catch (err) {\n fail(err);\n }\n });\n\n const structure = withInputOptions(\n program\n .command(\"structure\")\n .description(\n \"Lint document structure against doctype templates, routing each page by its `type`\",\n ),\n );\n structure\n .optionsGroup(TOOL_OPTIONS_GROUP)\n .option(\n \"--tool <name>\",\n `tool that performs the job: ${TOOLS_BY_JOB.structure.join(\", \")}`,\n )\n .option(\n \"-t, --template <ref>\",\n \"apply this template to every file, overriding type routing\",\n )\n .option(\n \"--templates <path>\",\n \"template file to route by: its `types:` win over built-ins; repeatable\",\n collect,\n [],\n )\n .option(\n \"--explain\",\n \"print how each file's template was chosen, and lint nothing (always exits 0, unrouted pages included)\",\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni lint structure docs/ # route each page by its `type`\",\n \" manni lint structure docs/ --templates ./templates.yaml # add your own templates\",\n \" manni lint structure # targets from collections:\",\n \" manni lint structure docs/ --explain # show why each page routed where\",\n \" manni lint structure page.md -t tgdp:how-to:1.6 # force one template\",\n ' manni lint structure \"**/*.md\" -f github # CI annotations',\n \" manni lint structure docs/ --exclude '**/drafts/**'\",\n \" cat page.md | manni lint structure - -t tgdp:how-to:1.6 --as markdown\",\n ].join(\"\\n\"),\n )\n .action(\n async (paths: string[], options: StructureCliOptions, command: Command) => {\n try {\n assertStructureTool(options.tool);\n await lint(paths, options, command, { tool: options });\n } catch (err) {\n fail(err);\n }\n },\n );\n\n const templates = program\n .command(\"templates\")\n .description(\"List the templates that can be applied, and the types they serve\")\n .option(\n \"--templates <path>\",\n \"also list the templates in this file; repeatable\",\n collect,\n [],\n );\n withConfigOptions(templates)\n .option(\"-f, --format <format>\", \"output: pretty | json\", \"pretty\")\n .action(async (options: TemplatesCommandOptions, command: Command) => {\n try {\n const format = listFormat(options.format);\n // The listing answers \"what could route a page?\", so it has to see the\n // same template files a lint would - rebased the same way, or it would\n // answer for a different set of files depending on where it was run.\n const { configPath, noConfig } = configOption(options.config);\n const found = noConfig ? null : await loadConfig(configPath);\n const info = await runTemplates({\n templates:\n options.templates.length > 0\n ? options.templates\n : rebaseConfig(found).templates,\n });\n const color = resolveColor(command.parent ?? command);\n process.stdout.write(`${renderTemplates(info, format, { color })}\\n`);\n } catch (err) {\n fail(err);\n }\n });\n\n const inferCommand = templates\n .command(\"infer\")\n .description(\"Write a first template from a page that already has the shape you want\")\n .argument(\"<page>\", \"one file to infer from (use - for stdin)\")\n .option(\"--as <format>\", \"force an input format (e.g. markdown, mdx)\")\n .option(\n \"--name <name>\",\n \"name for the template; defaults to the page's `type`, else its filename\",\n )\n .option(\"-f, --format <format>\", `output: ${INFER_FORMATS.join(\" | \")}`, \"yaml\")\n .option(\"-o, --out <path>\", \"write the template here instead of to stdout\")\n .option(\"--force\", \"overwrite the --out path\");\n withConfigOptions(inferCommand)\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni lint templates infer docs/guides/install.md\",\n \" manni lint templates infer docs/guides/install.md --name how-to\",\n \" manni lint templates infer page.mdx -f json\",\n \" manni lint templates infer page.md -o ./templates.yaml\",\n \" manni lint templates infer page.md -o ./templates.yaml --force\",\n \" cat page.md | manni lint templates infer - --as markdown\",\n \"\",\n \"One page, and every rule it writes is exactly one occurrence: a single\",\n \"page cannot show what varies. Loosening a heading into a list or a\",\n \"pattern, setting `min: 0`, and adding a trailing rule with no heading\",\n \"for the sections that may follow are your edits to make.\",\n ].join(\"\\n\"),\n )\n .action(\n async (\n page: string,\n options: TemplatesInferCliOptions,\n command: Command,\n ) => {\n try {\n // `-f`, `-c` and `--no-config` are read through `optionValue`: the\n // parent `templates` declares all three, and commander hands it any\n // of them typed after `infer`.\n const format = inferFormat(optionValue(command, \"format\"));\n const { configPath, noConfig } = configOption(\n optionValue(command, \"config\"),\n );\n const stdinContent =\n page === STDIN_TOKEN ? await readStdin() : undefined;\n const result = await runTemplatesInfer({\n page,\n format,\n ...(options.as === undefined ? {} : { as: options.as }),\n ...(options.name === undefined ? {} : { name: options.name }),\n ...(options.out === undefined ? {} : { out: options.out }),\n ...(options.force === undefined ? {} : { force: options.force }),\n ...(configPath === undefined ? {} : { configPath }),\n ...(noConfig === undefined ? {} : { noConfig }),\n ...(stdinContent === undefined ? {} : { stdinContent }),\n // The template is the primary output, so with no --out it owns\n // stdout and the config line goes to stderr beside it. With --out\n // stdout is free, and the line still belongs on stderr: a reader\n // piping nothing is not a reason to move a diagnostic.\n onConfigLoaded: reportConfig(false, process.cwd()),\n });\n\n if (result.written === undefined) {\n process.stdout.write(result.text);\n return;\n }\n // Said on stderr, so `-o` leaves stdout empty for a shell that is\n // watching it, and the template file is the whole output.\n process.stderr.write(\n `Wrote template \"${result.name}\" to ${result.written}\\n`,\n );\n } catch (err) {\n fail(err);\n }\n },\n );\n\n withConfigOptions(\n program\n .command(\"tools\")\n .description(\n \"List the lint jobs, the tool that performs each, and what it reads\",\n ),\n )\n .option(\"-f, --format <format>\", \"output: pretty | json\", \"pretty\")\n .action(async (options: ToolsCommandOptions, command: Command) => {\n try {\n const format = listFormat(options.format);\n const tools = await runTools(configOption(options.config));\n const color = resolveColor(command.parent ?? command);\n process.stdout.write(`${renderTools(tools, format, { color })}\\n`);\n } catch (err) {\n fail(err);\n }\n });\n\n return program;\n}\n"],"mappings":"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","names":[]}
@@ -3,53 +3,45 @@ import {
3
3
  runAdd,
4
4
  runRemove,
5
5
  runUpdate
6
- } from "./chunk-2UCC26MO.js";
6
+ } from "./chunk-CH6IOGXV.js";
7
7
  import {
8
8
  runCheck
9
- } from "./chunk-3E2X2RBU.js";
9
+ } from "./chunk-DGRLHDM4.js";
10
10
  import {
11
11
  findingMessage,
12
12
  renderCheckGithub
13
- } from "./chunk-SUTMSDQ2.js";
13
+ } from "./chunk-GQ3KRY3B.js";
14
14
  import {
15
15
  renderCheckPretty,
16
16
  renderRemovePretty,
17
17
  renderUpdatePretty
18
- } from "./chunk-7Y3N4Y72.js";
18
+ } from "./chunk-OHUDZRLK.js";
19
19
  import {
20
20
  errorSite,
21
21
  shortCommit,
22
22
  shortLine,
23
23
  shortPin,
24
24
  shortSrc
25
- } from "./chunk-RZVCWX5R.js";
26
- import {
27
- renderCheckJson,
28
- renderRemoveJson,
29
- renderUpdateJson
30
- } from "./chunk-PCE7QHXJ.js";
31
- import "./chunk-77AINBYM.js";
25
+ } from "./chunk-AYVKN3PG.js";
32
26
  import {
33
27
  CiteError,
34
28
  RULE_ID_PREFIX,
35
29
  asCiteError,
36
30
  isCiteRule,
37
31
  spellSource
38
- } from "./chunk-PK7EKJ5T.js";
32
+ } from "./chunk-24AJK2RG.js";
33
+ import {
34
+ renderCheckJson,
35
+ renderRemoveJson,
36
+ renderUpdateJson
37
+ } from "./chunk-PCE7QHXJ.js";
39
38
  import "./chunk-IKEWBMCN.js";
40
- import "./chunk-G6FNWRAI.js";
39
+ import "./chunk-YUTVAMWW.js";
40
+ import "./chunk-JSSM7VVV.js";
41
41
  import {
42
42
  terminalConfirm
43
- } from "./chunk-2W34HX2U.js";
44
- import {
45
- collect,
46
- configOption,
47
- explicitFalse,
48
- readStdin,
49
- reportConfig,
50
- splitList,
51
- splitPageArgument
52
- } from "./chunk-KBG463UK.js";
43
+ } from "./chunk-PS257NIU.js";
44
+ import "./chunk-2OZF2VUB.js";
53
45
  import {
54
46
  COMMON_FORMAT_LIST,
55
47
  OMITTED_WHEN_CLEAN,
@@ -59,25 +51,37 @@ import {
59
51
  isReportFormat,
60
52
  renderJunit,
61
53
  renderSarif
62
- } from "./chunk-QBVP3SQP.js";
54
+ } from "./chunk-SGR7ZAVE.js";
55
+ import "./chunk-QEAGL4V5.js";
63
56
  import {
64
- STDIN_TOKEN
65
- } from "./chunk-G7XD4QH5.js";
57
+ collect,
58
+ configOption,
59
+ explicitFalse,
60
+ readStdin,
61
+ reportConfig,
62
+ splitList,
63
+ splitPageArgument
64
+ } from "./chunk-SMHAYK6I.js";
65
+ import "./chunk-DSWKBZWW.js";
66
66
  import {
67
- fail
68
- } from "./chunk-YEUYKR62.js";
67
+ STDIN_TOKEN
68
+ } from "./chunk-RGLFV4KO.js";
69
+ import "./chunk-77AINBYM.js";
70
+ import "./chunk-MNH7QO4Z.js";
69
71
  import {
70
72
  shouldColor
71
73
  } from "./chunk-RNVYGWIC.js";
72
- import "./chunk-MNH7QO4Z.js";
73
- import "./chunk-6M5VJOC2.js";
74
+ import {
75
+ fail
76
+ } from "./chunk-YEUYKR62.js";
77
+ import "./chunk-OTJOBZJ5.js";
74
78
  import {
75
79
  notice
76
80
  } from "./chunk-HX44GB4Z.js";
77
- import "./chunk-QCHVR4ZM.js";
81
+ import "./chunk-VM7VAFJW.js";
78
82
  import {
79
83
  package_default
80
- } from "./chunk-2BV4FBC7.js";
84
+ } from "./chunk-DHGB4JBG.js";
81
85
  import "./chunk-OWBRDNRZ.js";
82
86
  import "./chunk-G3T47CFV.js";
83
87
  import "./chunk-2H7UOFLK.js";
@@ -547,4 +551,4 @@ export {
547
551
  colorFor,
548
552
  splitPageArgument2 as splitPageArgument
549
553
  };
550
- //# sourceMappingURL=cli-V2DI3K2R.js.map
554
+ //# sourceMappingURL=cli-6R4W3HAH.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cite/cli.ts","../src/cite/reporters/sarif.ts","../src/cite/reporters/junit.ts"],"sourcesContent":["/**\n * The `cite` domain's commander program. Mounted by `src/cli.ts` under\n * `manni cite`; no entry point of its own. Grammar per proposal 0034: verbs are\n * `check`, `add`, `update`, `remove`; there is no default subcommand.\n *\n * Follows clig.dev as meta's does: primary output to stdout, diagnostics to\n * stderr, colour only on a TTY and never under `NO_COLOR`/`--no-color`, exit\n * `0` clean, `1` an error-severity finding, `2` operational/usage.\n */\nimport { Command, Option } from \"commander\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\nimport {\n collect,\n configOption,\n explicitFalse,\n readStdin,\n reportConfig,\n splitList,\n} from \"../shared/cli-options.js\";\nimport { shouldColor } from \"../shared/color.js\";\nimport { splitPageArgument as splitSharedPageArgument } from \"../shared/pin.js\";\nimport { terminalConfirm } from \"../shared/prompt.js\";\nimport { fail } from \"../shared/run.js\";\nimport { notice } from \"../shared/warn.js\";\nimport {\n COMMON_FORMAT_LIST,\n OMITTED_WHEN_CLEAN,\n REPORT_FORMAT_LIST,\n STDIN_TOKEN,\n isMachineFormat,\n} from \"../meta/internal.js\";\nimport { REPORT_FORMATS, isReportFormat } from \"../meta/index.js\";\nimport { runAdd } from \"./commands/add.js\";\nimport { runCheck } from \"./commands/check.js\";\nimport { runRemove } from \"./commands/remove.js\";\nimport { runUpdate } from \"./commands/update.js\";\nimport { CiteError, asCiteError } from \"./errors.js\";\nimport { spellSource } from \"./core/range.js\";\nimport { shortCommit, shortLine, shortPin, shortSrc } from \"./core/spell.js\";\nimport { renderCheckGithub } from \"./reporters/github.js\";\nimport { renderCheckJson, renderRemoveJson, renderUpdateJson } from \"./reporters/json.js\";\nimport { renderCheckJunit } from \"./reporters/junit.js\";\nimport { renderCheckPretty, renderRemovePretty, renderUpdatePretty } from \"./reporters/pretty.js\";\nimport { renderCheckSarif } from \"./reporters/sarif.js\";\nimport type { AddResult, PageLines } from \"./types.js\";\n\nconst UPDATE_FORMATS = [\"pretty\", \"json\"] as const;\ntype UpdateFormat = (typeof UPDATE_FORMATS)[number];\n/** The same two `update` has: a removal is a write, and writes report alike. */\nconst REMOVE_FORMATS = UPDATE_FORMATS;\ntype RemoveFormat = UpdateFormat;\n\n/**\n * Whether `command`'s output gets colour: this domain's `--no-color` and\n * `NO_COLOR` turn it off, and otherwise only a TTY turns it on\n * (`shouldColor`). `isTTY` is passed uncoerced: Node leaves it undefined off\n * a terminal, never false, and `shouldColor` reads a missing one as \"not a\n * terminal\".\n */\nexport function colorFor(\n command: Command,\n isTTY: boolean | undefined,\n env?: NodeJS.ProcessEnv,\n): boolean {\n // commander maps --no-color to opts.color === false, on the command that\n // declares it.\n const noColor = colorOwner(command).opts().color === false;\n return shouldColor({ noColor, isTTY, env });\n}\n\n/**\n * The nearest command, this one or an ancestor, that declares `--no-color`:\n * the `cite` program, wherever it is mounted. Not the root: under the\n * umbrella that is `manni`, which has no `--no-color` of its own.\n */\nfunction colorOwner(command: Command): Command {\n for (let c: Command | null = command; c !== null; c = c.parent) {\n if (c.options.some((o) => o.long === \"--no-color\")) return c;\n }\n return command;\n}\n\nfunction isUpdateFormat(value: string): value is UpdateFormat {\n return (UPDATE_FORMATS as readonly string[]).includes(value);\n}\n\nfunction isRemoveFormat(value: string): value is RemoveFormat {\n return (REMOVE_FORMATS as readonly string[]).includes(value);\n}\n\n/**\n * Commander hands an `.action()` callback an untyped bag of option values, so\n * each subcommand declares the shape it actually reads. The `--no-<thing>`\n * flags are `boolean` and never `undefined`: commander supplies `true` when\n * the flag is absent, which is its default and not a choice, so only the\n * explicit `false` travels to the core (`explicitFalse`).\n */\ninterface InputCliOptions {\n /** `--collection <name>`, repeatable; commander's default value is `[]`. */\n collection: string[];\n /** `--ext <list>`; the command splits it. */\n ext?: string;\n /** `--exclude <glob>`, repeatable; commander's default value is `[]`. */\n exclude: string[];\n /** `--as <format>`: force an extractor. */\n as?: string;\n /**\n * `-c, --config <path>` and `--no-config` share one commander attribute:\n * `undefined` with neither flag, the path with `-c`, `false` with\n * `--no-config`. Split by `configOption`.\n */\n config?: string | boolean;\n allowEmpty?: boolean;\n /** `--no-gitignore`. */\n gitignore: boolean;\n /** `--root <dir>`: where `src:` paths resolve from. */\n root?: string;\n}\n\ninterface CheckCliOptions extends InputCliOptions {\n /** `-f, --format <format>`. Always a string: the declaration has a default. */\n format: string;\n quiet?: boolean;\n /**\n * `--baseline [path]` / `--no-baseline`, the same three-state split as\n * `config`: absent leaves the config in charge, a string names a file, `true`\n * is a bare `--baseline` (the default path), `false` is `--no-baseline`.\n */\n baseline?: string | boolean;\n /** `--write-baseline [path]`; `true` for the bare flag. */\n writeBaseline?: string | boolean;\n /** `--no-check-sources`. */\n checkSources: boolean;\n showDiff?: boolean;\n reveal?: boolean;\n}\n\ninterface AddCliOptions {\n id?: string;\n marker?: boolean;\n quote?: boolean;\n /** `--encrypt`. */\n encrypt?: boolean;\n /** `--no-commit-sha`. */\n commitSha: boolean;\n dryRun?: boolean;\n as?: string;\n root?: string;\n config?: string | boolean;\n}\n\ninterface RemoveCliOptions extends Omit<InputCliOptions, \"root\"> {\n /** `--only <id>`, repeatable; commander's default value is `[]`. */\n only: string[];\n dryRun?: boolean;\n format: string;\n}\n\ninterface UpdateCliOptions extends InputCliOptions {\n /** `--no-check-sources`: declared so the refusal names the flag rather than commander rejecting it. */\n checkSources: boolean;\n accept?: boolean;\n recommit?: boolean;\n /** `--only <id>`, repeatable; commander's default value is `[]`. */\n only: string[];\n dryRun?: boolean;\n format: string;\n}\n\n/**\n * Split `docs/limits.md:9` or `docs/limits.md:14-18` into the page and the\n * claim's lines, under cite's error contract. The parsing is the shared pin\n * engine's (`splitPageArgument` in `src/shared/pin.ts`).\n */\nexport function splitPageArgument(arg: string): { page: string; lines?: PageLines } {\n return asCiteError(() => splitSharedPageArgument(arg));\n}\n\n/** `line 9`, or `lines 14-18` for a range. */\nfunction spellAt(lines: PageLines, noun = \"line\"): string {\n return lines.start === lines.end\n ? `${noun} ${String(lines.start)}`\n : `${noun}s ${String(lines.start)}-${String(lines.end)}`;\n}\n\n/**\n * What `add` says on success. One sentence composed from the result: what was\n * added, where it went, and what each end is pinned to. Lines are the page's\n * own, after the write. The source is spelled as it was written to the page,\n * abbreviated when it is a ciphertext, and quoted with its first pinned line\n * where the result carries one.\n */\nexport function addMessage(result: AddResult): string {\n const { citation, claimLines } = result;\n const claim = citation.claim;\n const name = citation.id ?? (claim === undefined ? \"a bare pin\" : \"an entry\");\n const src = shortSrc(spellSource(citation.source));\n const commit = citation.source[\"commit-sha\"];\n const quoted = result.sourceLine === undefined ? \"\" : shortLine(result.sourceLine);\n const line = quoted === \"\" ? \"\" : ` \"${quoted}\"`;\n const pin = `${src}${line}, ${shortPin(citation.source.integrity)}, ${commit === undefined ? \"no commit\" : shortCommit(commit)}`;\n // Where it went: the page's own frontmatter, or the manifest that owns the\n // page's citations, at the line the entry now sits on.\n const where =\n result.manifest === undefined\n ? \"frontmatter\"\n : `${result.manifest.file}:${String(result.manifest.line)}`;\n const head = `${result.file}: added ${name} to ${where}`;\n\n if (result.markerLine !== undefined) {\n const at =\n claimLines === undefined ? \"\" : `, claim pinned at ${spellAt(claimLines)}`;\n const wrote = result.markerJoined === true ? \"joined the marker at line\" : \"marker at line\";\n const marked = `${head}; ${wrote} ${String(result.markerLine)}${at}`;\n if (claim === undefined) return marked;\n if (citation.quote === true) return `${marked} (a block that reproduces ${src})`;\n return `${marked} (${shortPin(claim.integrity)}; source ${pin})`;\n }\n if (claim === undefined || claimLines === undefined) {\n return `${head} (source ${pin})`;\n }\n if (citation.quote === true) {\n return `${head} (claim ${spellAt(claimLines, \"line\")}, a block that reproduces ${src})`;\n }\n return `${head} (claim at ${spellAt(claimLines)}, ${shortPin(claim.integrity)}; source ${pin})`;\n}\n\nexport function buildProgram(): Command {\n const program = new Command();\n program\n .name(\"cite\")\n .description(\n \"Track citations from doc claims to source lines and check them for drift.\",\n )\n .version(pkg.version, \"-V, --version\")\n .option(\"--no-color\", \"disable colored output\")\n // A pointer, not the whole help screen: the message that precedes it\n // already names the offending flag.\n .showHelpAfterError(\"(add --help for usage)\")\n // MUST come before the `.command()` calls below. `copyInheritedSettings`\n // copies `_exitCallback` by value at subcommand-creation time, so an\n // `exitOverride()` installed afterwards leaves every subcommand still\n // calling `process.exit(1)`.\n .exitOverride();\n\n program\n .command(\"check\")\n .description(\"Check every citation in the given pages against its source\")\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to check (use - for stdin)\",\n )\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format for every input\")\n .option(\n \"-f, --format <format>\",\n `output: ${REPORT_FORMATS.join(\" | \")}`,\n \"pretty\",\n )\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\")\n .option(\"-q, --quiet\", \"in pretty output, hide current citations and clean files\")\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"check files .gitignore covers\")\n // No `defaultValue` and no `.preset()`, for the reasons meta's validate\n // gives: a bare flag must stay distinguishable from a typed path.\n .addOption(\n new Option(\n \"--baseline [path]\",\n \"compare against a baseline; fail only on findings not in it\",\n ),\n )\n .addOption(\n new Option(\n \"--write-baseline [path]\",\n \"record current findings as the baseline, then exit 0\",\n ),\n )\n .option(\"--no-baseline\", \"ignore a baseline configured by `baseline:`\")\n .option(\"--no-check-sources\", \"page-side rules only; every source status is skipped\")\n .option(\n \"--root <dir>\",\n \"directory src: paths resolve from (default: cite.root from config, else the git root, else the current directory)\",\n )\n .option(\"--show-diff\", \"in pretty output, print the diff and commit subjects for changed\")\n .option(\"--reveal\", \"in pretty output, print the decrypted path beside an encrypted source\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni cite check docs/ # walk a directory\",\n \" manni cite check --collection guides # one configured collection\",\n ' manni cite check \"docs/**/*.md\" -f github # CI annotations',\n \" manni cite check --show-diff docs/limits.md # see what changed\",\n \" manni cite check --baseline # fail only on new findings\",\n \" cat page.md | manni cite check - --as markdown\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: CheckCliOptions, command: Command) => {\n try {\n const format = options.format;\n if (!isReportFormat(format)) {\n throw new CiteError(\n `Unknown --format \"${format}\". Use ${REPORT_FORMAT_LIST}.`,\n );\n }\n const exts = options.ext ? splitList(options.ext) : undefined;\n const stdinContent = paths.includes(STDIN_TOKEN) ? await readStdin() : undefined;\n const cwd = process.cwd();\n\n const run = await runCheck({\n inputs: paths,\n collection: options.collection,\n exts,\n exclude: options.exclude,\n as: options.as,\n ...configOption(options.config),\n onConfigLoaded: reportConfig(!isMachineFormat(format), cwd),\n stdinContent,\n // `undefined` rather than `false` when absent, so config still wins.\n allowEmpty: options.allowEmpty ? true : undefined,\n respectGitignore: explicitFalse(options.gitignore),\n onNotice: notice,\n baseline: options.baseline,\n writeBaseline: options.writeBaseline,\n checkSources: explicitFalse(options.checkSources),\n // Only so the run can say git is not there to give diffs; the diffs\n // themselves are the pretty reporter's.\n showDiff: options.showDiff ? true : undefined,\n root: options.root,\n });\n\n let text: string;\n switch (format) {\n case \"pretty\":\n text = renderCheckPretty(run, {\n color: colorFor(command, process.stdout.isTTY),\n quiet: Boolean(options.quiet),\n showDiff: Boolean(options.showDiff),\n reveal: Boolean(options.reveal),\n });\n break;\n case \"json\":\n text = renderCheckJson(run);\n break;\n case \"github\":\n text = renderCheckGithub(run);\n break;\n case \"sarif\":\n text = renderCheckSarif(run, { onNotice: notice });\n break;\n case \"junit\":\n text = renderCheckJunit(run);\n break;\n }\n // Only `github` may say nothing on a clean run; every other format\n // owes its envelope even when empty.\n if (text.length > 0 || !OMITTED_WHEN_CLEAN.has(format)) {\n process.stdout.write(`${text}\\n`);\n }\n // `failed` counts files with an unbaselined error-severity finding;\n // warnings never move it.\n process.exitCode = run.summary.failed > 0 ? 1 : 0;\n } catch (err) {\n fail(err);\n }\n });\n\n program\n .command(\"add\")\n .description(\"Mint a citation for a source range and write it to a page\")\n .argument(\n \"<page>\",\n \"the page to cite from, with the claim's lines: page:L or page:L1-L2 (use - for stdin, with --as)\",\n )\n .argument(\n \"<src>\",\n \"path, path:L or path:L1-L2 relative to --root, or an encrypted ~source with the same line forms\",\n )\n .option(\"--id <id>\", \"kebab-case id, unique on the page; required with --marker\")\n .option(\"--marker\", \"write a cite <id> marker above the paragraph holding the page lines and pin the text it anchors\")\n .option(\"--quote\", \"the page lines are a fenced block that reproduces the source\")\n .option(\n \"--encrypt\",\n \"write source.file encrypted, with an hmac-sha256- pin; with no key, offer to create one (an available key encrypts without the flag)\",\n )\n .option(\"--no-commit-sha\", \"do not record HEAD\")\n .option(\"--dry-run\", \"print the diff; write nothing\")\n .option(\"--as <format>\", \"force the page format\")\n .option(\"--root <dir>\", \"directory source paths resolve from (as check)\")\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni cite add docs/limits.md:9 lib/limits.ts:2 --id fetch-timeout\",\n \" manni cite add docs/limits.md:30 lib/limits.ts:8-12 --id timeouts --marker\",\n \" manni cite add docs/limits.md:14-18 lib/limits.ts:1-3 --quote\",\n \" manni cite add docs/limits.md lib/limits.ts --dry-run\",\n \" cat page.md | manni cite add -:9 lib/limits.ts:2 --as markdown > out.md\",\n ].join(\"\\n\"),\n )\n .action(async (pageArgument: string, src: string, options: AddCliOptions) => {\n try {\n const { page, lines } = splitPageArgument(pageArgument);\n const usingStdin = page === STDIN_TOKEN;\n const stdinContent = usingStdin ? await readStdin() : undefined;\n const dryRun = Boolean(options.dryRun);\n const cwd = process.cwd();\n\n const result = await runAdd({\n page,\n pageLines: lines,\n src,\n id: options.id,\n marker: options.marker ? true : undefined,\n quote: options.quote ? true : undefined,\n // `undefined` when absent, so the key decides: an available one\n // encrypts without the flag.\n encrypt: options.encrypt ? true : undefined,\n commitSha: explicitFalse(options.commitSha),\n dryRun,\n as: options.as,\n ...configOption(options.config),\n // With `-` the page owns stdout; so does the diff under --dry-run.\n onConfigLoaded: reportConfig(!usingStdin && !dryRun, cwd),\n stdinContent,\n root: options.root,\n onNotice: notice,\n // Only on a terminal: off one, a missing key is a refusal, not a\n // question nobody can answer. With `-` stdin is the page, so no\n // question is put either.\n confirm: terminalConfirm(),\n });\n\n const message = addMessage(result);\n // A dry run prints every diff the write would make: the page's, and\n // the manifest's when the entry goes there.\n const diffs = [result.diff, result.manifest?.diff ?? \"\"].filter((d) => d.length > 0);\n if (usingStdin) {\n // The rewritten page owns stdout; everything else is a diagnostic.\n process.stdout.write(result.content);\n if (dryRun) for (const diff of diffs) process.stderr.write(`${diff}\\n`);\n process.stderr.write(`${message}\\n`);\n } else if (dryRun) {\n for (const diff of diffs) process.stdout.write(`${diff}\\n`);\n process.stderr.write(`${message}\\n`);\n } else {\n process.stdout.write(`${message}\\n`);\n }\n process.exitCode = 0;\n } catch (err) {\n fail(err);\n }\n });\n\n program\n .command(\"update\")\n .description(\"Rewrite moved citations in place; with --accept, re-mint changed ones\")\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to update (use - for stdin)\",\n )\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format for every input\")\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\")\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"update files .gitignore covers\")\n .option(\"--no-check-sources\", \"refused: update needs the sources\")\n .option(\"--root <dir>\", \"directory src: paths resolve from (as check)\")\n .option(\"--accept\", \"re-mint changed and never-true entries at HEAD; prints old and new pins\")\n .option(\n \"--recommit\",\n \"re-record commit-sha where the recorded commit does not contain the pinned lines, or is outside HEAD's history\",\n )\n .option(\"--only <id>\", \"limit to entries with this id; repeatable\", collect, [])\n .option(\"--dry-run\", \"print the diffs; write nothing\")\n .option(\n \"-f, --format <format>\",\n `output: ${UPDATE_FORMATS.join(\" | \")}`,\n \"pretty\",\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni cite update docs/ # rewrite moved entries\",\n \" manni cite update --accept --only fetch-timeout docs/limits.md\",\n \" manni cite update --dry-run docs/ # see the diffs first\",\n \" manni cite update --recommit docs/ # repair unsupported commit-sha\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: UpdateCliOptions, command: Command) => {\n try {\n const format = options.format;\n if (!isUpdateFormat(format)) {\n throw new CiteError(\n `Unknown --format \"${format}\". Use ${COMMON_FORMAT_LIST}.`,\n );\n }\n if (!options.checkSources) {\n throw new CiteError(\n \"update needs the sources: drop --no-check-sources (or `checkSources: false`).\",\n );\n }\n const exts = options.ext ? splitList(options.ext) : undefined;\n const usingStdin = paths.includes(STDIN_TOKEN);\n const stdinContent = usingStdin ? await readStdin() : undefined;\n const dryRun = Boolean(options.dryRun);\n // With `-` the rewritten page owns stdout, as it does for `add -`; a\n // dry run prints the diffs instead, so the report keeps stdout.\n const pageToStdout = usingStdin && !dryRun;\n const cwd = process.cwd();\n\n const run = await runUpdate({\n inputs: paths,\n collection: options.collection,\n exts,\n exclude: options.exclude,\n as: options.as,\n ...configOption(options.config),\n onConfigLoaded: reportConfig(format === \"pretty\" && !pageToStdout, cwd),\n stdinContent,\n allowEmpty: options.allowEmpty ? true : undefined,\n respectGitignore: explicitFalse(options.gitignore),\n onNotice: notice,\n root: options.root,\n accept: options.accept ? true : undefined,\n recommit: options.recommit ? true : undefined,\n only: options.only.length > 0 ? options.only : undefined,\n dryRun,\n });\n\n const text =\n format === \"json\"\n ? renderUpdateJson(run)\n : renderUpdatePretty(run, {\n color: colorFor(command, process.stdout.isTTY),\n // The diffs are the point of a dry run; a real run prints\n // what it rewrote and leaves the file to say the rest.\n showDiff: dryRun,\n });\n const stdinPage = pageToStdout ? run.pages.find((page) => page.content !== undefined) : undefined;\n if (stdinPage?.content !== undefined) {\n process.stdout.write(stdinPage.content);\n process.stderr.write(`${text}\\n`);\n } else {\n process.stdout.write(`${text}\\n`);\n }\n // Exit 1 when something was skipped with an error-severity finding:\n // work left undone, `fill`'s precedent.\n process.exitCode = run.exitCode;\n } catch (err) {\n fail(err);\n }\n });\n\n program\n .command(\"remove\")\n .description(\"Remove the named citations from the given pages, markers and all\")\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to remove from (use - for stdin)\",\n )\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format for every input\")\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\")\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"remove from files .gitignore covers\")\n .option(\n \"--only <id>\",\n \"the entry to remove, by id or by pointer (/citations/N); required, and repeatable\",\n collect,\n [],\n )\n .option(\"--dry-run\", \"print the diffs and the report; write nothing\")\n .option(\n \"-f, --format <format>\",\n `output: ${REMOVE_FORMATS.join(\" | \")}`,\n \"pretty\",\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni cite remove docs/limits.md --only fetch-timeout\",\n \" manni cite remove docs/ --only fetch-timeout --only retries --dry-run\",\n \" manni cite remove --collection site --only /citations/3 -f json\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: RemoveCliOptions, command: Command) => {\n try {\n const format = options.format;\n if (!isRemoveFormat(format)) {\n throw new CiteError(\n `Unknown --format \"${format}\". Use ${COMMON_FORMAT_LIST}.`,\n );\n }\n const exts = options.ext ? splitList(options.ext) : undefined;\n const usingStdin = paths.includes(STDIN_TOKEN);\n const stdinContent = usingStdin ? await readStdin() : undefined;\n const dryRun = Boolean(options.dryRun);\n // With `-` the rewritten page owns stdout, exactly as on `update -`.\n const pageToStdout = usingStdin && !dryRun;\n const cwd = process.cwd();\n\n const run = await runRemove({\n inputs: paths,\n collection: options.collection,\n exts,\n exclude: options.exclude,\n as: options.as,\n ...configOption(options.config),\n onConfigLoaded: reportConfig(format === \"pretty\" && !pageToStdout, cwd),\n stdinContent,\n allowEmpty: options.allowEmpty ? true : undefined,\n respectGitignore: explicitFalse(options.gitignore),\n onNotice: notice,\n only: options.only,\n dryRun,\n });\n\n const text =\n format === \"json\"\n ? renderRemoveJson(run)\n : renderRemovePretty(run, {\n color: colorFor(command, process.stdout.isTTY),\n // The diffs are the point of a dry run; a real run prints\n // what it removed and leaves the file to say the rest.\n showDiff: dryRun,\n dryRun,\n });\n const stdinPage = pageToStdout ? run.pages.find((page) => page.content !== undefined) : undefined;\n if (stdinPage?.content !== undefined) {\n process.stdout.write(stdinPage.content);\n process.stderr.write(`${text}\\n`);\n } else {\n process.stdout.write(`${text}\\n`);\n }\n // Everything named was removed, or previewed: there is no exit 1.\n process.exitCode = 0;\n } catch (err) {\n fail(err);\n }\n });\n\n return program;\n}\n","/**\n * SARIF for `check`. Meta's renderer builds the envelope, the\n * repository-relative uris and the fingerprints the baseline shares, from the\n * adapted results. What it cannot know is what a cite rule is: it describes\n * every rule as a schema keyword, links meta's fix page, and prefixes each\n * message with the JSON Pointer of the entry, `(root)` for a finding about no\n * entry. This renderer replaces those three with the cite rule's own\n * description, a link to its row of the citations reference, and the message\n * the github annotation carries, which names the citation the pointer only\n * numbered. A message is no part of a fingerprint, so the baseline is\n * unaffected.\n */\nimport { renderSarif, type ValidationResult } from \"../../meta/index.js\";\nimport { errorSite } from \"../core/adapt.js\";\nimport { RULE_ID_PREFIX, isCiteRule } from \"../core/severity.js\";\nimport type { CheckRun, CiteRule } from \"../types.js\";\nimport { findingMessage } from \"./github.js\";\n\nconst INFORMATION_URI = \"https://hawkeyexl.github.io/manni/cite/\";\n\n/** The citations reference, whose rule tables anchor each row by rule name. */\nconst RULES_URI = \"https://hawkeyexl.github.io/manni/cite/reference/citations/\";\n\n/** What each rule is, as the citations reference's tables say it. */\nconst RULE_DESCRIPTIONS: Readonly<Record<CiteRule, string>> = {\n \"source-moved\": \"The cited source lines moved to one other place in the file.\",\n \"source-moved-ambiguous\": \"The cited source lines now match at several places in the file.\",\n \"source-changed\": \"The cited source lines changed since the citation pinned them.\",\n \"source-never-true\": \"The pin never matched the source at the recorded commit.\",\n \"source-missing\": \"The cited source file is not tracked under the root, or cannot be decrypted.\",\n \"claim-moved\": \"The cited sentence moved to other lines of the page.\",\n \"claim-moved-ambiguous\": \"The cited sentence now appears at several places on the page.\",\n \"claim-reanchored\": \"The cited sentence's words are unchanged since the claim's baseline, and only its layout moved.\",\n \"claim-changed\": \"The cited sentence was edited since the citation pinned it.\",\n \"marker-orphan\": \"A marker names an id no citation has.\",\n \"marker-invalid\": \"A marker is malformed, or the page has too many markers.\",\n \"marker-repeated\": \"Two markers name the same citation id.\",\n \"marker-misplaced\": \"A marker line sits inside the paragraph it anchors, and splits it.\",\n \"anchor-invalid\": \"A citation's anchor cannot work.\",\n \"entry-invalid\": \"A citation entry is malformed.\",\n \"quote-drift\": \"A quoted block no longer reproduces its source.\",\n};\n\n/**\n * The label meta's reporters put before a message: `(root) ` for a finding\n * about no entry, `/citations/N ` for one about an entry. Nothing else ever\n * opens a cite finding's adapted message.\n */\nexport const ENTRY_LABEL = /^(?:\\(root\\)|\\/citations\\/\\d+) /;\n\nexport interface SarifRule {\n id: string;\n shortDescription: { text: string };\n helpUri?: string;\n}\n\n/** As much of meta's SARIF as this renderer and its tests read back. */\nexport interface SarifLog {\n runs: {\n tool: { driver: { informationUri: string; rules: SarifRule[] } };\n results: { ruleId: string; message: { text: string } }[];\n }[];\n}\n\n/**\n * The adapted results with each message rewritten as the github annotation\n * says it. An error is paired with its finding by rule, entry, line and\n * message, as the baseline split pairs them; the baseline has already\n * dropped the errors it forgives.\n */\nexport function withFindingMessages(run: CheckRun): ValidationResult[] {\n return run.results.map((result) => {\n const page = run.pages.find((p) => p.file === result.file);\n if (page === undefined) return result;\n const errors = result.errors.map((error) => {\n const finding = page.findings.find(\n (f) =>\n f.rule === error.keyword &&\n (f.index === undefined ? \"\" : `/citations/${String(f.index)}`) === error.instancePath &&\n f.message === error.message &&\n (errorSite(f).line ?? null) === (error.line ?? null),\n );\n return finding === undefined ? error : { ...error, message: findingMessage(finding) };\n });\n return { ...result, errors };\n });\n}\n\n/** A rule as the citation tool describes it. */\nfunction describe(rule: SarifRule): SarifRule {\n const name = rule.id.slice(RULE_ID_PREFIX.length + 1);\n if (!isCiteRule(name)) return rule;\n return { id: rule.id, shortDescription: { text: RULE_DESCRIPTIONS[name] }, helpUri: `${RULES_URI}#${name}` };\n}\n\nexport function renderCheckSarif(run: CheckRun, opts: { onNotice?: (message: string) => void } = {}): string {\n const log = JSON.parse(\n renderSarif(withFindingMessages(run), {\n frame: run.frame,\n ...(opts.onNotice === undefined ? {} : { onNotice: opts.onNotice }),\n }),\n ) as SarifLog;\n for (const sarifRun of log.runs) {\n sarifRun.tool.driver.informationUri = INFORMATION_URI;\n sarifRun.tool.driver.rules = sarifRun.tool.driver.rules.map(describe);\n for (const result of sarifRun.results) result.message.text = result.message.text.replace(ENTRY_LABEL, \"\");\n }\n return JSON.stringify(log, null, 2);\n}\n","/**\n * JUnit for `check`: meta's renderer over the adapted results, under the\n * `manni.cite` classname, with each failure's message the one the github\n * annotation carries.\n * Meta's renderer opens every message with the entry's JSON Pointer, `(root)`\n * for a finding about no entry, which says nothing about a citation. The\n * failure's `type` is already the rule id.\n */\nimport { renderJunit } from \"../../meta/index.js\";\nimport type { CheckRun } from \"../types.js\";\nimport { ENTRY_LABEL, withFindingMessages } from \"./sarif.js\";\n\n/** JUnit `classname` for the citation tool's findings. */\nexport const JUNIT_CLASSNAME = \"manni.cite\";\n\n/** A `message=\"` attribute's opening label. The value is escaped, so `message=\"` opens nothing else. */\nconst MESSAGE_LABEL = new RegExp(`message=\"${ENTRY_LABEL.source.replace(/^\\^/, \"\")}`, \"g\");\n\nexport function renderCheckJunit(run: CheckRun): string {\n return renderJunit(withFindingMessages(run), { frame: run.frame, classname: JUNIT_CLASSNAME }).replace(\n MESSAGE_LABEL,\n 'message=\"',\n );\n}\n"],"mappings":"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","names":["splitPageArgument"]}
1
+ {"version":3,"sources":["../src/cite/cli.ts","../src/cite/reporters/sarif.ts","../src/cite/reporters/junit.ts"],"sourcesContent":["/**\n * The `cite` domain's commander program. Mounted by `src/cli.ts` under\n * `manni cite`; no entry point of its own. Grammar per proposal 0034: verbs are\n * `check`, `add`, `update`, `remove`; there is no default subcommand.\n *\n * Follows clig.dev as meta's does: primary output to stdout, diagnostics to\n * stderr, colour only on a TTY and never under `NO_COLOR`/`--no-color`, exit\n * `0` clean, `1` an error-severity finding, `2` operational/usage.\n */\nimport { Command, Option } from \"commander\";\nimport pkg from \"../../package.json\" with { type: \"json\" };\nimport {\n collect,\n configOption,\n explicitFalse,\n readStdin,\n reportConfig,\n splitList,\n} from \"../shared/cli-options.js\";\nimport { shouldColor } from \"../shared/color.js\";\nimport { splitPageArgument as splitSharedPageArgument } from \"../shared/pin.js\";\nimport { terminalConfirm } from \"../shared/prompt.js\";\nimport { fail } from \"../shared/run.js\";\nimport { notice } from \"../shared/warn.js\";\nimport {\n COMMON_FORMAT_LIST,\n OMITTED_WHEN_CLEAN,\n REPORT_FORMAT_LIST,\n STDIN_TOKEN,\n isMachineFormat,\n} from \"../meta/internal.js\";\nimport { REPORT_FORMATS, isReportFormat } from \"../meta/index.js\";\nimport { runAdd } from \"./commands/add.js\";\nimport { runCheck } from \"./commands/check.js\";\nimport { runRemove } from \"./commands/remove.js\";\nimport { runUpdate } from \"./commands/update.js\";\nimport { CiteError, asCiteError } from \"./errors.js\";\nimport { spellSource } from \"./core/range.js\";\nimport { shortCommit, shortLine, shortPin, shortSrc } from \"./core/spell.js\";\nimport { renderCheckGithub } from \"./reporters/github.js\";\nimport { renderCheckJson, renderRemoveJson, renderUpdateJson } from \"./reporters/json.js\";\nimport { renderCheckJunit } from \"./reporters/junit.js\";\nimport { renderCheckPretty, renderRemovePretty, renderUpdatePretty } from \"./reporters/pretty.js\";\nimport { renderCheckSarif } from \"./reporters/sarif.js\";\nimport type { AddResult, PageLines } from \"./types.js\";\n\nconst UPDATE_FORMATS = [\"pretty\", \"json\"] as const;\ntype UpdateFormat = (typeof UPDATE_FORMATS)[number];\n/** The same two `update` has: a removal is a write, and writes report alike. */\nconst REMOVE_FORMATS = UPDATE_FORMATS;\ntype RemoveFormat = UpdateFormat;\n\n/**\n * Whether `command`'s output gets colour: this domain's `--no-color` and\n * `NO_COLOR` turn it off, and otherwise only a TTY turns it on\n * (`shouldColor`). `isTTY` is passed uncoerced: Node leaves it undefined off\n * a terminal, never false, and `shouldColor` reads a missing one as \"not a\n * terminal\".\n */\nexport function colorFor(\n command: Command,\n isTTY: boolean | undefined,\n env?: NodeJS.ProcessEnv,\n): boolean {\n // commander maps --no-color to opts.color === false, on the command that\n // declares it.\n const noColor = colorOwner(command).opts().color === false;\n return shouldColor({ noColor, isTTY, env });\n}\n\n/**\n * The nearest command, this one or an ancestor, that declares `--no-color`:\n * the `cite` program, wherever it is mounted. Not the root: under the\n * umbrella that is `manni`, which has no `--no-color` of its own.\n */\nfunction colorOwner(command: Command): Command {\n for (let c: Command | null = command; c !== null; c = c.parent) {\n if (c.options.some((o) => o.long === \"--no-color\")) return c;\n }\n return command;\n}\n\nfunction isUpdateFormat(value: string): value is UpdateFormat {\n return (UPDATE_FORMATS as readonly string[]).includes(value);\n}\n\nfunction isRemoveFormat(value: string): value is RemoveFormat {\n return (REMOVE_FORMATS as readonly string[]).includes(value);\n}\n\n/**\n * Commander hands an `.action()` callback an untyped bag of option values, so\n * each subcommand declares the shape it actually reads. The `--no-<thing>`\n * flags are `boolean` and never `undefined`: commander supplies `true` when\n * the flag is absent, which is its default and not a choice, so only the\n * explicit `false` travels to the core (`explicitFalse`).\n */\ninterface InputCliOptions {\n /** `--collection <name>`, repeatable; commander's default value is `[]`. */\n collection: string[];\n /** `--ext <list>`; the command splits it. */\n ext?: string;\n /** `--exclude <glob>`, repeatable; commander's default value is `[]`. */\n exclude: string[];\n /** `--as <format>`: force an extractor. */\n as?: string;\n /**\n * `-c, --config <path>` and `--no-config` share one commander attribute:\n * `undefined` with neither flag, the path with `-c`, `false` with\n * `--no-config`. Split by `configOption`.\n */\n config?: string | boolean;\n allowEmpty?: boolean;\n /** `--no-gitignore`. */\n gitignore: boolean;\n /** `--root <dir>`: where `src:` paths resolve from. */\n root?: string;\n}\n\ninterface CheckCliOptions extends InputCliOptions {\n /** `-f, --format <format>`. Always a string: the declaration has a default. */\n format: string;\n quiet?: boolean;\n /**\n * `--baseline [path]` / `--no-baseline`, the same three-state split as\n * `config`: absent leaves the config in charge, a string names a file, `true`\n * is a bare `--baseline` (the default path), `false` is `--no-baseline`.\n */\n baseline?: string | boolean;\n /** `--write-baseline [path]`; `true` for the bare flag. */\n writeBaseline?: string | boolean;\n /** `--no-check-sources`. */\n checkSources: boolean;\n showDiff?: boolean;\n reveal?: boolean;\n}\n\ninterface AddCliOptions {\n id?: string;\n marker?: boolean;\n quote?: boolean;\n /** `--encrypt`. */\n encrypt?: boolean;\n /** `--no-commit-sha`. */\n commitSha: boolean;\n dryRun?: boolean;\n as?: string;\n root?: string;\n config?: string | boolean;\n}\n\ninterface RemoveCliOptions extends Omit<InputCliOptions, \"root\"> {\n /** `--only <id>`, repeatable; commander's default value is `[]`. */\n only: string[];\n dryRun?: boolean;\n format: string;\n}\n\ninterface UpdateCliOptions extends InputCliOptions {\n /** `--no-check-sources`: declared so the refusal names the flag rather than commander rejecting it. */\n checkSources: boolean;\n accept?: boolean;\n recommit?: boolean;\n /** `--only <id>`, repeatable; commander's default value is `[]`. */\n only: string[];\n dryRun?: boolean;\n format: string;\n}\n\n/**\n * Split `docs/limits.md:9` or `docs/limits.md:14-18` into the page and the\n * claim's lines, under cite's error contract. The parsing is the shared pin\n * engine's (`splitPageArgument` in `src/shared/pin.ts`).\n */\nexport function splitPageArgument(arg: string): { page: string; lines?: PageLines } {\n return asCiteError(() => splitSharedPageArgument(arg));\n}\n\n/** `line 9`, or `lines 14-18` for a range. */\nfunction spellAt(lines: PageLines, noun = \"line\"): string {\n return lines.start === lines.end\n ? `${noun} ${String(lines.start)}`\n : `${noun}s ${String(lines.start)}-${String(lines.end)}`;\n}\n\n/**\n * What `add` says on success. One sentence composed from the result: what was\n * added, where it went, and what each end is pinned to. Lines are the page's\n * own, after the write. The source is spelled as it was written to the page,\n * abbreviated when it is a ciphertext, and quoted with its first pinned line\n * where the result carries one.\n */\nexport function addMessage(result: AddResult): string {\n const { citation, claimLines } = result;\n const claim = citation.claim;\n const name = citation.id ?? (claim === undefined ? \"a bare pin\" : \"an entry\");\n const src = shortSrc(spellSource(citation.source));\n const commit = citation.source[\"commit-sha\"];\n const quoted = result.sourceLine === undefined ? \"\" : shortLine(result.sourceLine);\n const line = quoted === \"\" ? \"\" : ` \"${quoted}\"`;\n const pin = `${src}${line}, ${shortPin(citation.source.integrity)}, ${commit === undefined ? \"no commit\" : shortCommit(commit)}`;\n // Where it went: the page's own frontmatter, or the manifest that owns the\n // page's citations, at the line the entry now sits on.\n const where =\n result.manifest === undefined\n ? \"frontmatter\"\n : `${result.manifest.file}:${String(result.manifest.line)}`;\n const head = `${result.file}: added ${name} to ${where}`;\n\n if (result.markerLine !== undefined) {\n const at =\n claimLines === undefined ? \"\" : `, claim pinned at ${spellAt(claimLines)}`;\n const wrote = result.markerJoined === true ? \"joined the marker at line\" : \"marker at line\";\n const marked = `${head}; ${wrote} ${String(result.markerLine)}${at}`;\n if (claim === undefined) return marked;\n if (citation.quote === true) return `${marked} (a block that reproduces ${src})`;\n return `${marked} (${shortPin(claim.integrity)}; source ${pin})`;\n }\n if (claim === undefined || claimLines === undefined) {\n return `${head} (source ${pin})`;\n }\n if (citation.quote === true) {\n return `${head} (claim ${spellAt(claimLines, \"line\")}, a block that reproduces ${src})`;\n }\n return `${head} (claim at ${spellAt(claimLines)}, ${shortPin(claim.integrity)}; source ${pin})`;\n}\n\nexport function buildProgram(): Command {\n const program = new Command();\n program\n .name(\"cite\")\n .description(\n \"Track citations from doc claims to source lines and check them for drift.\",\n )\n .version(pkg.version, \"-V, --version\")\n .option(\"--no-color\", \"disable colored output\")\n // A pointer, not the whole help screen: the message that precedes it\n // already names the offending flag.\n .showHelpAfterError(\"(add --help for usage)\")\n // MUST come before the `.command()` calls below. `copyInheritedSettings`\n // copies `_exitCallback` by value at subcommand-creation time, so an\n // `exitOverride()` installed afterwards leaves every subcommand still\n // calling `process.exit(1)`.\n .exitOverride();\n\n program\n .command(\"check\")\n .description(\"Check every citation in the given pages against its source\")\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to check (use - for stdin)\",\n )\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format for every input\")\n .option(\n \"-f, --format <format>\",\n `output: ${REPORT_FORMATS.join(\" | \")}`,\n \"pretty\",\n )\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\")\n .option(\"-q, --quiet\", \"in pretty output, hide current citations and clean files\")\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"check files .gitignore covers\")\n // No `defaultValue` and no `.preset()`, for the reasons meta's validate\n // gives: a bare flag must stay distinguishable from a typed path.\n .addOption(\n new Option(\n \"--baseline [path]\",\n \"compare against a baseline; fail only on findings not in it\",\n ),\n )\n .addOption(\n new Option(\n \"--write-baseline [path]\",\n \"record current findings as the baseline, then exit 0\",\n ),\n )\n .option(\"--no-baseline\", \"ignore a baseline configured by `baseline:`\")\n .option(\"--no-check-sources\", \"page-side rules only; every source status is skipped\")\n .option(\n \"--root <dir>\",\n \"directory src: paths resolve from (default: cite.root from config, else the git root, else the current directory)\",\n )\n .option(\"--show-diff\", \"in pretty output, print the diff and commit subjects for changed\")\n .option(\"--reveal\", \"in pretty output, print the decrypted path beside an encrypted source\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni cite check docs/ # walk a directory\",\n \" manni cite check --collection guides # one configured collection\",\n ' manni cite check \"docs/**/*.md\" -f github # CI annotations',\n \" manni cite check --show-diff docs/limits.md # see what changed\",\n \" manni cite check --baseline # fail only on new findings\",\n \" cat page.md | manni cite check - --as markdown\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: CheckCliOptions, command: Command) => {\n try {\n const format = options.format;\n if (!isReportFormat(format)) {\n throw new CiteError(\n `Unknown --format \"${format}\". Use ${REPORT_FORMAT_LIST}.`,\n );\n }\n const exts = options.ext ? splitList(options.ext) : undefined;\n const stdinContent = paths.includes(STDIN_TOKEN) ? await readStdin() : undefined;\n const cwd = process.cwd();\n\n const run = await runCheck({\n inputs: paths,\n collection: options.collection,\n exts,\n exclude: options.exclude,\n as: options.as,\n ...configOption(options.config),\n onConfigLoaded: reportConfig(!isMachineFormat(format), cwd),\n stdinContent,\n // `undefined` rather than `false` when absent, so config still wins.\n allowEmpty: options.allowEmpty ? true : undefined,\n respectGitignore: explicitFalse(options.gitignore),\n onNotice: notice,\n baseline: options.baseline,\n writeBaseline: options.writeBaseline,\n checkSources: explicitFalse(options.checkSources),\n // Only so the run can say git is not there to give diffs; the diffs\n // themselves are the pretty reporter's.\n showDiff: options.showDiff ? true : undefined,\n root: options.root,\n });\n\n let text: string;\n switch (format) {\n case \"pretty\":\n text = renderCheckPretty(run, {\n color: colorFor(command, process.stdout.isTTY),\n quiet: Boolean(options.quiet),\n showDiff: Boolean(options.showDiff),\n reveal: Boolean(options.reveal),\n });\n break;\n case \"json\":\n text = renderCheckJson(run);\n break;\n case \"github\":\n text = renderCheckGithub(run);\n break;\n case \"sarif\":\n text = renderCheckSarif(run, { onNotice: notice });\n break;\n case \"junit\":\n text = renderCheckJunit(run);\n break;\n }\n // Only `github` may say nothing on a clean run; every other format\n // owes its envelope even when empty.\n if (text.length > 0 || !OMITTED_WHEN_CLEAN.has(format)) {\n process.stdout.write(`${text}\\n`);\n }\n // `failed` counts files with an unbaselined error-severity finding;\n // warnings never move it.\n process.exitCode = run.summary.failed > 0 ? 1 : 0;\n } catch (err) {\n fail(err);\n }\n });\n\n program\n .command(\"add\")\n .description(\"Mint a citation for a source range and write it to a page\")\n .argument(\n \"<page>\",\n \"the page to cite from, with the claim's lines: page:L or page:L1-L2 (use - for stdin, with --as)\",\n )\n .argument(\n \"<src>\",\n \"path, path:L or path:L1-L2 relative to --root, or an encrypted ~source with the same line forms\",\n )\n .option(\"--id <id>\", \"kebab-case id, unique on the page; required with --marker\")\n .option(\"--marker\", \"write a cite <id> marker above the paragraph holding the page lines and pin the text it anchors\")\n .option(\"--quote\", \"the page lines are a fenced block that reproduces the source\")\n .option(\n \"--encrypt\",\n \"write source.file encrypted, with an hmac-sha256- pin; with no key, offer to create one (an available key encrypts without the flag)\",\n )\n .option(\"--no-commit-sha\", \"do not record HEAD\")\n .option(\"--dry-run\", \"print the diff; write nothing\")\n .option(\"--as <format>\", \"force the page format\")\n .option(\"--root <dir>\", \"directory source paths resolve from (as check)\")\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\")\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni cite add docs/limits.md:9 lib/limits.ts:2 --id fetch-timeout\",\n \" manni cite add docs/limits.md:30 lib/limits.ts:8-12 --id timeouts --marker\",\n \" manni cite add docs/limits.md:14-18 lib/limits.ts:1-3 --quote\",\n \" manni cite add docs/limits.md lib/limits.ts --dry-run\",\n \" cat page.md | manni cite add -:9 lib/limits.ts:2 --as markdown > out.md\",\n ].join(\"\\n\"),\n )\n .action(async (pageArgument: string, src: string, options: AddCliOptions) => {\n try {\n const { page, lines } = splitPageArgument(pageArgument);\n const usingStdin = page === STDIN_TOKEN;\n const stdinContent = usingStdin ? await readStdin() : undefined;\n const dryRun = Boolean(options.dryRun);\n const cwd = process.cwd();\n\n const result = await runAdd({\n page,\n pageLines: lines,\n src,\n id: options.id,\n marker: options.marker ? true : undefined,\n quote: options.quote ? true : undefined,\n // `undefined` when absent, so the key decides: an available one\n // encrypts without the flag.\n encrypt: options.encrypt ? true : undefined,\n commitSha: explicitFalse(options.commitSha),\n dryRun,\n as: options.as,\n ...configOption(options.config),\n // With `-` the page owns stdout; so does the diff under --dry-run.\n onConfigLoaded: reportConfig(!usingStdin && !dryRun, cwd),\n stdinContent,\n root: options.root,\n onNotice: notice,\n // Only on a terminal: off one, a missing key is a refusal, not a\n // question nobody can answer. With `-` stdin is the page, so no\n // question is put either.\n confirm: terminalConfirm(),\n });\n\n const message = addMessage(result);\n // A dry run prints every diff the write would make: the page's, and\n // the manifest's when the entry goes there.\n const diffs = [result.diff, result.manifest?.diff ?? \"\"].filter((d) => d.length > 0);\n if (usingStdin) {\n // The rewritten page owns stdout; everything else is a diagnostic.\n process.stdout.write(result.content);\n if (dryRun) for (const diff of diffs) process.stderr.write(`${diff}\\n`);\n process.stderr.write(`${message}\\n`);\n } else if (dryRun) {\n for (const diff of diffs) process.stdout.write(`${diff}\\n`);\n process.stderr.write(`${message}\\n`);\n } else {\n process.stdout.write(`${message}\\n`);\n }\n process.exitCode = 0;\n } catch (err) {\n fail(err);\n }\n });\n\n program\n .command(\"update\")\n .description(\"Rewrite moved citations in place; with --accept, re-mint changed ones\")\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to update (use - for stdin)\",\n )\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format for every input\")\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\")\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"update files .gitignore covers\")\n .option(\"--no-check-sources\", \"refused: update needs the sources\")\n .option(\"--root <dir>\", \"directory src: paths resolve from (as check)\")\n .option(\"--accept\", \"re-mint changed and never-true entries at HEAD; prints old and new pins\")\n .option(\n \"--recommit\",\n \"re-record commit-sha where the recorded commit does not contain the pinned lines, or is outside HEAD's history\",\n )\n .option(\"--only <id>\", \"limit to entries with this id; repeatable\", collect, [])\n .option(\"--dry-run\", \"print the diffs; write nothing\")\n .option(\n \"-f, --format <format>\",\n `output: ${UPDATE_FORMATS.join(\" | \")}`,\n \"pretty\",\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni cite update docs/ # rewrite moved entries\",\n \" manni cite update --accept --only fetch-timeout docs/limits.md\",\n \" manni cite update --dry-run docs/ # see the diffs first\",\n \" manni cite update --recommit docs/ # repair unsupported commit-sha\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: UpdateCliOptions, command: Command) => {\n try {\n const format = options.format;\n if (!isUpdateFormat(format)) {\n throw new CiteError(\n `Unknown --format \"${format}\". Use ${COMMON_FORMAT_LIST}.`,\n );\n }\n if (!options.checkSources) {\n throw new CiteError(\n \"update needs the sources: drop --no-check-sources (or `checkSources: false`).\",\n );\n }\n const exts = options.ext ? splitList(options.ext) : undefined;\n const usingStdin = paths.includes(STDIN_TOKEN);\n const stdinContent = usingStdin ? await readStdin() : undefined;\n const dryRun = Boolean(options.dryRun);\n // With `-` the rewritten page owns stdout, as it does for `add -`; a\n // dry run prints the diffs instead, so the report keeps stdout.\n const pageToStdout = usingStdin && !dryRun;\n const cwd = process.cwd();\n\n const run = await runUpdate({\n inputs: paths,\n collection: options.collection,\n exts,\n exclude: options.exclude,\n as: options.as,\n ...configOption(options.config),\n onConfigLoaded: reportConfig(format === \"pretty\" && !pageToStdout, cwd),\n stdinContent,\n allowEmpty: options.allowEmpty ? true : undefined,\n respectGitignore: explicitFalse(options.gitignore),\n onNotice: notice,\n root: options.root,\n accept: options.accept ? true : undefined,\n recommit: options.recommit ? true : undefined,\n only: options.only.length > 0 ? options.only : undefined,\n dryRun,\n });\n\n const text =\n format === \"json\"\n ? renderUpdateJson(run)\n : renderUpdatePretty(run, {\n color: colorFor(command, process.stdout.isTTY),\n // The diffs are the point of a dry run; a real run prints\n // what it rewrote and leaves the file to say the rest.\n showDiff: dryRun,\n });\n const stdinPage = pageToStdout ? run.pages.find((page) => page.content !== undefined) : undefined;\n if (stdinPage?.content !== undefined) {\n process.stdout.write(stdinPage.content);\n process.stderr.write(`${text}\\n`);\n } else {\n process.stdout.write(`${text}\\n`);\n }\n // Exit 1 when something was skipped with an error-severity finding:\n // work left undone, `fill`'s precedent.\n process.exitCode = run.exitCode;\n } catch (err) {\n fail(err);\n }\n });\n\n program\n .command(\"remove\")\n .description(\"Remove the named citations from the given pages, markers and all\")\n .argument(\n \"[paths...]\",\n \"files, directories, or globs to remove from (use - for stdin)\",\n )\n .option(\n \"--collection <name>\",\n \"configured collection to run over; repeatable\",\n collect,\n [],\n )\n .option(\"--ext <list>\", \"comma-separated extensions for directory walks\")\n .option(\"--exclude <glob>\", \"glob to exclude; repeatable\", collect, [])\n .option(\"--as <format>\", \"force an input format for every input\")\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .option(\"--no-config\", \"ignore any discovered config file\")\n .option(\"--allow-empty\", \"treat zero matched files as success\")\n .option(\"--no-gitignore\", \"remove from files .gitignore covers\")\n .option(\n \"--only <id>\",\n \"the entry to remove, by id or by pointer (/citations/N); required, and repeatable\",\n collect,\n [],\n )\n .option(\"--dry-run\", \"print the diffs and the report; write nothing\")\n .option(\n \"-f, --format <format>\",\n `output: ${REMOVE_FORMATS.join(\" | \")}`,\n \"pretty\",\n )\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni cite remove docs/limits.md --only fetch-timeout\",\n \" manni cite remove docs/ --only fetch-timeout --only retries --dry-run\",\n \" manni cite remove --collection site --only /citations/3 -f json\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: RemoveCliOptions, command: Command) => {\n try {\n const format = options.format;\n if (!isRemoveFormat(format)) {\n throw new CiteError(\n `Unknown --format \"${format}\". Use ${COMMON_FORMAT_LIST}.`,\n );\n }\n const exts = options.ext ? splitList(options.ext) : undefined;\n const usingStdin = paths.includes(STDIN_TOKEN);\n const stdinContent = usingStdin ? await readStdin() : undefined;\n const dryRun = Boolean(options.dryRun);\n // With `-` the rewritten page owns stdout, exactly as on `update -`.\n const pageToStdout = usingStdin && !dryRun;\n const cwd = process.cwd();\n\n const run = await runRemove({\n inputs: paths,\n collection: options.collection,\n exts,\n exclude: options.exclude,\n as: options.as,\n ...configOption(options.config),\n onConfigLoaded: reportConfig(format === \"pretty\" && !pageToStdout, cwd),\n stdinContent,\n allowEmpty: options.allowEmpty ? true : undefined,\n respectGitignore: explicitFalse(options.gitignore),\n onNotice: notice,\n only: options.only,\n dryRun,\n });\n\n const text =\n format === \"json\"\n ? renderRemoveJson(run)\n : renderRemovePretty(run, {\n color: colorFor(command, process.stdout.isTTY),\n // The diffs are the point of a dry run; a real run prints\n // what it removed and leaves the file to say the rest.\n showDiff: dryRun,\n dryRun,\n });\n const stdinPage = pageToStdout ? run.pages.find((page) => page.content !== undefined) : undefined;\n if (stdinPage?.content !== undefined) {\n process.stdout.write(stdinPage.content);\n process.stderr.write(`${text}\\n`);\n } else {\n process.stdout.write(`${text}\\n`);\n }\n // Everything named was removed, or previewed: there is no exit 1.\n process.exitCode = 0;\n } catch (err) {\n fail(err);\n }\n });\n\n return program;\n}\n","/**\n * SARIF for `check`. Meta's renderer builds the envelope, the\n * repository-relative uris and the fingerprints the baseline shares, from the\n * adapted results. What it cannot know is what a cite rule is: it describes\n * every rule as a schema keyword, links meta's fix page, and prefixes each\n * message with the JSON Pointer of the entry, `(root)` for a finding about no\n * entry. This renderer replaces those three with the cite rule's own\n * description, a link to its row of the citations reference, and the message\n * the github annotation carries, which names the citation the pointer only\n * numbered. A message is no part of a fingerprint, so the baseline is\n * unaffected.\n */\nimport { renderSarif, type ValidationResult } from \"../../meta/index.js\";\nimport { errorSite } from \"../core/adapt.js\";\nimport { RULE_ID_PREFIX, isCiteRule } from \"../core/severity.js\";\nimport type { CheckRun, CiteRule } from \"../types.js\";\nimport { findingMessage } from \"./github.js\";\n\nconst INFORMATION_URI = \"https://hawkeyexl.github.io/manni/cite/\";\n\n/** The citations reference, whose rule tables anchor each row by rule name. */\nconst RULES_URI = \"https://hawkeyexl.github.io/manni/cite/reference/citations/\";\n\n/** What each rule is, as the citations reference's tables say it. */\nconst RULE_DESCRIPTIONS: Readonly<Record<CiteRule, string>> = {\n \"source-moved\": \"The cited source lines moved to one other place in the file.\",\n \"source-moved-ambiguous\": \"The cited source lines now match at several places in the file.\",\n \"source-changed\": \"The cited source lines changed since the citation pinned them.\",\n \"source-never-true\": \"The pin never matched the source at the recorded commit.\",\n \"source-missing\": \"The cited source file is not tracked under the root, or cannot be decrypted.\",\n \"claim-moved\": \"The cited sentence moved to other lines of the page.\",\n \"claim-moved-ambiguous\": \"The cited sentence now appears at several places on the page.\",\n \"claim-reanchored\": \"The cited sentence's words are unchanged since the claim's baseline, and only its layout moved.\",\n \"claim-changed\": \"The cited sentence was edited since the citation pinned it.\",\n \"marker-orphan\": \"A marker names an id no citation has.\",\n \"marker-invalid\": \"A marker is malformed, or the page has too many markers.\",\n \"marker-repeated\": \"Two markers name the same citation id.\",\n \"marker-misplaced\": \"A marker line sits inside the paragraph it anchors, and splits it.\",\n \"anchor-invalid\": \"A citation's anchor cannot work.\",\n \"entry-invalid\": \"A citation entry is malformed.\",\n \"quote-drift\": \"A quoted block no longer reproduces its source.\",\n};\n\n/**\n * The label meta's reporters put before a message: `(root) ` for a finding\n * about no entry, `/citations/N ` for one about an entry. Nothing else ever\n * opens a cite finding's adapted message.\n */\nexport const ENTRY_LABEL = /^(?:\\(root\\)|\\/citations\\/\\d+) /;\n\nexport interface SarifRule {\n id: string;\n shortDescription: { text: string };\n helpUri?: string;\n}\n\n/** As much of meta's SARIF as this renderer and its tests read back. */\nexport interface SarifLog {\n runs: {\n tool: { driver: { informationUri: string; rules: SarifRule[] } };\n results: { ruleId: string; message: { text: string } }[];\n }[];\n}\n\n/**\n * The adapted results with each message rewritten as the github annotation\n * says it. An error is paired with its finding by rule, entry, line and\n * message, as the baseline split pairs them; the baseline has already\n * dropped the errors it forgives.\n */\nexport function withFindingMessages(run: CheckRun): ValidationResult[] {\n return run.results.map((result) => {\n const page = run.pages.find((p) => p.file === result.file);\n if (page === undefined) return result;\n const errors = result.errors.map((error) => {\n const finding = page.findings.find(\n (f) =>\n f.rule === error.keyword &&\n (f.index === undefined ? \"\" : `/citations/${String(f.index)}`) === error.instancePath &&\n f.message === error.message &&\n (errorSite(f).line ?? null) === (error.line ?? null),\n );\n return finding === undefined ? error : { ...error, message: findingMessage(finding) };\n });\n return { ...result, errors };\n });\n}\n\n/** A rule as the citation tool describes it. */\nfunction describe(rule: SarifRule): SarifRule {\n const name = rule.id.slice(RULE_ID_PREFIX.length + 1);\n if (!isCiteRule(name)) return rule;\n return { id: rule.id, shortDescription: { text: RULE_DESCRIPTIONS[name] }, helpUri: `${RULES_URI}#${name}` };\n}\n\nexport function renderCheckSarif(run: CheckRun, opts: { onNotice?: (message: string) => void } = {}): string {\n const log = JSON.parse(\n renderSarif(withFindingMessages(run), {\n frame: run.frame,\n ...(opts.onNotice === undefined ? {} : { onNotice: opts.onNotice }),\n }),\n ) as SarifLog;\n for (const sarifRun of log.runs) {\n sarifRun.tool.driver.informationUri = INFORMATION_URI;\n sarifRun.tool.driver.rules = sarifRun.tool.driver.rules.map(describe);\n for (const result of sarifRun.results) result.message.text = result.message.text.replace(ENTRY_LABEL, \"\");\n }\n return JSON.stringify(log, null, 2);\n}\n","/**\n * JUnit for `check`: meta's renderer over the adapted results, under the\n * `manni.cite` classname, with each failure's message the one the github\n * annotation carries.\n * Meta's renderer opens every message with the entry's JSON Pointer, `(root)`\n * for a finding about no entry, which says nothing about a citation. The\n * failure's `type` is already the rule id.\n */\nimport { renderJunit } from \"../../meta/index.js\";\nimport type { CheckRun } from \"../types.js\";\nimport { ENTRY_LABEL, withFindingMessages } from \"./sarif.js\";\n\n/** JUnit `classname` for the citation tool's findings. */\nexport const JUNIT_CLASSNAME = \"manni.cite\";\n\n/** A `message=\"` attribute's opening label. The value is escaped, so `message=\"` opens nothing else. */\nconst MESSAGE_LABEL = new RegExp(`message=\"${ENTRY_LABEL.source.replace(/^\\^/, \"\")}`, \"g\");\n\nexport function renderCheckJunit(run: CheckRun): string {\n return renderJunit(withFindingMessages(run), { frame: run.frame, classname: JUNIT_CLASSNAME }).replace(\n MESSAGE_LABEL,\n 'message=\"',\n );\n}\n"],"mappings":"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","names":["splitPageArgument"]}
@@ -4,18 +4,21 @@ import {
4
4
  parseQueryParams,
5
5
  resolveGetInputs,
6
6
  resolveQueryInputs
7
- } from "./chunk-6LR73NMO.js";
8
- import "./chunk-2W34HX2U.js";
9
- import "./chunk-KBG463UK.js";
10
- import "./chunk-QBVP3SQP.js";
11
- import "./chunk-G7XD4QH5.js";
12
- import "./chunk-YEUYKR62.js";
13
- import "./chunk-RNVYGWIC.js";
7
+ } from "./chunk-DLU5FCFT.js";
8
+ import "./chunk-PS257NIU.js";
9
+ import "./chunk-2OZF2VUB.js";
10
+ import "./chunk-SGR7ZAVE.js";
11
+ import "./chunk-QEAGL4V5.js";
12
+ import "./chunk-SMHAYK6I.js";
13
+ import "./chunk-DSWKBZWW.js";
14
+ import "./chunk-RGLFV4KO.js";
14
15
  import "./chunk-MNH7QO4Z.js";
15
- import "./chunk-6M5VJOC2.js";
16
+ import "./chunk-RNVYGWIC.js";
17
+ import "./chunk-YEUYKR62.js";
18
+ import "./chunk-OTJOBZJ5.js";
16
19
  import "./chunk-HX44GB4Z.js";
17
- import "./chunk-QCHVR4ZM.js";
18
- import "./chunk-2BV4FBC7.js";
20
+ import "./chunk-VM7VAFJW.js";
21
+ import "./chunk-DHGB4JBG.js";
19
22
  import "./chunk-OWBRDNRZ.js";
20
23
  import "./chunk-G3T47CFV.js";
21
24
  import "./chunk-2H7UOFLK.js";
@@ -25,4 +28,4 @@ export {
25
28
  resolveGetInputs,
26
29
  resolveQueryInputs
27
30
  };
28
- //# sourceMappingURL=cli-HO62TOM2.js.map
31
+ //# sourceMappingURL=cli-BOMA2FMP.js.map