@hawkeyexl/manni 4.9.0 → 4.11.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 (196) hide show
  1. package/README.md +1 -1
  2. package/dist/{batch-W5GXL2P4.js → batch-UAULUMGH.js} +18 -14
  3. package/dist/{build-Q56FEXR6.js → build-QSPNK5AL.js} +14 -11
  4. package/dist/calibrate-KXN4URPM.js +40 -0
  5. package/dist/{capture-GMYH4ATL.js → capture-JHTSUPUC.js} +16 -13
  6. package/dist/{check-OAJWC3WD.js → check-MDGXEUWL.js} +5 -5
  7. package/dist/{check-KUBELO5G.js → check-VELUQAUW.js} +17 -14
  8. package/dist/{check-KUBELO5G.js.map → check-VELUQAUW.js.map} +1 -1
  9. package/dist/check-WOQRKNZK.js +29 -0
  10. package/dist/{check-ZE5HIDOW.js → check-YEOYBFST.js} +14 -11
  11. package/dist/{chunk-FGUXMZXO.js → chunk-2DRHT73U.js} +7 -7
  12. package/dist/{chunk-XHFHXOQQ.js → chunk-2IAZEB45.js} +8 -8
  13. package/dist/{chunk-35WTFPQS.js → chunk-2IR4T5PO.js} +2 -2
  14. package/dist/{chunk-KX5IYIOO.js → chunk-2MJ62AYQ.js} +2 -2
  15. package/dist/chunk-2MJ62AYQ.js.map +1 -0
  16. package/dist/{chunk-OWSNXPPX.js → chunk-4CK6ZSOK.js} +6 -6
  17. package/dist/{chunk-YUZ2ECZY.js → chunk-4D5IZSXM.js} +3 -3
  18. package/dist/{chunk-RFSGKF4O.js → chunk-4VBSTXN6.js} +4 -4
  19. package/dist/{chunk-3XMG4CZY.js → chunk-54F74XR3.js} +15 -13
  20. package/dist/{chunk-3XMG4CZY.js.map → chunk-54F74XR3.js.map} +1 -1
  21. package/dist/{chunk-IN6DWNVE.js → chunk-6HWBRZIN.js} +47 -191
  22. package/dist/chunk-6HWBRZIN.js.map +1 -0
  23. package/dist/{chunk-GEMXGXPR.js → chunk-ADMEPUBT.js} +3 -3
  24. package/dist/{chunk-23UAGEKP.js → chunk-B7XYNRJQ.js} +2 -2
  25. package/dist/{chunk-QKE3XS2L.js → chunk-BBT6AVUG.js} +2 -2
  26. package/dist/{chunk-VKWZCEWB.js → chunk-BKVHX6FU.js} +4 -4
  27. package/dist/{chunk-X6WLCNKC.js → chunk-D4N2V43Z.js} +4 -4
  28. package/dist/{chunk-XXDXIIQ4.js → chunk-EFW7CAG4.js} +2 -2
  29. package/dist/{chunk-UDUHRXJ4.js → chunk-EIFCP6CZ.js} +2 -2
  30. package/dist/{chunk-KPXOJMQ6.js → chunk-FBMZJEB3.js} +2 -2
  31. package/dist/{chunk-HRXDM6H6.js → chunk-FQXWVS6J.js} +8 -8
  32. package/dist/{chunk-76I6I5N2.js → chunk-FUCPZVRY.js} +2 -2
  33. package/dist/{chunk-DTGIUMZV.js → chunk-GDVZ5VII.js} +4 -4
  34. package/dist/{chunk-QCCAHV6A.js → chunk-GV56WGL2.js} +321 -3308
  35. package/dist/chunk-GV56WGL2.js.map +1 -0
  36. package/dist/{chunk-TKTRIZT4.js → chunk-HA6MQMOY.js} +6 -6
  37. package/dist/{chunk-ECVQNGTH.js → chunk-HQR2ZBHW.js} +3 -3
  38. package/dist/{chunk-MHAYLDBK.js → chunk-IGSHYP74.js} +4 -4
  39. package/dist/{chunk-YEUQ7OKT.js → chunk-J6IDQGJL.js} +4 -4
  40. package/dist/{chunk-5LBEQ4ZU.js → chunk-JPQDNYXH.js} +2 -2
  41. package/dist/{chunk-6KKZXB2O.js → chunk-JROBZ7JA.js} +2 -2
  42. package/dist/{chunk-TMI2YF6D.js → chunk-KGEQJ5CC.js} +15 -26
  43. package/dist/{chunk-TMI2YF6D.js.map → chunk-KGEQJ5CC.js.map} +1 -1
  44. package/dist/{chunk-2EHDJ47Y.js → chunk-LBSCW232.js} +4 -4
  45. package/dist/{chunk-M6GH3FGJ.js → chunk-LKP7QDFN.js} +4 -4
  46. package/dist/{chunk-5EB6RIXJ.js → chunk-LPIF5LIE.js} +2 -2
  47. package/dist/chunk-M42DZCOU.js +164 -0
  48. package/dist/chunk-M42DZCOU.js.map +1 -0
  49. package/dist/{chunk-ND2S5BXB.js → chunk-MSRU4D4P.js} +2 -2
  50. package/dist/{chunk-BSTXARMY.js → chunk-NSBXVPZL.js} +11 -11
  51. package/dist/{chunk-Q45PZX2D.js → chunk-ODRPL3WB.js} +2 -2
  52. package/dist/{chunk-FSBIPCWE.js → chunk-OPXWPJDA.js} +10 -10
  53. package/dist/chunk-PCQ7ELJH.js +3081 -0
  54. package/dist/chunk-PCQ7ELJH.js.map +1 -0
  55. package/dist/{chunk-QAKJNPY3.js → chunk-PCS4VJBV.js} +6 -6
  56. package/dist/{chunk-GRILZZGS.js → chunk-PWBH7DCQ.js} +3 -3
  57. package/dist/{chunk-XKBEHKWO.js → chunk-QLWC7MKD.js} +34 -32
  58. package/dist/chunk-QLWC7MKD.js.map +1 -0
  59. package/dist/{chunk-XTAHZTES.js → chunk-R4WXQIOZ.js} +6 -6
  60. package/dist/{chunk-3CDZWY6M.js → chunk-RLT5SEML.js} +5 -5
  61. package/dist/{chunk-XG6PVB5S.js → chunk-SSQZB5SQ.js} +1 -11
  62. package/dist/chunk-SSQZB5SQ.js.map +1 -0
  63. package/dist/chunk-T7JAOYE5.js +393 -0
  64. package/dist/chunk-T7JAOYE5.js.map +1 -0
  65. package/dist/chunk-TU2WUBVZ.js +2 -0
  66. package/dist/{chunk-Q2H7J3FF.js → chunk-U7CTFN2J.js} +12 -10
  67. package/dist/{chunk-Q2H7J3FF.js.map → chunk-U7CTFN2J.js.map} +1 -1
  68. package/dist/{chunk-3XGGF5JW.js → chunk-VSEBFHAY.js} +10 -7
  69. package/dist/{chunk-3XGGF5JW.js.map → chunk-VSEBFHAY.js.map} +1 -1
  70. package/dist/{chunk-OVOYKWCM.js → chunk-WDWXAYVH.js} +4 -4
  71. package/dist/{chunk-5WME4CB6.js → chunk-Y6DOMTQD.js} +10 -8
  72. package/dist/{chunk-5WME4CB6.js.map → chunk-Y6DOMTQD.js.map} +1 -1
  73. package/dist/chunk-ZMECS2IJ.js +27 -0
  74. package/dist/chunk-ZMECS2IJ.js.map +1 -0
  75. package/dist/chunk-ZPLVANY2.js +15 -0
  76. package/dist/chunk-ZPLVANY2.js.map +1 -0
  77. package/dist/{cli-MEPJTS2V.js → cli-3BTCK4AB.js} +18 -15
  78. package/dist/{cli-MEPJTS2V.js.map → cli-3BTCK4AB.js.map} +1 -1
  79. package/dist/{cli-EMQXRN6E.js → cli-4MF37HAQ.js} +16 -12
  80. package/dist/{cli-EMQXRN6E.js.map → cli-4MF37HAQ.js.map} +1 -1
  81. package/dist/{cli-YDMMIL2U.js → cli-6KZTHWGP.js} +17 -14
  82. package/dist/{cli-YDMMIL2U.js.map → cli-6KZTHWGP.js.map} +1 -1
  83. package/dist/{cli-ZJRHU7MO.js → cli-DRMZBZLB.js} +39 -34
  84. package/dist/cli-DRMZBZLB.js.map +1 -0
  85. package/dist/{cli-J35OPSTP.js → cli-I62SRH3R.js} +10 -8
  86. package/dist/cli-JJMOVIKS.js +83 -0
  87. package/dist/cli-JJMOVIKS.js.map +1 -0
  88. package/dist/{cli-TPONWND4.js → cli-O4ABTN4Z.js} +25 -21
  89. package/dist/{cli-TPONWND4.js.map → cli-O4ABTN4Z.js.map} +1 -1
  90. package/dist/{cli-URNPOMOH.js → cli-ONTC5PKT.js} +3 -3
  91. package/dist/{cli-BJ7JXJ2U.js → cli-RORDPAPE.js} +17 -14
  92. package/dist/{cli-BJ7JXJ2U.js.map → cli-RORDPAPE.js.map} +1 -1
  93. package/dist/{cli-B7SFJDZA.js → cli-VID7PJS3.js} +17 -13
  94. package/dist/{cli-B7SFJDZA.js.map → cli-VID7PJS3.js.map} +1 -1
  95. package/dist/cli-VUKMWSSF.js +839 -0
  96. package/dist/cli-VUKMWSSF.js.map +1 -0
  97. package/dist/cli.js +24 -11
  98. package/dist/cli.js.map +1 -1
  99. package/dist/{config-YWSNBFEE.js → config-XDA42RJL.js} +3 -3
  100. package/dist/docmeta.js +9 -7
  101. package/dist/docmeta.js.map +1 -1
  102. package/dist/github-RY3FRA6P.js +29 -0
  103. package/dist/github-YKQSH7FS.js +34 -0
  104. package/dist/index.d.ts +1023 -915
  105. package/dist/index.js +107 -81
  106. package/dist/index.js.map +1 -1
  107. package/dist/{json-JIUPGOUQ.js → json-BXY44ED7.js} +13 -10
  108. package/dist/lint-YJ2L22BW.js +33 -0
  109. package/dist/list-NSG24VVX.js +31 -0
  110. package/dist/list-V6EGCSHX.js +34 -0
  111. package/dist/{page-WQ3GQF76.js → page-EV7OUBAU.js} +12 -9
  112. package/dist/{prepare-ZUTYXTUZ.js → prepare-JHJDJB6I.js} +17 -14
  113. package/dist/{prepare-ZUTYXTUZ.js.map → prepare-JHJDJB6I.js.map} +1 -1
  114. package/dist/{pretty-Q3C433DW.js → pretty-Q5Y2PA64.js} +14 -11
  115. package/dist/{pretty-CBV5XSMZ.js → pretty-SCRK66M5.js} +13 -10
  116. package/dist/{reporters-DH5HPFXJ.js → reporters-A5ADKDYR.js} +12 -9
  117. package/dist/{reporters-TTYGOUAF.js → reporters-RBYTASMI.js} +5 -5
  118. package/dist/run-BUE2DDXN.js +36 -0
  119. package/dist/{term-DL3YFL43.js → term-CQAGNG3Q.js} +17 -14
  120. package/dist/{term-DL3YFL43.js.map → term-CQAGNG3Q.js.map} +1 -1
  121. package/dist/{validate-UVDMC5LT.js → validate-ZBW44RHT.js} +6 -5
  122. package/dist/validate-ZBW44RHT.js.map +1 -0
  123. package/package.json +1 -1
  124. package/plugin/manni/.claude-plugin/plugin.json +1 -1
  125. package/dist/calibrate-XFE56P4M.js +0 -36
  126. package/dist/check-HBRX4FOR.js +0 -26
  127. package/dist/chunk-IN6DWNVE.js.map +0 -1
  128. package/dist/chunk-KX5IYIOO.js.map +0 -1
  129. package/dist/chunk-QCCAHV6A.js.map +0 -1
  130. package/dist/chunk-XG6PVB5S.js.map +0 -1
  131. package/dist/chunk-XKBEHKWO.js.map +0 -1
  132. package/dist/cli-ZJRHU7MO.js.map +0 -1
  133. package/dist/github-63CZJGZS.js +0 -31
  134. package/dist/github-IYOVHWHG.js +0 -26
  135. package/dist/lint-TBE35CCW.js +0 -29
  136. package/dist/list-IZ4RIM72.js +0 -30
  137. package/dist/list-TNEJ3J77.js +0 -28
  138. package/dist/run-LZXKVTM7.js +0 -32
  139. /package/dist/{batch-W5GXL2P4.js.map → batch-UAULUMGH.js.map} +0 -0
  140. /package/dist/{build-Q56FEXR6.js.map → build-QSPNK5AL.js.map} +0 -0
  141. /package/dist/{calibrate-XFE56P4M.js.map → calibrate-KXN4URPM.js.map} +0 -0
  142. /package/dist/{capture-GMYH4ATL.js.map → capture-JHTSUPUC.js.map} +0 -0
  143. /package/dist/{check-HBRX4FOR.js.map → check-MDGXEUWL.js.map} +0 -0
  144. /package/dist/{check-OAJWC3WD.js.map → check-WOQRKNZK.js.map} +0 -0
  145. /package/dist/{check-ZE5HIDOW.js.map → check-YEOYBFST.js.map} +0 -0
  146. /package/dist/{chunk-FGUXMZXO.js.map → chunk-2DRHT73U.js.map} +0 -0
  147. /package/dist/{chunk-XHFHXOQQ.js.map → chunk-2IAZEB45.js.map} +0 -0
  148. /package/dist/{chunk-35WTFPQS.js.map → chunk-2IR4T5PO.js.map} +0 -0
  149. /package/dist/{chunk-OWSNXPPX.js.map → chunk-4CK6ZSOK.js.map} +0 -0
  150. /package/dist/{chunk-YUZ2ECZY.js.map → chunk-4D5IZSXM.js.map} +0 -0
  151. /package/dist/{chunk-RFSGKF4O.js.map → chunk-4VBSTXN6.js.map} +0 -0
  152. /package/dist/{chunk-GEMXGXPR.js.map → chunk-ADMEPUBT.js.map} +0 -0
  153. /package/dist/{chunk-23UAGEKP.js.map → chunk-B7XYNRJQ.js.map} +0 -0
  154. /package/dist/{chunk-QKE3XS2L.js.map → chunk-BBT6AVUG.js.map} +0 -0
  155. /package/dist/{chunk-VKWZCEWB.js.map → chunk-BKVHX6FU.js.map} +0 -0
  156. /package/dist/{chunk-X6WLCNKC.js.map → chunk-D4N2V43Z.js.map} +0 -0
  157. /package/dist/{chunk-XXDXIIQ4.js.map → chunk-EFW7CAG4.js.map} +0 -0
  158. /package/dist/{chunk-UDUHRXJ4.js.map → chunk-EIFCP6CZ.js.map} +0 -0
  159. /package/dist/{chunk-KPXOJMQ6.js.map → chunk-FBMZJEB3.js.map} +0 -0
  160. /package/dist/{chunk-HRXDM6H6.js.map → chunk-FQXWVS6J.js.map} +0 -0
  161. /package/dist/{chunk-76I6I5N2.js.map → chunk-FUCPZVRY.js.map} +0 -0
  162. /package/dist/{chunk-DTGIUMZV.js.map → chunk-GDVZ5VII.js.map} +0 -0
  163. /package/dist/{chunk-TKTRIZT4.js.map → chunk-HA6MQMOY.js.map} +0 -0
  164. /package/dist/{chunk-ECVQNGTH.js.map → chunk-HQR2ZBHW.js.map} +0 -0
  165. /package/dist/{chunk-MHAYLDBK.js.map → chunk-IGSHYP74.js.map} +0 -0
  166. /package/dist/{chunk-YEUQ7OKT.js.map → chunk-J6IDQGJL.js.map} +0 -0
  167. /package/dist/{chunk-5LBEQ4ZU.js.map → chunk-JPQDNYXH.js.map} +0 -0
  168. /package/dist/{chunk-6KKZXB2O.js.map → chunk-JROBZ7JA.js.map} +0 -0
  169. /package/dist/{chunk-2EHDJ47Y.js.map → chunk-LBSCW232.js.map} +0 -0
  170. /package/dist/{chunk-M6GH3FGJ.js.map → chunk-LKP7QDFN.js.map} +0 -0
  171. /package/dist/{chunk-5EB6RIXJ.js.map → chunk-LPIF5LIE.js.map} +0 -0
  172. /package/dist/{chunk-ND2S5BXB.js.map → chunk-MSRU4D4P.js.map} +0 -0
  173. /package/dist/{chunk-BSTXARMY.js.map → chunk-NSBXVPZL.js.map} +0 -0
  174. /package/dist/{chunk-Q45PZX2D.js.map → chunk-ODRPL3WB.js.map} +0 -0
  175. /package/dist/{chunk-FSBIPCWE.js.map → chunk-OPXWPJDA.js.map} +0 -0
  176. /package/dist/{chunk-QAKJNPY3.js.map → chunk-PCS4VJBV.js.map} +0 -0
  177. /package/dist/{chunk-GRILZZGS.js.map → chunk-PWBH7DCQ.js.map} +0 -0
  178. /package/dist/{chunk-XTAHZTES.js.map → chunk-R4WXQIOZ.js.map} +0 -0
  179. /package/dist/{chunk-3CDZWY6M.js.map → chunk-RLT5SEML.js.map} +0 -0
  180. /package/dist/{cli-J35OPSTP.js.map → chunk-TU2WUBVZ.js.map} +0 -0
  181. /package/dist/{chunk-OVOYKWCM.js.map → chunk-WDWXAYVH.js.map} +0 -0
  182. /package/dist/{config-YWSNBFEE.js.map → cli-I62SRH3R.js.map} +0 -0
  183. /package/dist/{cli-URNPOMOH.js.map → cli-ONTC5PKT.js.map} +0 -0
  184. /package/dist/{github-63CZJGZS.js.map → config-XDA42RJL.js.map} +0 -0
  185. /package/dist/{github-IYOVHWHG.js.map → github-RY3FRA6P.js.map} +0 -0
  186. /package/dist/{json-JIUPGOUQ.js.map → github-YKQSH7FS.js.map} +0 -0
  187. /package/dist/{lint-TBE35CCW.js.map → json-BXY44ED7.js.map} +0 -0
  188. /package/dist/{list-IZ4RIM72.js.map → lint-YJ2L22BW.js.map} +0 -0
  189. /package/dist/{list-TNEJ3J77.js.map → list-NSG24VVX.js.map} +0 -0
  190. /package/dist/{page-WQ3GQF76.js.map → list-V6EGCSHX.js.map} +0 -0
  191. /package/dist/{pretty-CBV5XSMZ.js.map → page-EV7OUBAU.js.map} +0 -0
  192. /package/dist/{pretty-Q3C433DW.js.map → pretty-Q5Y2PA64.js.map} +0 -0
  193. /package/dist/{reporters-DH5HPFXJ.js.map → pretty-SCRK66M5.js.map} +0 -0
  194. /package/dist/{reporters-TTYGOUAF.js.map → reporters-A5ADKDYR.js.map} +0 -0
  195. /package/dist/{run-LZXKVTM7.js.map → reporters-RBYTASMI.js.map} +0 -0
  196. /package/dist/{validate-UVDMC5LT.js.map → run-BUE2DDXN.js.map} +0 -0
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/shared/exec.ts","../src/docevals/judge/budget.ts"],"sourcesContent":["/**\n * Process execution for every grader in the family that runs a program. The\n * implementation lives in `@hawkeyexl/inference`: the judge's subprocess\n * provider and the command graders were running copies of the same\n * cross-spawn wrapper, and the Windows-specific parts (npm `.cmd` shim\n * resolution without `shell: true`, stdin piping past the ~32K command-line\n * limit, and StringDecoder-backed output so multi-byte UTF-8 survives chunk\n * boundaries) are exactly the parts worth having in one place.\n *\n * Shared rather than per domain: `manni docevals` and `manni tracevals` both\n * run `command` evals, and both reach the OS through this one wrapper.\n */\nimport type { ExecResult } from \"@hawkeyexl/inference\";\n\nexport { realExec } from \"@hawkeyexl/inference\";\n\n/** Truncate command output for finding messages. */\nexport function outputTail(result: ExecResult, maxChars = 400): string {\n const text = (result.stderr.trim() || result.stdout.trim()).trim();\n if (text.length <= maxChars) return text;\n return `…${text.slice(-maxChars)}`;\n}\n\n/**\n * How a finished process is described in a finding: \"exited 2\", or the truth\n * when there was no exit code.\n *\n * `code` is null when the process was killed by a signal rather than exiting.\n * \"exited null\" describes nothing a reader can act on, and it is the case a\n * timeout produces — so it is the one worth naming.\n */\nexport function exited(code: number | null): string {\n return code === null ? \"was killed before exiting\" : `exited ${code}`;\n}\n","/**\n * The turn-budget skip marker (ADR 01019), in one place.\n *\n * `judge.ts` produces the skip reason; `core/engine.ts` and `commands/\n * calibrate.ts` both have to tell a budget truncation apart from every other\n * reason an eval went unjudged, because that distinction is what stops a\n * partial run from reporting as a complete one. They did it by matching the\n * bare substring `\"turn budget\"` against a message written in a third file,\n * so a reword in the producer would have left both detectors matching nothing\n * — silently, since the tests that exercise truncation supply the skip reason\n * themselves rather than getting it from the judge.\n *\n * Kept in its own module rather than exported from `judge.ts`: the detectors\n * need the marker, not the judge, and `engine.ts` deliberately takes the judge\n * by injection.\n */\n\n/** The substring every budget-truncation skip reason carries. */\nexport const TURN_BUDGET_SKIP = \"turn budget\";\n\n/** The skip reason recorded for an eval the budget stopped before dispatch. */\nexport function turnBudgetSkipReason(maxTurns: number): string {\n return `judge ${TURN_BUDGET_SKIP} exhausted (${maxTurns})`;\n}\n\n/**\n * Whether a skip reason is the budget's doing rather than the judge's.\n *\n * A type predicate, not a plain boolean: a budget skip always carries a\n * reason, and callers interpolate it into the message they report.\n */\nexport function isTurnBudgetSkip(reason: string | undefined): reason is string {\n return reason !== undefined && reason.includes(TURN_BUDGET_SKIP);\n}\n"],"mappings":";;;AAcA,SAAS,gBAAgB;AAGlB,SAAS,WAAW,QAAoB,WAAW,KAAa;AACrE,QAAM,QAAQ,OAAO,OAAO,KAAK,KAAK,OAAO,OAAO,KAAK,GAAG,KAAK;AACjE,MAAI,KAAK,UAAU,SAAU,QAAO;AACpC,SAAO,SAAI,KAAK,MAAM,CAAC,QAAQ,CAAC;AAClC;;;ACHO,IAAM,mBAAmB;AAGzB,SAAS,qBAAqB,UAA0B;AAC7D,SAAO,SAAS,gBAAgB,eAAe,QAAQ;AACzD;AAQO,SAAS,iBAAiB,QAA8C;AAC7E,SAAO,WAAW,UAAa,OAAO,SAAS,gBAAgB;AACjE;","names":[]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/shared/encryption.ts","../src/shared/collections.ts","../src/shared/globs.ts","../src/shared/page-manifest.ts","../src/shared/tools.ts","../src/shared/config-file.ts","../src/shared/git-root.ts"],"sourcesContent":["/**\n * The family's value encryption (proposal 0045).\n *\n * One ciphertext format for every tool: meta frontmatter values and cite\n * source paths encrypt the same way, under different contexts, so rotation\n * has one rule. Pure, and `node:crypto` only.\n *\n * The construction is SIV-style on AES-256-GCM, because Node has no SIV mode\n * (`aes-256-gcm-siv` and `aes-*-siv` are unknown ciphers in Node 24):\n *\n * - Three 32-byte subkeys come from the configured key with HKDF-SHA256 and an\n * empty salt, labelled `manni/v1/encrypt`, `manni/v1/nonce` and\n * `manni/v1/pin`. The key is expanded, not stretched: a hand-picked value is\n * only as strong as it is random, which is why `manni key set` generates 256\n * bits.\n * - The plaintext is the value's JSON, padded ISO/IEC 7816-4 style (`0x80`,\n * then `0x00` up to the next multiple of 32, always at least one pad byte),\n * so a token's length reveals a size class, not the value.\n * - The nonce is the first 12 bytes of `HMAC(nonceKey, context ‖ 0x00 ‖\n * padded)`. Equal plaintexts give equal tokens, which is what a join needs;\n * decryption checks the nonce is that HMAC, so every valid token is\n * canonical.\n * - The associated data is `0x01 ‖ context`, so the same text in two contexts\n * never reuses a nonce under different tags. The property name is not\n * bound: a value moved between fields stays readable.\n *\n * A token is `~` then unpadded base64url of `0x01 ‖ nonce ‖ ciphertext ‖\n * tag`: 61 bytes at the smallest, so 82 characters after the `~`.\n */\nimport {\n createCipheriv,\n createDecipheriv,\n createHmac,\n hkdfSync,\n randomBytes,\n timingSafeEqual,\n} from \"node:crypto\";\nimport { TextDecoder } from \"node:util\";\n\n/** Which kind of value a token holds. Bound as associated data. */\nexport type EncryptionContext = \"meta\" | \"cite-src\";\n\n/** An encrypted value: `~` and at least 82 base64url characters. */\nexport const ENCRYPTED_VALUE = /^~[A-Za-z0-9_-]{82,}$/;\n\n/** Whether `value` is shaped like a token. Says nothing about which key. */\nexport function isEncryptedValue(value: unknown): value is string {\n return typeof value === \"string\" && ENCRYPTED_VALUE.test(value);\n}\n\n/** A configured key: hex or base64url, at least 32 characters. */\nexport const ENCRYPTION_KEY_SHAPE = /^[A-Za-z0-9_-]{32,}$/;\n\nexport function isValidEncryptionKey(value: unknown): value is string {\n return typeof value === \"string\" && ENCRYPTION_KEY_SHAPE.test(value);\n}\n\n/** 256 random bits as 64 lowercase hex characters. */\nexport function generateEncryptionKey(): string {\n return randomBytes(32).toString(\"hex\");\n}\n\nconst VERSION = 0x01;\nconst NONCE_BYTES = 12;\nconst TAG_BYTES = 16;\nconst BLOCK = 32;\n/** Version byte, nonce, one padded block, tag. */\nconst MIN_BYTES = 1 + NONCE_BYTES + BLOCK + TAG_BYTES;\n\ninterface Subkeys {\n encrypt: Buffer;\n nonce: Buffer;\n pin: Buffer;\n}\n\n/**\n * Subkeys per configured key. A run sees one key, or two while rotating, so\n * the cache stays tiny; it saves three HKDF calls per value on a large tree.\n */\nconst subkeyCache = new Map<string, Subkeys>();\n\nfunction subkeys(key: string): Subkeys {\n const cached = subkeyCache.get(key);\n if (cached !== undefined) return cached;\n const ikm = Buffer.from(key, \"utf8\");\n const derive = (info: string): Buffer =>\n Buffer.from(hkdfSync(\"sha256\", ikm, Buffer.alloc(0), info, 32));\n const made: Subkeys = {\n encrypt: derive(\"manni/v1/encrypt\"),\n nonce: derive(\"manni/v1/nonce\"),\n pin: derive(\"manni/v1/pin\"),\n };\n subkeyCache.set(key, made);\n return made;\n}\n\nfunction requireKey(key: string, caller: string): void {\n if (!isValidEncryptionKey(key)) {\n // Never echo the value: it is key material.\n throw new Error(\n `${caller}: the key must be at least 32 hex or base64url characters.`,\n );\n }\n}\n\nfunction pad(data: Buffer): Buffer {\n const out = Buffer.alloc((Math.floor(data.length / BLOCK) + 1) * BLOCK);\n data.copy(out);\n out[data.length] = 0x80;\n return out;\n}\n\n/** The data before the padding, or `null` when the padding is not canonical. */\nfunction unpad(padded: Buffer): Buffer | null {\n let i = padded.length - 1;\n while (i >= 0 && padded[i] === 0) i--;\n if (i < 0 || padded[i] !== 0x80) return null;\n // Exactly the padding `pad` would have added: never a spare block.\n if (padded.length !== (Math.floor(i / BLOCK) + 1) * BLOCK) return null;\n return padded.subarray(0, i);\n}\n\nfunction nonceFor(keys: Subkeys, context: Buffer, padded: Buffer): Buffer {\n return createHmac(\"sha256\", keys.nonce)\n .update(context)\n .update(Buffer.from([0x00]))\n .update(padded)\n .digest()\n .subarray(0, NONCE_BYTES);\n}\n\nfunction aad(context: Buffer): Buffer {\n return Buffer.concat([Buffer.from([VERSION]), context]);\n}\n\n/**\n * Encrypt any JSON value. Throws for a value that is not JSON (`undefined`, a\n * function) and for a key that is not key-shaped: both are programming\n * errors, since keys arrive through `resolveEncryptionKey`.\n */\nexport function encryptValue(\n value: unknown,\n key: string,\n context: EncryptionContext,\n): string {\n requireKey(key, \"encryptValue\");\n // lib.d.ts types the result as `string`, but `undefined`, a function or a\n // symbol stringify to `undefined` at run time.\n const json = JSON.stringify(value) as string | undefined;\n if (json === undefined) {\n throw new TypeError(\"encryptValue: the value is not JSON.\");\n }\n const keys = subkeys(key);\n const ctx = Buffer.from(context, \"utf8\");\n const padded = pad(Buffer.from(json, \"utf8\"));\n const nonce = nonceFor(keys, ctx, padded);\n const cipher = createCipheriv(\"aes-256-gcm\", keys.encrypt, nonce, {\n authTagLength: TAG_BYTES,\n });\n cipher.setAAD(aad(ctx));\n const sealed = Buffer.concat([cipher.update(padded), cipher.final()]);\n const tag = cipher.getAuthTag();\n const bytes = Buffer.concat([Buffer.from([VERSION]), nonce, sealed, tag]);\n return `~${bytes.toString(\"base64url\")}`;\n}\n\nconst FAILED = { ok: false } as const;\n\n/**\n * Decrypt a token. `{ ok: false }` for anything that is not a canonical token\n * under this key and context; never throws.\n */\nexport function decryptValue(\n token: string,\n key: string,\n context: EncryptionContext,\n): { ok: true; value: unknown } | { ok: false } {\n try {\n return open(token, key, context);\n } catch {\n return FAILED;\n }\n}\n\nfunction open(\n token: string,\n key: string,\n context: EncryptionContext,\n): { ok: true; value: unknown } | { ok: false } {\n if (!isEncryptedValue(token) || !isValidEncryptionKey(key)) return FAILED;\n const body = token.slice(1);\n const bytes = Buffer.from(body, \"base64url\");\n // Buffer's decoder ignores stray trailing bits; a token is canonical only\n // if it is exactly what the encoder writes for these bytes.\n if (bytes.toString(\"base64url\") !== body) return FAILED;\n if (bytes.length < MIN_BYTES) return FAILED;\n if ((bytes.length - 1 - NONCE_BYTES - TAG_BYTES) % BLOCK !== 0) return FAILED;\n if (bytes[0] !== VERSION) return FAILED;\n\n const nonce = bytes.subarray(1, 1 + NONCE_BYTES);\n const sealed = bytes.subarray(1 + NONCE_BYTES, bytes.length - TAG_BYTES);\n const tag = bytes.subarray(bytes.length - TAG_BYTES);\n const keys = subkeys(key);\n const ctx = Buffer.from(context, \"utf8\");\n const decipher = createDecipheriv(\"aes-256-gcm\", keys.encrypt, nonce, {\n authTagLength: TAG_BYTES,\n });\n decipher.setAAD(aad(ctx));\n decipher.setAuthTag(tag);\n // `final` throws on a bad tag; the caller turns that into `{ ok: false }`.\n const padded = Buffer.concat([decipher.update(sealed), decipher.final()]);\n\n if (!timingSafeEqual(nonceFor(keys, ctx, padded), nonce)) return FAILED;\n const data = unpad(padded);\n if (data === null) return FAILED;\n const json = new TextDecoder(\"utf-8\", { fatal: true }).decode(data);\n const value: unknown = JSON.parse(json);\n return { ok: true, value };\n}\n\n/** The prefix a keyed pin carries, so it never reads as a plain hash of the text. */\nexport const KEYED_PIN_PREFIX = \"hmac-sha256-\";\n\n/**\n * A keyed fingerprint of `text`: `hmac-sha256-` and the hex HMAC-SHA256 under\n * the pin subkey. Stable per key, so it can be compared without being\n * reversible. The prefix says it is an HMAC: hashing the text by hand gives\n * a different value, and the prefix is why.\n */\nexport function keyedPin(text: string, key: string): string {\n requireKey(key, \"keyedPin\");\n const mac = createHmac(\"sha256\", subkeys(key).pin)\n .update(text, \"utf8\")\n .digest(\"hex\");\n return `${KEYED_PIN_PREFIX}${mac}`;\n}\n","/**\n * `collections:`, the family-level home for document sets (proposal 0041).\n *\n * A collection names a set of documents once, at the top level of\n * `manni.config.yaml`, and every tool reads the same declaration: the metadata\n * tool validates its members, `query` exposes it as a view, and `a11y check`\n * seeds from its `url`. Only the *declaration* is shared. Loading a manifest\n * and merging it into `ExtractedMetadata` stays with the metadata tool,\n * because that type is the metadata tool's.\n *\n * Every refusal in this parser is a shape that would otherwise read as\n * configured and do nothing, or do something nobody can see. The manifest\n * rules are 0037's, moved here unchanged in substance: an entry with an empty\n * `keys` list owns nothing, one key under two manifests of a collection would need a\n * tiebreak (0020 refuses tiebreaks), and `$schema` from external metadata\n * would let a private file pick the schema a public document is judged by\n * (0015) with the provenance lost at the merge.\n */\nimport picomatch from \"picomatch\";\nimport { matchesFileGlob } from \"./globs.js\";\nimport { posix, win32 } from \"node:path\";\nimport {\n PAGE_PLACEHOLDER,\n hasPagePlaceholder,\n normalizeManifestPattern,\n} from \"./page-manifest.js\";\n\n/** One external-metadata manifest (proposals 0037, 0038, 0039) joined to a collection. */\nexport interface ExternalMetadataConfig {\n file: string;\n /**\n * The top-level keys the manifest owns. Absent (proposal 0068), it owns\n * what each page's schemas mark `x-manni-location: external`, as `ownsKey`\n * decides.\n */\n keys?: string[];\n tokenEnv?: string;\n join?: string;\n}\n\n/** One named document set, as declared under the top-level `collections:` key. */\nexport interface CollectionConfig {\n name: string;\n paths: string[];\n exclude: string[];\n externalMetadata: ExternalMetadataConfig[];\n /** Where the collection is published; `manni a11y check` seeds from it. */\n url?: string;\n}\n\nconst COLLECTION_KEYS = [\n \"name\",\n \"paths\",\n \"exclude\",\n \"url\",\n \"externalMetadata\",\n] as const;\n\nconst EXTERNAL_METADATA_KEYS = [\"file\", \"keys\", \"tokenEnv\", \"join\"] as const;\n\n/**\n * The join that names documents by path, and the default. The metadata tool\n * spells it `PATH_JOIN` in `src/meta/core/external-metadata.ts`; the literal\n * is repeated here for the same reason as `SCHEMA_KEY` below.\n */\nconst PATH_JOIN = \"path\";\n\n/**\n * The document-level schema key. The metadata tool spells it\n * `FILE_SCHEMA_KEY` in `src/meta/core/resolve-schema.ts`; the literal is\n * repeated here so the shared layer does not import a tool's module. Keep the\n * two in step.\n */\nconst SCHEMA_KEY = \"$schema\";\n\n/**\n * The label `load-files.ts` gives stdin (`STDIN_LABEL`). Repeated as a literal\n * for the same reason as `SCHEMA_KEY`: the shared layer does not depend on the\n * metadata tool. Stdin has no path, so it is a member of nothing.\n */\nconst STDIN = \"<stdin>\";\n\n/** Is this manifest reference a URL? The `url` branch of `classifyRef`. */\nfunction isUrlRef(ref: string): boolean {\n return /^https?:\\/\\//i.test(ref);\n}\n\n/**\n * Whether a URL may name an external-metadata manifest: `https://` anywhere,\n * or `http://` on a loopback host only, where plaintext leaks nothing.\n * Userinfo is refused because the URL is printed in every diagnostic and a\n * secret in it would print too. Returns the reason it may not, or `null`.\n */\nexport function externalMetadataUrlProblem(url: string): string | null {\n let parsed: URL;\n try {\n parsed = new URL(url);\n } catch {\n return \"is not a valid URL\";\n }\n if (parsed.username !== \"\" || parsed.password !== \"\") {\n return 'carries a credential in the URL; put the token in an environment variable and name it with \"tokenEnv\"';\n }\n if (parsed.protocol === \"https:\") return null;\n if (parsed.protocol === \"http:\" && isLoopback(parsed.hostname)) return null;\n if (parsed.protocol === \"http:\") {\n return \"is plain http://; a bearer token over plaintext is a leak, and a public manifest is served over https too\";\n }\n return `has the unsupported scheme \"${parsed.protocol}\"`;\n}\n\nfunction isLoopback(host: string): boolean {\n return (\n host === \"localhost\" ||\n host === \"127.0.0.1\" ||\n host === \"[::1]\" ||\n host === \"::1\" ||\n host.startsWith(\"127.\")\n );\n}\n\nfunction rejectUnknownKeys(\n raw: Record<string, unknown>,\n allowed: readonly string[],\n where: string,\n source: string,\n toError: (message: string) => Error,\n): void {\n for (const key of Object.keys(raw)) {\n if (!allowed.includes(key)) {\n throw toError(\n `${source}: ${where} has unknown key \"${key}\". Supported keys: ${allowed.join(\", \")}.`,\n );\n }\n }\n}\n\nfunction isMapping(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction isNonEmptyString(value: unknown): value is string {\n return typeof value === \"string\" && value.trim() !== \"\";\n}\n\n/**\n * Parse the top-level `collections:` value. Errors are built with `toError`,\n * so each tool reports a bad family file in its own error class.\n */\nexport function parseCollections(\n raw: unknown,\n source: string,\n toError: (message: string) => Error,\n): CollectionConfig[] {\n if (!Array.isArray(raw)) {\n throw toError(`${source}: \"collections\" must be a list.`);\n }\n if (raw.length === 0) {\n throw toError(\n `${source}: \"collections\" must name at least one collection; remove the key if there are none.`,\n );\n }\n // Names become SQL view names, and SQLite compares identifiers without\n // regard to case, so two names that differ only in case are one view.\n const taken = new Map<string, number>();\n return raw.map((entry, i) => {\n const where = `collections[${i}]`;\n if (!isMapping(entry)) {\n throw toError(`${source}: ${where} must be a mapping.`);\n }\n rejectUnknownKeys(entry, COLLECTION_KEYS, where, source, toError);\n\n if (!isNonEmptyString(entry.name)) {\n throw toError(`${source}: ${where}.name must be a non-empty string.`);\n }\n const name = entry.name;\n const folded = name.toLowerCase();\n if (folded === \"docs\") {\n throw toError(\n `${source}: ${where}.name \"${name}\" collides with the docs table every query reads. Pick another name, such as \"site\" or \"pages\".`,\n );\n }\n // The derived table (proposal 0040) is a view named `derived` over a\n // backing table named `_derived_rows`, built beside `docs` when a\n // statement asks for it, and `resolved` (proposal 0043) is the view over\n // `docs` and those rows. Any of the three would shadow it the same way.\n if (folded === \"derived\" || folded === \"_derived_rows\" || folded === \"resolved\") {\n throw toError(\n `${source}: ${where}.name \"${name}\" collides with the derived table a query builds beside docs (the derived view, its _derived_rows table, and the resolved view over both). Pick another name.`,\n );\n }\n if (folded.startsWith(\"sqlite_\")) {\n throw toError(\n `${source}: ${where}.name \"${name}\" starts with \"sqlite_\", which SQLite reserves for its own objects. Pick another name.`,\n );\n }\n const owner = taken.get(folded);\n if (owner !== undefined) {\n throw toError(\n `${source}: ${where}.name \"${name}\" is already taken by collections[${owner}]; names are compared case-insensitively because they become SQL views.`,\n );\n }\n taken.set(folded, i);\n\n if (\n !Array.isArray(entry.paths) ||\n entry.paths.length === 0 ||\n entry.paths.some((p) => !isNonEmptyString(p))\n ) {\n throw toError(\n `${source}: ${where}.paths must be a non-empty list of files, directories or globs.`,\n );\n }\n const paths = entry.paths as string[];\n\n let exclude: string[] = [];\n if (entry.exclude !== undefined) {\n if (\n !Array.isArray(entry.exclude) ||\n entry.exclude.some((g) => !isNonEmptyString(g))\n ) {\n throw toError(`${source}: ${where}.exclude must be a list of globs.`);\n }\n exclude = entry.exclude as string[];\n }\n\n let url: string | undefined;\n if (entry.url !== undefined) {\n if (typeof entry.url !== \"string\" || !isHttpUrl(entry.url)) {\n throw toError(`${source}: ${where}.url must be an http(s) URL.`);\n }\n url = entry.url;\n }\n\n let externalMetadata: ExternalMetadataConfig[] = [];\n if (entry.externalMetadata !== undefined) {\n if (!Array.isArray(entry.externalMetadata)) {\n throw toError(`${source}: ${where}.externalMetadata must be a list.`);\n }\n externalMetadata = parseExternalMetadata(\n entry.externalMetadata,\n where,\n source,\n toError,\n );\n }\n\n return {\n name,\n paths,\n exclude,\n externalMetadata,\n ...(url === undefined ? {} : { url }),\n };\n });\n}\n\nfunction isHttpUrl(value: string): boolean {\n let parsed: URL;\n try {\n parsed = new URL(value);\n } catch {\n return false;\n }\n return parsed.protocol === \"http:\" || parsed.protocol === \"https:\";\n}\n\n/**\n * Parse one collection's `externalMetadata:`. 0037's rules, with the error\n * path rewritten and the noun changed: ownership is now disjoint within a\n * collection rather than across the whole config, because two collections may\n * each own the same key.\n */\nfunction parseExternalMetadata(\n raw: readonly unknown[],\n collectionWhere: string,\n source: string,\n toError: (message: string) => Error,\n): ExternalMetadataConfig[] {\n const owners = new Map<string, number>();\n const patterns = new Map<string, number>();\n /** The one entry that omits `keys` (proposal 0068), once one does. */\n let keyless: number | undefined;\n const parsedEntries = raw.map((entry, i): ExternalMetadataConfig => {\n const where = `${collectionWhere}.externalMetadata[${i}]`;\n if (!isMapping(entry)) {\n throw toError(`${source}: ${where} must be a mapping.`);\n }\n rejectUnknownKeys(entry, EXTERNAL_METADATA_KEYS, where, source, toError);\n if (!isNonEmptyString(entry.file)) {\n throw toError(\n `${source}: ${where}.file must be a non-empty string naming the manifest, relative to the config file.`,\n );\n }\n const placeholderProblem = pagePlaceholderProblem(entry.file);\n if (placeholderProblem !== null) {\n throw toError(`${source}: ${where}.file ${placeholderProblem}`);\n }\n const perPage = hasPagePlaceholder(entry.file);\n if (perPage && (posix.isAbsolute(entry.file) || win32.isAbsolute(entry.file))) {\n throw toError(\n `${source}: ${where}.file uses ${PAGE_PLACEHOLDER} in an absolute path, so every manifest would sit outside the repository. Make it relative to the config file.`,\n );\n }\n // Absent keys (proposal 0068) is an ownership rule, not an empty list:\n // the manifest owns what each page's schemas mark external. Written, the\n // list still has to name something.\n if (\n entry.keys !== undefined &&\n (!Array.isArray(entry.keys) ||\n entry.keys.length === 0 ||\n entry.keys.some((k) => !isNonEmptyString(k)))\n ) {\n throw toError(\n `${source}: ${where}.keys must be a non-empty list of key names.`,\n );\n }\n if (entry.keys === undefined) {\n if (keyless !== undefined) {\n throw toError(\n `${source}: ${collectionWhere}.externalMetadata: entries ${String(keyless)} and ${String(i)} both omit keys; at most one manifest may own the external-marked fields`,\n );\n }\n keyless = i;\n }\n const isUrl = isUrlRef(entry.file);\n if (isUrl) {\n const problem = externalMetadataUrlProblem(entry.file);\n if (problem !== null) {\n throw toError(`${source}: ${where}.file ${problem}.`);\n }\n if (perPage) {\n throw toError(\n `${source}: ${where}.file uses ${PAGE_PLACEHOLDER} in a URL. A placeholder names a file this run can write, and a URL is not one.`,\n );\n }\n }\n if (entry.tokenEnv !== undefined) {\n if (!isNonEmptyString(entry.tokenEnv)) {\n throw toError(\n `${source}: ${where}.tokenEnv must be the name of an environment variable.`,\n );\n }\n if (!isUrl) {\n throw toError(\n `${source}: ${where}.tokenEnv is set, but \"file\" is a path, so no request is made and the token would go nowhere. Remove it, or make \"file\" a URL.`,\n );\n }\n }\n const keys = entry.keys === undefined ? undefined : (entry.keys as string[]);\n if (entry.join !== undefined) {\n if (!isNonEmptyString(entry.join)) {\n throw toError(\n `${source}: ${where}.join must be \"path\" or the name of a top-level frontmatter field.`,\n );\n }\n if (entry.join === SCHEMA_KEY) {\n throw toError(`${source}: ${where}.join may not be \"${SCHEMA_KEY}\".`);\n }\n if (keys?.includes(entry.join) === true) {\n throw toError(\n `${source}: ${where}.join names \"${entry.join}\", which the same entry owns — the value that selects an entry cannot come from the entry.`,\n );\n }\n }\n // An explicit `join: path` is the default spelled out, and a per-page\n // manifest is found by that path. A field would name the file by one\n // thing and key its entry by another (0058 § 6).\n if (perPage && typeof entry.join === \"string\" && entry.join !== PATH_JOIN) {\n throw toError(\n `${source}: ${where}.file uses ${PAGE_PLACEHOLDER}, and join is \"${entry.join}\". A per-page manifest is found by path, so it cannot be keyed by a field. Remove ${PAGE_PLACEHOLDER}, or remove join.`,\n );\n }\n const seen = new Set<string>();\n for (const key of keys ?? []) {\n if (key === SCHEMA_KEY) {\n throw toError(\n `${source}: ${where}.keys may not include \"${SCHEMA_KEY}\" — a manifest never chooses the schema a document is judged by; use \"overrides\".`,\n );\n }\n if (seen.has(key)) {\n throw toError(`${source}: ${where}.keys lists \"${key}\" twice.`);\n }\n seen.add(key);\n const owner = owners.get(key);\n if (owner !== undefined) {\n throw toError(\n `${source}: ${where}.keys claims \"${key}\", which externalMetadata[${owner}] already owns — a key has exactly one manifest in a collection.`,\n );\n }\n owners.set(key, i);\n }\n // Two spellings of one pattern are one manifest for every page (0058\n // stress test 10), compared once, with no page known yet. Two concrete\n // entries naming one file stay legal, as they were before placeholders.\n if (perPage) {\n const pattern = normalizeManifestPattern(entry.file);\n const first = patterns.get(pattern);\n if (first !== undefined) {\n throw toError(\n `${source}: ${where}.file resolves to the same manifest as externalMetadata[${String(first)}].file for every page. Give each entry its own file name.`,\n );\n }\n patterns.set(pattern, i);\n }\n const parsed: ExternalMetadataConfig = {\n file: entry.file,\n ...(keys === undefined ? {} : { keys }),\n ...(typeof entry.tokenEnv === \"string\" ? { tokenEnv: entry.tokenEnv } : {}),\n ...(typeof entry.join === \"string\" ? { join: entry.join } : {}),\n };\n origins.set(parsed, { source, where });\n return parsed;\n });\n // What each keyless manifest can never own, fixed here against the whole\n // declaration. A caller that narrows a collection to some of its manifests\n // still gets the answer the full collection gives.\n for (const manifest of parsedEntries) {\n if (manifest.keys === undefined) declaredNever.set(manifest, neverOwnedIn(parsedEntries, manifest));\n }\n return parsedEntries;\n}\n\n/**\n * The problem with `file`'s `{page}` placeholder grammar (0058 § 1), as the\n * tail of a sentence that starts with the entry's path, or `null` when there\n * is none. One token, spelled exactly, at most once; every other brace is\n * refused rather than read as a literal.\n */\nfunction pagePlaceholderProblem(file: string): string | null {\n for (const match of file.matchAll(/\\{[^{}]*\\}/g)) {\n if (match[0] !== PAGE_PLACEHOLDER) {\n return `uses \"${match[0]}\", which is not a placeholder. The only placeholder is ${PAGE_PLACEHOLDER}.`;\n }\n }\n const tokens = file.split(PAGE_PLACEHOLDER);\n const stray = /[{}]/.exec(tokens.join(\"\"));\n if (stray !== null) {\n return `contains \"${stray[0]}\" outside a ${PAGE_PLACEHOLDER} placeholder. Remove it, or write ${PAGE_PLACEHOLDER}.`;\n }\n if (tokens.length > 2) {\n return `uses ${PAGE_PLACEHOLDER} twice. One manifest names one page.`;\n }\n return null;\n}\n\n/**\n * Where a parsed `externalMetadata:` entry was declared: the config file as\n * the parse was told to name it, and the entry's\n * `collections[c].externalMetadata[i]` path. Kept beside the entry rather\n * than on it, so the entry's shape, its equality, and anything that\n * serializes it stay what they were. A copy made with a spread has no origin.\n */\nconst origins = new WeakMap<ExternalMetadataConfig, { source: string; where: string }>();\n\n/**\n * The config file and path an entry was parsed from, for a refusal that is\n * known only once a page is: a `{page}` manifest resolving above the config\n * directory. `undefined` for an entry `parseCollections` did not build.\n */\nexport function externalMetadataOrigin(\n entry: ExternalMetadataConfig,\n): { source: string; where: string } | undefined {\n return origins.get(entry);\n}\n\n/**\n * Does `manifest`, one of `collection`'s, own `key` for one page? The one\n * answer every reader and writer asks for (proposal 0068).\n *\n * A manifest with `keys` owns exactly those, for every page. One without owns\n * what `marked` holds: the top-level keys the page's resolved schema set marks\n * `x-manni-location: external`. It never owns a key another manifest of the\n * collection names in its own `keys`, because written keys win. Nor its own\n * join field, which the page carries to name its entry, nor `$schema`. With\n * `marked` undefined, because the page's schemas are not known, a keyless\n * manifest owns nothing.\n */\nexport function ownsKey(\n collection: Pick<CollectionConfig, \"externalMetadata\">,\n manifest: ExternalMetadataConfig,\n key: string,\n marked: ReadonlySet<string> | undefined,\n): boolean {\n if (manifest.keys !== undefined) return manifest.keys.includes(key);\n if (marked === undefined || !marked.has(key)) return false;\n return !neverOwned(collection, manifest).has(key);\n}\n\n/**\n * The keys a keyless manifest never owns, whatever a page marks: the keys\n * the collection's other manifests name, its join field, and `$schema`. An\n * entry setting one of them is refused when the manifest is read.\n */\nexport function neverOwned(\n collection: Pick<CollectionConfig, \"externalMetadata\">,\n manifest: ExternalMetadataConfig,\n): ReadonlySet<string> {\n return declaredNever.get(manifest) ?? neverOwnedIn(collection.externalMetadata, manifest);\n}\n\nfunction neverOwnedIn(\n manifests: readonly ExternalMetadataConfig[],\n manifest: ExternalMetadataConfig,\n): Set<string> {\n const out = new Set<string>([SCHEMA_KEY]);\n if (manifest.join !== undefined && manifest.join !== PATH_JOIN) out.add(manifest.join);\n for (const other of manifests) {\n if (other === manifest) continue;\n for (const key of other.keys ?? []) out.add(key);\n }\n return out;\n}\n\n/**\n * `neverOwned` for each keyless manifest `parseCollections` built, computed\n * over its whole collection. Kept beside the entry, as `origins` is, so a\n * copy of the collection filtered to some of its manifests does not forget a\n * key a manifest it left out names.\n */\nconst declaredNever = new WeakMap<ExternalMetadataConfig, ReadonlySet<string>>();\n\n/**\n * The collections a run covers: every one when `names` is undefined, else the\n * named ones in **declaration** order, however they were named on the command\n * line. Repeats collapse; an unknown name is an error, because a typo that\n * silently narrowed the run to nothing would read as a clean pass.\n */\nexport function selectCollections(\n collections: readonly CollectionConfig[],\n names: readonly string[] | undefined,\n source: string,\n toError: (message: string) => Error,\n): CollectionConfig[] {\n // An empty list means the same as no list: every collection. Commander's\n // repeatable-option collector defaults to `[]`, so \"the user passed no\n // --collection\" reaches this function as an empty array at least as often as\n // it reaches it as `undefined`. Were `[]` to select nothing, a plain\n // `manni meta validate` would validate zero files and exit 0 the moment a\n // caller forwarded the raw commander value — the false green proposal 0014\n // exists to end, and invisible in the exit code. Nothing needs to express\n // \"select no collections\", so the ambiguity is resolved in the safe\n // direction. Do not tighten this back.\n if (names === undefined || names.length === 0) return [...collections];\n const wanted = new Set(names);\n for (const name of wanted) {\n if (!collections.some((c) => c.name === name)) {\n const configured =\n collections.length === 0\n ? \"(none)\"\n : collections.map((c) => c.name).join(\", \");\n // Names are unique case-insensitively (they become SQL views) but are\n // selected by their one spelling. When the miss is only a casing miss,\n // say so — \"Configured: guides\" beside \"Guides\" reads as a contradiction\n // to anyone who does not already know the rule.\n const nearMiss = collections.find(\n (c) => c.name.toLowerCase() === name.toLowerCase(),\n );\n const hint =\n nearMiss === undefined\n ? \"\"\n : ` Names are case-sensitive; did you mean \"${nearMiss.name}\"?`;\n throw toError(\n `no collection named \"${name}\" in ${source}. Configured: ${configured}.${hint}`,\n );\n }\n }\n return collections.filter((c) => wanted.has(c.name));\n}\n\n/**\n * Is this file a member of the collection? `relPath` is posix and already\n * relative to the config file's directory, so this is arithmetic on a string:\n * no `stat`, nothing that can fail, and nothing that costs per file. A path\n * that climbed out of the config directory, and stdin, are members of nothing.\n */\nexport function isMember(\n collection: CollectionConfig,\n relPath: string,\n): boolean {\n if (relPath === STDIN) return false;\n if (relPath.startsWith(\"../\")) return false;\n return matchesCollectionPaths(collection, relPath);\n}\n\n/**\n * Do the collection's `paths:` and `exclude:` claim this path, before the two\n * guards `isMember` adds? Only a caller that has to *say* why a claimed path\n * is not a member needs this: a page above the config directory that a\n * `{page}` manifest would resolve outside the tree (proposal 0058). Everyone\n * else wants `isMember`.\n */\nexport function matchesCollectionPaths(\n collection: CollectionConfig,\n relPath: string,\n): boolean {\n const matched = collection.paths.some((entry) => {\n const normalized = normalizeEntry(entry);\n if (normalized === \"\") return false;\n if (isGlob(normalized)) return matchesFileGlob(relPath, normalized);\n return relPath === normalized || relPath.startsWith(`${normalized}/`);\n });\n if (!matched) return false;\n // `exclude` is globs only, whatever `paths` was written as.\n return !collection.exclude.some((glob) => matchesFileGlob(relPath, glob));\n}\n\n/** A `paths` entry as a posix path with no `./` prefix and no trailing `/`. */\nfunction normalizeEntry(entry: string): string {\n const posix = entry.replace(/\\\\/g, \"/\").replace(/^\\.\\//, \"\");\n return posix.endsWith(\"/\") ? posix.slice(0, -1) : posix;\n}\n\n/**\n * Is this `paths` entry a glob, by picomatch's own definition, rather than a\n * bare file or directory to match by prefix?\n *\n * picomatch decides, not a character class of our own: an extended glob such\n * as `docs/!(drafts)/**` or `@(a|b)` has no `*`, `?`, `[` or `{` of its own\n * and a hand-rolled test read it as a literal path — matching nothing and\n * excluding nothing, silently. The one cost is that a literal directory whose\n * name carries parentheses, `docs/notes (old)`, is also read as a glob and so\n * matches itself only, not everything beneath it. Spell such a path as\n * `docs/notes (old)/**` to get the prefix behaviour back.\n */\nfunction isGlob(entry: string): boolean {\n return picomatch.scan(entry).isGlob;\n}\n","/**\n * Glob matching, shared by every tool.\n *\n * One matcher, so that the two questions that look alike really are alike: is\n * this file in a collection (proposal 0041), and does it match a schema\n * override's `files:` (0015). It lived in the metadata tool's schema resolver\n * until membership needed it too; a second copy is how the two would start\n * disagreeing about a dot file or a `\\`.\n */\nimport picomatch from \"picomatch\";\n\n/**\n * One compiled matcher per distinct glob, kept for the life of the process.\n * Never evicted, on purpose: the set of globs a run sees is the config's plus\n * a handful of flags, which is dozens at most, and a compile is the expensive\n * step. This module is shared across the family, so if it ever sits inside a\n * long-lived host that feeds it unbounded user globs, this is the line to\n * revisit — bound it, or key it per run. Until then an eviction policy would\n * be machinery for a case that does not exist.\n */\nconst matcherCache = new Map<string, (p: string) => boolean>();\n\n/**\n * Does this file path match the glob — or, for the list form, any of them — by\n * the shared rules (picomatch, dot files included, `\\` normalized to `/`)?\n */\nexport function matchesFileGlob(\n relPath: string,\n glob: string | readonly string[],\n): boolean {\n // picomatch takes a pattern array natively, so the list form needs no loop\n // here — but the cache does need a *string* key. Keyed on the array itself\n // this Map would compare by identity: a hit only for the very same object,\n // and an entry retained for every config ever parsed. JSON.stringify is the\n // key because it separates the two shapes on its own — a lone \"a/**\" and\n // [\"a/**\"] serialize differently — with no separator char to collide with\n // one inside a glob.\n const key = JSON.stringify(glob);\n let m = matcherCache.get(key);\n if (!m) {\n m = picomatch(glob as string | string[], { dot: true });\n matcherCache.set(key, m);\n }\n // Normalize Windows separators so globs written with `/` still match.\n return m(relPath.replace(/\\\\/g, \"/\"));\n}\n","/**\n * The `{page}` placeholder in `externalMetadata[].file` (proposal 0058).\n *\n * A `file` holding `{page}` is a rule rather than a file: each page gets its\n * own manifest, named by substituting the page's path, relative to the config\n * file's directory and without its extension. `\"{page}.citations.yaml\"` puts\n * `docs/x/index.mdx`'s manifest at `docs/x/index.citations.yaml`.\n *\n * One normalization is used wherever a pattern or a page path is compared or\n * substituted (0058 § 1): strip one leading `./`, and write every separator as\n * a forward slash. It is deliberately that small. It is not `path.resolve`, so\n * `./a/../{page}.yaml` stays its own pattern, and it does not fold case.\n *\n * The grammar itself (one token, spelled exactly, never in a URL or an\n * absolute path) is enforced by the config parser in `collections.ts`, so\n * everything here may assume a `file` that passed it.\n *\n * Shared, so it imports nothing from a tool.\n */\nimport { readFileSync, realpathSync } from \"node:fs\";\nimport { isAbsolute, posix, relative, resolve, sep } from \"node:path\";\nimport fg from \"fast-glob\";\nimport { LineCounter, isMap, isNode, isScalar, parseDocument } from \"yaml\";\n\n/** The one placeholder `externalMetadata[].file` accepts. */\nexport const PAGE_PLACEHOLDER = \"{page}\";\n\n/** True when `file` contains the {page} token (assumes it already passed parse validation). */\nexport function hasPagePlaceholder(file: string): boolean {\n return file.includes(PAGE_PLACEHOLDER);\n}\n\n/** Every separator written as a forward slash. */\nfunction slashes(path: string): string {\n return path.split(sep).join(\"/\").replace(/\\\\/g, \"/\");\n}\n\n/**\n * 0058 § 1 normalization: strip one leading \"./\", backslashes to \"/\". No case\n * folding, no path.resolve, no \"..\" collapsing.\n */\nexport function normalizeManifestPattern(file: string): string {\n const forward = file.replace(/\\\\/g, \"/\");\n return forward.startsWith(\"./\") ? forward.slice(2) : forward;\n}\n\n/**\n * The manifest a page resolves to. `configDir` absolute; `pageAbs` absolute.\n *\n * `{page}` is `relative(configDir, pageAbs)` with its extension removed,\n * normalized as above, substituted into the normalized pattern. Returns the\n * manifest's absolute path and its posix path relative to `configDir`, or\n * `{ outside: true, pageRel }` when the page is not under the config\n * directory: its relative path climbs with `../`, or, across Windows drives,\n * there is no relative path at all.\n */\nexport function pageManifestPath(\n file: string,\n configDir: string,\n pageAbs: string,\n): { abs: string; rel: string } | { outside: true; pageRel: string } {\n const between = relative(configDir, pageAbs);\n const pageRel = slashes(between);\n if (isAbsolute(between) || pageRel === \"..\" || pageRel.startsWith(\"../\")) {\n return { outside: true, pageRel };\n }\n const ext = posix.extname(pageRel);\n const page = ext === \"\" ? pageRel : pageRel.slice(0, -ext.length);\n const named = normalizeManifestPattern(file).replace(PAGE_PLACEHOLDER, () => page);\n const abs = resolve(configDir, named);\n return { abs, rel: slashes(relative(configDir, abs)) };\n}\n\n/**\n * 0058 § 5: the glob every manifest of a pattern matches. The normalized\n * pattern is split at `{page}` and `**` + `/*` inserted, keeping the prefix\n * and the suffix. No page path reaches it, but the prefix and suffix are the\n * config author's own literal text, and a directory name may hold glob\n * syntax: read raw, `meta (v2)/` is an extglob group that matches nothing. So\n * both are escaped, and only the inserted `**` + `/*` is live.\n * `\"{page}.citations.yaml\"` gives `**` + `/*.citations.yaml`, and\n * `\"./meta/{page}.citations.yaml\"` gives `meta/**` + `/*.citations.yaml`.\n */\nexport function strayManifestGlob(file: string): string {\n const normalized = normalizeManifestPattern(file);\n const at = normalized.indexOf(PAGE_PLACEHOLDER);\n if (at < 0) return literal(normalized);\n const prefix = literal(normalized.slice(0, at));\n const suffix = literal(normalized.slice(at + PAGE_PLACEHOLDER.length));\n return `${prefix}**/*${suffix}`;\n}\n\n/** Text a glob matches exactly. fast-glob refuses to escape an empty string. */\nfunction literal(text: string): string {\n return text === \"\" ? \"\" : fg.escapePath(text);\n}\n\n/** One entry of a per-page manifest found on disk, naming the page it is for. */\nexport interface FoundPageEntry {\n /** The key exactly as the manifest spells it. */\n spelled: string;\n /** The page it names, absolute. */\n pageAbs: string;\n /** 1-based line of the key in the manifest, when known. */\n line?: number;\n}\n\n/** A manifest file a `{page}` pattern names, and the entries it holds for its own page. */\nexport interface FoundPageManifest {\n /** The manifest, absolute. */\n abs: string;\n entries: FoundPageEntry[];\n}\n\n/**\n * The manifests on disk that `file`, a `{page}` pattern, names (0058 § 5):\n * every file the pattern's `strayManifestGlob` matches under `configDir`,\n * kept when it holds an entry the pattern resolves back to that very file,\n * for a page `isMember` claims. `isMember` takes the page's posix path\n * relative to `configDir`. A file with no such entry is not this pattern's\n * manifest, whatever its name: a copy of the tree elsewhere, a fixture, or a\n * file that only looks like one.\n *\n * The walk does not consult `.gitignore`, because a manifest is config named\n * input rather than a discovered document. It skips `node_modules`, `.git`\n * and dot directories, as the document walk does, so a checkout nested under\n * a dot directory is never read as this one's. A file that cannot be read or\n * parsed is not recognizably a manifest, and is skipped.\n *\n * Synchronous, so a synchronous orphan check can call it. It runs once per\n * whole-corpus run, never for a run given paths. A match in `skip` (absolute\n * paths) is neither read nor returned: the orphan check passes the manifests\n * the run already loaded, which would otherwise be parsed a second time.\n */\nexport function findPageManifests(\n file: string,\n configDir: string,\n isMember: (relPath: string) => boolean,\n skip: ReadonlySet<string> = new Set(),\n): FoundPageManifest[] {\n const matched = fg\n .sync(strayManifestGlob(file), {\n cwd: configDir,\n absolute: true,\n onlyFiles: true,\n dot: false,\n ignore: [\"**/node_modules/**\", \"**/.git/**\"],\n })\n .map((path) => resolve(path))\n .sort();\n const found: FoundPageManifest[] = [];\n for (const abs of matched) {\n if (skip.has(abs)) continue;\n const entries = ownEntries(abs, file, configDir, isMember);\n if (entries.length > 0) found.push({ abs, entries });\n }\n return found;\n}\n\n/** The entries of the manifest at `abs` that `file` resolves back to `abs`. */\nfunction ownEntries(\n abs: string,\n file: string,\n configDir: string,\n isMember: (relPath: string) => boolean,\n): FoundPageEntry[] {\n let text: string;\n try {\n text = readFileSync(abs, \"utf8\");\n } catch {\n return [];\n }\n const lc = new LineCounter();\n const doc = parseDocument(text, { lineCounter: lc, uniqueKeys: false });\n const root = doc.contents;\n if (doc.errors.length > 0 || !isMap(root)) return [];\n const entries: FoundPageEntry[] = [];\n for (const pair of root.items) {\n const spelled = isScalar(pair.key) ? String(pair.key.value) : String(pair.key);\n const pageAbs = resolve(configDir, spelled);\n if (!isMember(slashes(relative(configDir, pageAbs)))) continue;\n const resolved = pageManifestPath(file, configDir, pageAbs);\n if (\"outside\" in resolved || !sameFile(resolved.abs, abs)) continue;\n const range = isNode(pair.key) ? pair.key.range : undefined;\n entries.push({\n spelled,\n pageAbs,\n ...(range ? { line: lc.linePos(range[0]).line } : {}),\n });\n }\n return entries;\n}\n\n/**\n * Are these one file, as the filesystem resolves them? Compared as files and\n * not as text (0058 stress test 8), so a case-only difference is one file on\n * a case-insensitive filesystem and two elsewhere.\n */\nexport function sameFile(a: string, b: string): boolean {\n if (a === b) return true;\n try {\n return realpathSync(a) === realpathSync(b);\n } catch {\n return false;\n }\n}\n","/**\n * `tools:`, the family-level home for an outside tool's settings (proposal\n * 0052, in the shape lint's proposal 0050 recorded).\n *\n * An outside tool is not any one domain's, so its settings do not sit under a\n * domain's key. Vale is the case in point: `manni term lint` runs it, and so\n * does a docevals grader. Each should read one description of where Vale's\n * config lives, not two that can disagree.\n *\n * Each tool gets a namespace of its own keys rather than a shared\n * `{tool, config}` shape, because tools do not have the same settings. A\n * lowest-common-denominator shape would either lie or grow a passthrough blob.\n *\n * Only the declaration is shared. Running a tool stays with the domain that\n * runs it. Paths are kept as the user spelled them and resolved on use,\n * against the config file's directory, the way `collections:` keeps its globs;\n * whether the file exists is a question for the run that needs it.\n */\nimport { isAbsolute, resolve } from \"node:path\";\n\n/** Vale's settings under `tools.vale`. */\nexport interface ValeToolConfig {\n /** Vale's config file, as written, relative to `manni.config.yaml`. */\n config?: string;\n}\n\n/** DITA Open Toolkit's settings under `tools.dita-ot`. */\nexport interface DitaOtToolConfig {\n /**\n * DITA-OT's installation directory, as written, relative to\n * `manni.config.yaml`. Unset means the `dita` on PATH.\n *\n * A directory rather than a path to the launcher, because that is the unit\n * DITA-OT is distributed and documented as: the download unpacks to one\n * directory, and `bin/dita` inside it will not run from anywhere else.\n */\n home?: string;\n}\n\n/** The document's top-level `tools:`, one namespace per outside tool. */\nexport interface ToolsConfig {\n vale?: ValeToolConfig;\n \"dita-ot\"?: DitaOtToolConfig;\n}\n\nconst TOOL_KEYS = [\"vale\", \"dita-ot\"] as const;\nconst VALE_KEYS = [\"config\"] as const;\nconst DITA_OT_KEYS = [\"home\"] as const;\n\nfunction isMapping(value: unknown): value is Record<string, unknown> {\n return typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction rejectUnknownKeys(\n raw: Record<string, unknown>,\n allowed: readonly string[],\n where: string,\n source: string,\n toError: (message: string) => Error,\n): void {\n for (const key of Object.keys(raw)) {\n if (!allowed.includes(key)) {\n throw toError(\n `${source}: ${where} has unknown key \"${key}\". Supported keys: ${allowed.join(\", \")}.`,\n );\n }\n }\n}\n\n/**\n * Parse the value under the top-level `tools:` key. A bare `tools:` (YAML\n * null) is no tools. Every refusal is a shape that would otherwise read as\n * configured and do nothing: a misspelled tool, or a key a tool never reads.\n */\nexport function parseTools(\n raw: unknown,\n source: string,\n toError: (message: string) => Error,\n): ToolsConfig {\n if (raw === null || raw === undefined) return {};\n if (!isMapping(raw)) {\n throw toError(`${source}: \"tools\" must be a mapping.`);\n }\n rejectUnknownKeys(raw, TOOL_KEYS, \"tools\", source, toError);\n\n const tools: ToolsConfig = {};\n if (Object.hasOwn(raw, \"vale\")) {\n tools.vale = parseVale(raw[\"vale\"], source, toError);\n }\n if (Object.hasOwn(raw, \"dita-ot\")) {\n tools[\"dita-ot\"] = parseDitaOt(raw[\"dita-ot\"], source, toError);\n }\n return tools;\n}\n\nfunction parseVale(\n raw: unknown,\n source: string,\n toError: (message: string) => Error,\n): ValeToolConfig {\n if (!isMapping(raw)) {\n throw toError(`${source}: tools.vale must be a mapping.`);\n }\n rejectUnknownKeys(raw, VALE_KEYS, \"tools.vale\", source, toError);\n\n const vale: ValeToolConfig = {};\n if (Object.hasOwn(raw, \"config\")) {\n const config = raw[\"config\"];\n if (typeof config !== \"string\" || config.trim() === \"\") {\n throw toError(`${source}: tools.vale.config must be a non-empty string.`);\n }\n vale.config = config;\n }\n return vale;\n}\n\nfunction parseDitaOt(\n raw: unknown,\n source: string,\n toError: (message: string) => Error,\n): DitaOtToolConfig {\n if (!isMapping(raw)) {\n throw toError(`${source}: tools.dita-ot must be a mapping.`);\n }\n rejectUnknownKeys(raw, DITA_OT_KEYS, \"tools.dita-ot\", source, toError);\n\n const ditaOt: DitaOtToolConfig = {};\n if (Object.hasOwn(raw, \"home\")) {\n const home = raw[\"home\"];\n if (typeof home !== \"string\" || home.trim() === \"\") {\n throw toError(`${source}: tools.dita-ot.home must be a non-empty string.`);\n }\n ditaOt.home = home;\n }\n return ditaOt;\n}\n\n/**\n * The absolute path of Vale's config file, resolved against the directory of\n * the config file that declared it. `undefined` when none is set, which means\n * Vale finds its own config, as it does when a person runs it.\n */\nexport function valeConfigPath(tools: ToolsConfig, configDir: string): string | undefined {\n const config = tools.vale?.config;\n if (config === undefined) return undefined;\n return isAbsolute(config) ? config : resolve(configDir, config);\n}\n\n/**\n * The absolute path of DITA-OT's installation directory, resolved against the\n * directory of the config file that declared it. `undefined` when none is set,\n * which means the `dita` on PATH, as when a person runs it.\n */\nexport function ditaOtHome(tools: ToolsConfig, configDir: string): string | undefined {\n const home = tools[\"dita-ot\"]?.home;\n if (home === undefined) return undefined;\n return isAbsolute(home) ? home : resolve(configDir, home);\n}\n","/**\n * The family config file.\n *\n * One file per repository, `manni.config.yaml`, with one top-level key per\n * tool: `meta:` for the metadata tool, `docevals:`, `tracevals:`, `lint:`,\n * `graph:` as each lands. A tool reads its own key and leaves its siblings alone,\n * so adding a tool never invalidates a config that predates it.\n *\n * This module only finds the file and hands a tool its slice. What the slice\n * may contain is the tool's business; it validates the value with its own\n * parser and its own error class, which is why `toError` is an option rather\n * than an import. Four top-level keys belong to the family rather than to a\n * tool, and are parsed here once for every tool. They are `collections:`\n * (proposal 0041), `tools:` (proposal 0052) and `encryptionKey:` (proposal\n * 0045). The fourth is `providers:`, the inference provider settings every\n * tool that sends content to a model reads.\n *\n * One older spelling is still read, with a warning on discovery: each tool's\n * pre-family file (`docmeta.config.yaml` for the metadata tool), whose whole\n * document is the tool's section with no wrapper key.\n *\n * Within one directory the order is manni, then the legacy names, and\n * `.yaml` before `.yml`. A family file that exists but has neither a key for\n * this tool nor a family key is not this tool's config: discovery keeps\n * looking, first at the legacy names beside it (a repository mid-migration,\n * where a sibling tool moved to the family file first) and then up the tree.\n * The walk stops at the nearest `.git` boundary, nearest directory first, and\n * the first hit wins; ancestor files are never merged.\n *\n * An explicit path is read the same way minus the warning: the section key is\n * unwrapped when present, a document carrying a family key is a family file\n * with an empty section, and the whole document is taken otherwise, so a\n * `-c ./anything.yaml` needs no filename sniffing and no flag.\n *\n * The core is synchronous: some tools load config from synchronous library\n * entry points, and one small file read is not worth an `await` through their\n * public API. `findConfigFileSync` and `readConfigFileSync` expose it; the\n * async spellings are wrappers over the same core for callers that await.\n */\nimport { readFileSync } from \"node:fs\";\nimport { basename, dirname, join, relative, resolve } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport { parseCollections, type CollectionConfig } from \"./collections.js\";\nimport { isValidEncryptionKey } from \"./encryption.js\";\nimport { PROVIDERS_KEY, parseProviders, type ProvidersConfig } from \"./providers.js\";\nimport { searchPath } from \"./git-root.js\";\nimport { parseTools, type ToolsConfig } from \"./tools.js\";\nimport { warn } from \"./warn.js\";\nimport { errorMessage } from \"./errors.js\";\n\n/** The canonical family filenames, in discovery order. */\nexport const FAMILY_CONFIG_NAMES: readonly string[] = [\n \"manni.config.yaml\",\n \"manni.config.yml\",\n];\n\n/** The top-level key holding the family encryption key (proposal 0045). */\nexport const ENCRYPTION_KEY_FIELD = \"encryptionKey\";\n\n/**\n * The top-level key holding the key a rotation is replacing (proposal 0045).\n * Present only while a rotation is unfinished: `manni key rotate` writes it\n * beside the new key before it touches a page, and removes it once every page\n * is written. Read only by `manni key rotate`, which finishes the rotation.\n */\nexport const ENCRYPTION_KEY_PREVIOUS_FIELD = \"encryptionKeyPrevious\";\n\nexport interface ConfigFileOptions {\n /** The tool's key in a family file, e.g. `\"meta\"`. */\n section: string;\n /**\n * The tool's own filenames from before the family file, in discovery order.\n * Their whole document is the tool's section.\n */\n legacyNames: readonly string[];\n /** Build the error for an unreadable document, in the tool's own class. */\n toError: (message: string) => Error;\n}\n\nexport interface ConfigFile {\n /** Absolute path to the file. */\n path: string;\n /** Directory holding it; relative paths in the config resolve from here. */\n dir: string;\n /**\n * The file as the user would name it: relative to `cwd`, posix separators,\n * or the spelling they typed for an explicit path. For error messages.\n */\n source: string;\n /** The file's text, for a tool that rewrites the file in place. */\n text: string;\n /**\n * The tool's slice: the value under `section:` when `wrapped`, otherwise\n * the whole document. `null` for an empty file or an empty section; the\n * tool decides what empty means.\n */\n value: unknown;\n /** Whether `value` came from under `section:`. */\n wrapped: boolean;\n /** How the file was found. Explicit paths are never warned about. */\n kind: \"manni\" | \"legacy\" | \"explicit\";\n /**\n * The document's top-level `collections:` (proposal 0041), parsed once here\n * because every tool reads the same declaration. `[]` when the key is\n * absent, and always `[]` for a `legacy` file: a per-tool file's whole\n * document *is* the tool's section, so it carries no family-wide keys.\n */\n collections: CollectionConfig[];\n /**\n * The document's top-level `tools:` (proposal 0052), an outside tool's\n * settings, parsed once here for the same reason as `collections`. `{}` when\n * the key is absent, and always `{}` for a `legacy` file.\n */\n tools: ToolsConfig;\n /**\n * The document's top-level `encryptionKey:` (proposal 0045), validated\n * here. Absent when the key is, and always absent for a `legacy` file, for\n * the same reason as `collections`. `MANNI_ENCRYPTION_KEY` wins over it;\n * read it through `resolveEncryptionKey`, not directly.\n */\n encryptionKey?: string;\n /**\n * The document's top-level `encryptionKeyPrevious:`, validated here as\n * `encryptionKey` is. Present only while a rotation is unfinished, and read\n * only by `manni key rotate`, which finishes it.\n */\n encryptionKeyPrevious?: string;\n /**\n * The document's top-level `providers:`, parsed here with a relative\n * `llama-cpp.modelsDir` resolved against `dir`. Absent when the key is, and\n * always absent for a `legacy` file, for the same reason as `collections`.\n */\n providers?: ProvidersConfig;\n}\n\ntype ToError = (message: string) => Error;\n\ninterface Document {\n text: string;\n /** Parsed YAML: a mapping, or `null` for an empty file. */\n doc: Record<string, unknown> | null;\n}\n\nfunction readDocument(\n path: string,\n source: string,\n toError: ToError,\n): Document | null {\n let text: string;\n try {\n text = readFileSync(path, \"utf8\");\n } catch {\n return null;\n }\n return { text, doc: parseMapping(text, source, toError) };\n}\n\n/**\n * Parse outside any \"not found\" handling. A discovered file with a typo must\n * be reported, not skipped: falling through to the next candidate, or to no\n * config at all, would run the tool on defaults and read as a clean pass.\n */\nfunction parseMapping(\n text: string,\n source: string,\n toError: ToError,\n): Record<string, unknown> | null {\n let raw: unknown;\n try {\n raw = parseYaml(text);\n } catch (err) {\n throw toError(`${source}: invalid YAML: ${errorMessage(err)}`);\n }\n if (raw == null) return null;\n if (typeof raw !== \"object\" || Array.isArray(raw)) {\n throw toError(`${source}: top level must be a mapping.`);\n }\n return raw as Record<string, unknown>;\n}\n\n/** The top-level key holding the family's document sets. */\nconst COLLECTIONS_KEY = \"collections\";\n\n/** The top-level key holding outside tools' settings (proposal 0052). */\nconst TOOLS_KEY = \"tools\";\n\n/** The keys that belong to the family, not to any one tool. */\nconst FAMILY_KEYS: readonly string[] = [\n COLLECTIONS_KEY,\n TOOLS_KEY,\n ENCRYPTION_KEY_FIELD,\n PROVIDERS_KEY,\n];\n\nfunction slice(\n document: Document,\n opts: ConfigFileOptions,\n): { value: unknown; wrapped: boolean } | null {\n const { doc } = document;\n if (doc !== null && Object.hasOwn(doc, opts.section)) {\n return { value: doc[opts.section] ?? null, wrapped: true };\n }\n // A family file carrying a family key and no section is still this tool's\n // config: the documents are declared (0041), or the key is (0045), or the\n // provider settings are, and the tool just has no options of its own.\n // Handing back an empty section is what stops discovery walking past it.\n // For the key that matters twice: a\n // file the key prompt created holds nothing else, and the next run must\n // find it.\n if (doc !== null && FAMILY_KEYS.some((key) => Object.hasOwn(doc, key))) {\n return { value: null, wrapped: true };\n }\n return null;\n}\n\n/**\n * The document's collections. Parsed with the tool's own `toError`, so a bad\n * `collections:` is reported in the class the tool already catches.\n */\nfunction collectionsOf(\n document: Document,\n source: string,\n toError: ToError,\n): CollectionConfig[] {\n const { doc } = document;\n if (doc === null || !Object.hasOwn(doc, COLLECTIONS_KEY)) return [];\n return parseCollections(doc[COLLECTIONS_KEY], source, toError);\n}\n\n/**\n * The document's outside-tool settings. Parsed with the tool's own `toError`,\n * as `collections:` is.\n */\nfunction toolsOf(document: Document, source: string, toError: ToError): ToolsConfig {\n const { doc } = document;\n if (doc === null || !Object.hasOwn(doc, TOOLS_KEY)) return {};\n return parseTools(doc[TOOLS_KEY], source, toError);\n}\n\n/**\n * The document's encryption key, as a spreadable field. A malformed one is an\n * error in the tool's class, and the message never repeats the value: it is\n * key material, and a CI log is not the place for it.\n */\nfunction encryptionKeyOf(\n document: Document,\n source: string,\n toError: ToError,\n): { encryptionKey?: string; encryptionKeyPrevious?: string } {\n const { doc } = document;\n if (doc === null) return {};\n const keys: { encryptionKey?: string; encryptionKeyPrevious?: string } = {};\n if (Object.hasOwn(doc, ENCRYPTION_KEY_FIELD)) {\n const value = doc[ENCRYPTION_KEY_FIELD];\n if (!isValidEncryptionKey(value)) {\n throw toError(\n `${source}: \"${ENCRYPTION_KEY_FIELD}\" must be at least 32 hex or base64url characters. Run \\`manni key set\\` to generate one.`,\n );\n }\n keys.encryptionKey = value;\n }\n // The key an unfinished rotation is replacing. Key material too, so the\n // same shape rule and the same silence about the value. There is no advice\n // to generate one: `manni key rotate` writes it, and nothing else should.\n if (Object.hasOwn(doc, ENCRYPTION_KEY_PREVIOUS_FIELD)) {\n const value = doc[ENCRYPTION_KEY_PREVIOUS_FIELD];\n if (!isValidEncryptionKey(value)) {\n throw toError(\n `${source}: \"${ENCRYPTION_KEY_PREVIOUS_FIELD}\" must be at least 32 hex or base64url characters.`,\n );\n }\n keys.encryptionKeyPrevious = value;\n }\n return keys;\n}\n\n/**\n * The document's provider settings, as a spreadable field. Parsed with the\n * tool's own `toError`, and a relative path in them resolves from `dir`.\n */\nfunction providersOf(\n document: Document,\n source: string,\n dir: string,\n toError: ToError,\n): { providers?: ProvidersConfig } {\n const { doc } = document;\n if (doc === null || !Object.hasOwn(doc, PROVIDERS_KEY)) return {};\n return { providers: parseProviders(doc[PROVIDERS_KEY], source, dir, toError) };\n}\n\n/**\n * The family keys as `manni key` reads them: only valid ones, and a malformed\n * one is no error, because replacing it is what the caller is for.\n */\nfunction tolerantKeysOf(document: Document): {\n encryptionKey?: string;\n encryptionKeyPrevious?: string;\n} {\n const key = document.doc?.[ENCRYPTION_KEY_FIELD];\n const previous = document.doc?.[ENCRYPTION_KEY_PREVIOUS_FIELD];\n return {\n ...(isValidEncryptionKey(key) ? { encryptionKey: key } : {}),\n ...(isValidEncryptionKey(previous) ? { encryptionKeyPrevious: previous } : {}),\n };\n}\n\nfunction relativeSource(cwd: string, path: string): string {\n return relative(cwd, path).replace(/\\\\/g, \"/\");\n}\n\n/**\n * Discover the tool's config from `cwd` upward. `null` when nothing exists.\n */\nexport function findConfigFileSync(\n cwd: string,\n opts: ConfigFileOptions,\n): ConfigFile | null {\n const start = resolve(cwd);\n for (const dir of searchPath(start)) {\n for (const name of FAMILY_CONFIG_NAMES) {\n const path = join(dir, name);\n const source = relativeSource(start, path);\n const document = readDocument(path, source, opts.toError);\n if (document === null) continue;\n const found = slice(document, opts);\n // A family file without this tool's key belongs to a sibling. Keep\n // looking, rather than treating the file as an empty config.\n if (found === null) continue;\n return {\n path,\n dir,\n source,\n text: document.text,\n kind: \"manni\",\n collections: collectionsOf(document, source, opts.toError),\n tools: toolsOf(document, source, opts.toError),\n ...encryptionKeyOf(document, source, opts.toError),\n ...providersOf(document, source, dir, opts.toError),\n ...found,\n };\n }\n for (const name of opts.legacyNames) {\n const path = join(dir, name);\n const source = relativeSource(start, path);\n const document = readDocument(path, source, opts.toError);\n if (document === null) continue;\n warn(\n `\"${name}\" is a deprecated config file name. Move its keys under \\`${opts.section}:\\` in \"${FAMILY_CONFIG_NAMES[0] ?? \"manni.config.yaml\"}\", and its paths, exclude and sidecars keys to a top-level collections: list, where sidecars becomes externalMetadata.`,\n );\n return {\n path,\n dir,\n source,\n text: document.text,\n value: document.doc,\n wrapped: false,\n kind: \"legacy\",\n collections: [],\n tools: {},\n };\n }\n }\n return null;\n}\n\n/**\n * Read the config at an explicit path. Missing is an error: a `-c` pointing\n * at a file that is not there is a mistake worth failing on, not a reason to\n * quietly run against something else.\n */\nexport function readConfigFileSync(\n explicitPath: string,\n cwd: string,\n opts: ConfigFileOptions,\n): ConfigFile {\n const path = resolve(cwd, explicitPath);\n // Report the spelling the user typed, not the resolved absolute path.\n const document = readDocument(path, explicitPath, opts.toError);\n if (document === null) {\n throw opts.toError(`Config file not found: \"${explicitPath}\".`);\n }\n const found = slice(document, opts) ?? {\n value: document.doc,\n wrapped: false,\n };\n return {\n path,\n dir: dirname(path),\n source: explicitPath,\n text: document.text,\n kind: \"explicit\",\n collections: collectionsOf(document, explicitPath, opts.toError),\n tools: toolsOf(document, explicitPath, opts.toError),\n // An unwrapped document carries no family key (else it would be wrapped),\n // so this only ever reads a family file's key.\n ...encryptionKeyOf(document, explicitPath, opts.toError),\n ...providersOf(document, explicitPath, dirname(path), opts.toError),\n ...found,\n };\n}\n\n/** `findConfigFileSync`, for callers that await. */\nexport function findConfigFile(\n cwd: string,\n opts: ConfigFileOptions,\n): Promise<ConfigFile | null> {\n return Promise.resolve().then(() => findConfigFileSync(cwd, opts));\n}\n\n/** `readConfigFileSync`, for callers that await. */\nexport function readConfigFile(\n explicitPath: string,\n cwd: string,\n opts: ConfigFileOptions,\n): Promise<ConfigFile> {\n return Promise.resolve().then(() =>\n readConfigFileSync(explicitPath, cwd, opts),\n );\n}\n\n/**\n * The nearest family file from `cwd` upward, whatever it carries: any tool's\n * section, a family key, or nothing at all. For `manni key`, which writes the\n * family's key and so belongs to no one tool's section. Never a legacy\n * per-tool file, whose whole document is one tool's section.\n *\n * `value` is `null` and `wrapped` is `true`: no tool's section is handed\n * over. `encryptionKey` is set only when the file holds a valid one. A\n * malformed key is not an error here, unlike in `findConfigFile`, because\n * replacing it is what the caller is for.\n */\nexport function findFamilyConfigFile(\n cwd: string,\n toError: ToError,\n): Promise<ConfigFile | null> {\n return Promise.resolve().then(() => findFamilyConfigFileSync(cwd, toError));\n}\n\nfunction findFamilyConfigFileSync(\n cwd: string,\n toError: ToError,\n): ConfigFile | null {\n const start = resolve(cwd);\n for (const dir of searchPath(start)) {\n for (const name of FAMILY_CONFIG_NAMES) {\n const path = join(dir, name);\n const source = relativeSource(start, path);\n const document = readDocument(path, source, toError);\n if (document === null) continue;\n return {\n path,\n dir,\n source,\n text: document.text,\n value: null,\n wrapped: true,\n kind: \"manni\",\n collections: collectionsOf(document, source, toError),\n tools: toolsOf(document, source, toError),\n ...tolerantKeysOf(document),\n };\n }\n }\n return null;\n}\n\n/**\n * Read an explicit path as a family file, for `manni key set -c`, which writes\n * the family's key and so belongs to no one tool's section.\n *\n * The file is a family file when it is empty, carries a family key, or is\n * named as one (`manni.config.yaml`, `manni.config.yml`): its top-level keys\n * are then sections, whatever they are, and `value` is `null`. Anything else\n * is read whole as one tool's section (`wrapped: false`), which the key writer\n * refuses rather than turn into a family file under that tool's feet. Missing\n * is an error, as it is for `readConfigFile`. Keys are carried as\n * `findFamilyConfigFile` carries them.\n */\nexport function readFamilyConfigFile(\n explicitPath: string,\n cwd: string,\n toError: ToError,\n): Promise<ConfigFile> {\n return Promise.resolve().then(() =>\n readFamilyConfigFileSync(explicitPath, cwd, toError),\n );\n}\n\nfunction readFamilyConfigFileSync(\n explicitPath: string,\n cwd: string,\n toError: ToError,\n): ConfigFile {\n const path = resolve(cwd, explicitPath);\n const document = readDocument(path, explicitPath, toError);\n if (document === null) {\n throw toError(`Config file not found: \"${explicitPath}\".`);\n }\n const { doc } = document;\n const named = FAMILY_CONFIG_NAMES.includes(basename(path));\n const family =\n doc === null || named || FAMILY_KEYS.some((key) => Object.hasOwn(doc, key));\n return {\n path,\n dir: dirname(path),\n source: explicitPath,\n text: document.text,\n value: family ? null : doc,\n wrapped: family,\n kind: \"explicit\",\n collections: collectionsOf(document, explicitPath, toError),\n tools: toolsOf(document, explicitPath, toError),\n ...tolerantKeysOf(document),\n };\n}\n","/**\n * The project boundary: the nearest directory at or above `cwd` holding a\n * `.git` entry. A file or a directory, since a worktree's `.git` is a file.\n *\n * Two callers need it for opposite reasons and only one of them wants a\n * chain. Config discovery walks the chain and stops here. The SARIF reporter\n * needs the root itself, and needs \"there is no repository\" to be\n * distinguishable from \"the repository root is where you are standing\" — a\n * one-element chain conflates the two, and getting that wrong means emitting\n * paths GitHub silently drops.\n */\nimport { existsSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\n\nexport function findGitRoot(cwd: string): string | null {\n let dir = resolve(cwd);\n for (;;) {\n if (existsSync(join(dir, \".git\"))) return dir;\n const parent = dirname(dir);\n if (parent === dir) return null;\n dir = parent;\n }\n}\n\n/**\n * The directories a discovery walk may look in, nearest first.\n *\n * The walk stops at the project boundary `findGitRoot` reports, which is\n * included in the search. Only that one call touches the filesystem; the chain\n * itself is then assembled from path strings.\n *\n * With **no** boundary anywhere above cwd, only cwd is considered. A\n * project-scoped config has no meaning without a project, and walking on would\n * let a stray config file in a home or temp directory silently govern\n * unrelated runs — including this repo's own tests, which work in OS temp\n * directories under the user's home.\n */\nexport function searchPath(cwd: string): string[] {\n const start = resolve(cwd);\n const root = findGitRoot(start);\n if (root === null) return [start];\n const chain: string[] = [];\n let dir = start;\n for (;;) {\n chain.push(dir);\n if (dir === root) return chain;\n const parent = dirname(dir);\n // `root` is an ancestor of `start` by construction, so this is unreachable\n // — but a filesystem race (the boundary removed mid-walk) must not loop.\n if (parent === dir) return chain;\n dir = parent;\n }\n}\n"],"mappings":"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","names":["picomatch","posix","isMember","posix","picomatch","isAbsolute","resolve","isMapping","rejectUnknownKeys","readFileSync","dirname","join","relative","resolve","resolve","readFileSync","relative","resolve","join","dirname"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/family/cli.ts","../src/family/core/envelope.ts","../src/family/core/in-play.ts","../src/family/commands/check.ts","../src/family/core/changed.ts","../src/family/core/said-once.ts","../src/family/commands/status.ts"],"sourcesContent":["/**\n * The two family verbs, `manni check` and `manni status`, mounted on the\n * umbrella with `addCommand`. They are the only verbs it carries: each\n * orchestrates other domains' command cores and owns no checks of its own.\n *\n * Run by hand or in CI they follow the family contract: 0 clean, 1 errors, 2\n * operational, the report on stdout and notices on stderr. Under a Claude\n * Code hook envelope on stdin they speak the hook protocol instead, which\n * changes where output goes and what the exit code means, never what is\n * checked beyond the scope.\n */\nimport { resolve } from \"node:path\";\nimport { Command, Option } from \"commander\";\nimport { shouldColor } from \"../shared/color.js\";\nimport { errorMessage } from \"../shared/errors.js\";\nimport { programName } from \"../shared/program-name.js\";\nimport { fail } from \"../shared/run.js\";\nimport { notice } from \"../shared/warn.js\";\nimport { readEnvelope, type Envelope } from \"./core/envelope.js\";\nimport { FamilyError, labelFrom } from \"./core/in-play.js\";\nimport {\n CHECK_FORMATS,\n EDIT_TOOLS,\n exitCodeFor,\n hookFailure,\n hookReply,\n render,\n runFamilyCheck,\n runTurnCheck,\n turnReply,\n type CheckFormat,\n type FamilyCheckRun,\n type HookReply,\n type Scope,\n} from \"./commands/check.js\";\nimport {\n STATUS_FORMATS,\n agentLines,\n exportGeneratedBy,\n renderStatus,\n runStatus,\n type StatusFormat,\n} from \"./commands/status.js\";\n\ninterface CheckCliOptions {\n config?: string;\n format: CheckFormat;\n /** `--no-color`: `false` when given. */\n color: boolean;\n}\n\ninterface StatusCliOptions {\n config?: string;\n format: StatusFormat;\n}\n\nfunction send(reply: HookReply): void {\n if (reply.stdout !== undefined) process.stdout.write(reply.stdout);\n if (reply.stderr !== undefined) process.stderr.write(reply.stderr);\n process.exitCode = reply.exitCode;\n}\n\n/**\n * The file checks a hook asks for, or `undefined` when this event runs none.\n * A SubagentStop runs none: its subagent's turn is judged alone.\n */\nexport function hookScope(envelope: Envelope, cwd: string): { scope: Scope; file?: string } | undefined {\n if (envelope.event === \"Stop\") return { scope: { kind: \"changed\" } };\n if (envelope.event !== \"PostToolUse\") return undefined;\n if (envelope.toolName === undefined || !EDIT_TOOLS.includes(envelope.toolName)) return undefined;\n if (envelope.filePath === undefined) return undefined;\n const file = labelFrom(cwd, resolve(cwd, envelope.filePath));\n return { scope: { kind: \"paths\", paths: [file] }, file };\n}\n\n/** The events that end a turn, which tracevals judges (proposal 0079). */\nconst TURN_EVENTS: readonly string[] = [\"Stop\", \"SubagentStop\"];\n\nasync function checkUnderHook(paths: string[], options: CheckCliOptions, envelope: Envelope): Promise<void> {\n const cwd = resolve(envelope.cwd ?? process.cwd());\n // Positional paths win over the envelope's own scope.\n const asked: { scope: Scope; file?: string } | undefined =\n paths.length > 0 ? { scope: { kind: \"paths\", paths }, file: paths.join(\", \") } : hookScope(envelope, cwd);\n const turnEvent = TURN_EVENTS.includes(envelope.event);\n if (asked === undefined && !turnEvent) return;\n let run: FamilyCheckRun | undefined;\n if (asked !== undefined) {\n try {\n run = await runFamilyCheck({\n cwd,\n scope: asked.scope,\n allowMissing: true,\n ...(options.config === undefined ? {} : { configPath: options.config }),\n // stdout and stderr are the hook's channels; a notice is not for the agent.\n onNotice: () => undefined,\n });\n } catch (err) {\n // Nothing set up for the file checks is not the end of a turn's judgement.\n if (!(err instanceof FamilyError && err.quiet) && !turnEvent) {\n send(hookFailure(errorMessage(err), envelope, asked.file));\n return;\n }\n }\n }\n if (!turnEvent) {\n if (run !== undefined) send(hookReply(run, envelope));\n return;\n }\n send(turnReply(run, await runTurnCheck(envelope, cwd), envelope));\n}\n\nexport function buildCheck(): Command {\n return new Command(\"check\")\n .description(\"Run every check this repository has set up, and nothing else\")\n .argument(\"[paths...]\", \"files, directories, or globs; the per-file checks run on the collection members among them\")\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .addOption(\n new Option(\"-f, --format <format>\", \"output (not read under a hook)\")\n .choices(CHECK_FORMATS)\n .default(\"pretty\"),\n )\n .option(\"--no-color\", \"disable colored output\")\n .showHelpAfterError(\"(add --help for usage)\")\n .exitOverride()\n .addHelpText(\n \"after\",\n [\n \"\",\n \"Examples:\",\n \" manni check # every in-play check, the CI gate\",\n \" manni check docs/limits.md # per-file checks on one page\",\n \" manni check -f github # in a GitHub workflow\",\n \" manni check docs/ -f json # scripting form\",\n ].join(\"\\n\"),\n )\n .action(async (paths: string[], options: CheckCliOptions) => {\n const envelope = await readEnvelope();\n if (envelope !== undefined) {\n await checkUnderHook(paths, options, envelope);\n return;\n }\n try {\n const run = await runFamilyCheck({\n scope: paths.length > 0 ? { kind: \"paths\", paths } : { kind: \"all\" },\n ...(options.config === undefined ? {} : { configPath: options.config }),\n onNotice: notice,\n });\n for (const check of run.checks) {\n if (check.status === \"error\") {\n process.stderr.write(`${programName()} ${check.command} could not run: ${check.message}\\n`);\n }\n }\n const color = shouldColor({ noColor: !options.color, isTTY: process.stdout.isTTY });\n const text = render(run, options.format, color);\n if (text.length > 0) process.stdout.write(`${text}\\n`);\n process.exitCode = exitCodeFor(run);\n } catch (err) {\n fail(err);\n }\n });\n}\n\nexport function buildStatus(): Command {\n return new Command(\"status\")\n .description(\"Say what is set up here, and so what manni check runs\")\n .option(\"-c, --config <path>\", \"path to a manni config file\")\n .addOption(\n new Option(\"-f, --format <format>\", \"output\").choices(STATUS_FORMATS).default(\"pretty\"),\n )\n .showHelpAfterError(\"(add --help for usage)\")\n .exitOverride()\n .action(async (options: StatusCliOptions) => {\n const envelope = await readEnvelope();\n const configOption = options.config === undefined ? {} : { configPath: options.config };\n if (envelope?.event === \"SessionStart\") {\n try {\n const report = await runStatus({ cwd: resolve(envelope.cwd ?? process.cwd()), ...configOption });\n // The agent lines promise checks, so they need a domain in play to be true.\n const lines = report.domains.some((d) => d.status === \"in-play\") ? `\\n\\n${agentLines(report)}` : \"\";\n process.stdout.write(`${renderStatus(report, \"pretty\")}${lines}\\n`);\n exportGeneratedBy(envelope);\n } catch {\n // No config, or one that cannot be read: the session starts without a word.\n }\n return;\n }\n try {\n const report = await runStatus(configOption);\n process.stdout.write(`${renderStatus(report, options.format)}\\n`);\n } catch (err) {\n fail(err);\n }\n });\n}\n","/**\n * The Claude Code hook envelope, detected rather than switched.\n *\n * A hook command gets one JSON object on stdin, and Claude Code closes the\n * stream after it. When stdin is not a terminal and parses as an object with a\n * string `hook_event_name`, `manni check` and `manni status` speak the hook\n * protocol. Anything else is a run by hand, and stdin is left unread beyond\n * that one look. The look never hangs: `readStdin` gives up on a stream that\n * stays silent, which is what an inherited pipe nobody writes to looks like.\n */\nimport { readStdin } from \"../../tracevals/capture/hook.js\";\n\nexport interface Envelope {\n /** `hook_event_name`: `PostToolUse`, `Stop`, `SessionStart`, … */\n event: string;\n /** The directory the hook fired in; relative paths resolve from it. */\n cwd?: string;\n /** `tool_name`, on a tool event. */\n toolName?: string;\n /** `tool_input.file_path`, or `tool_input.notebook_path` for a notebook. */\n filePath?: string;\n /** `stop_hook_active`: this stop already follows one repair pass. */\n stopHookActive: boolean;\n /** `model`, on `SessionStart`: a string, or an object carrying `id`. */\n model?: string;\n /** `session_id`. */\n sessionId?: string;\n /** `transcript_path`: the session's own transcript. */\n transcriptPath?: string;\n /** `agent_transcript_path`, on `SubagentStop`: the subagent's own transcript. */\n agentTranscriptPath?: string;\n /** `agent_id`, on `SubagentStop`. */\n agentId?: string;\n /** `agent_type`, on `SubagentStop`. */\n agentType?: string;\n /** `last_assistant_message`, on `Stop` and `SubagentStop`. */\n lastAssistantMessage?: string;\n}\n\nfunction str(value: unknown): string | undefined {\n return typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\n/** The envelope in `text`, or `undefined` when `text` is not one. */\nexport function parseEnvelope(text: string): Envelope | undefined {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text);\n } catch {\n return undefined;\n }\n const doc = record(parsed);\n const event = str(doc?.hook_event_name);\n if (doc === undefined || event === undefined) return undefined;\n const input = record(doc.tool_input);\n const filePath = str(input?.file_path) ?? str(input?.notebook_path);\n const cwd = str(doc.cwd);\n const toolName = str(doc.tool_name);\n const model = str(doc.model) ?? str(record(doc.model)?.id);\n const strings = {\n sessionId: str(doc.session_id),\n transcriptPath: str(doc.transcript_path),\n agentTranscriptPath: str(doc.agent_transcript_path),\n agentId: str(doc.agent_id),\n agentType: str(doc.agent_type),\n lastAssistantMessage: str(doc.last_assistant_message),\n };\n const given = Object.fromEntries(Object.entries(strings).filter(([, v]) => v !== undefined)) as Partial<\n Record<keyof typeof strings, string>\n >;\n return {\n event,\n stopHookActive: doc.stop_hook_active === true,\n ...(cwd === undefined ? {} : { cwd }),\n ...(toolName === undefined ? {} : { toolName }),\n ...(filePath === undefined ? {} : { filePath }),\n ...(model === undefined ? {} : { model }),\n ...given,\n };\n}\n\n/** The envelope on stdin, or `undefined` for a run by hand. */\nexport async function readEnvelope(\n stream: NodeJS.ReadStream = process.stdin,\n): Promise<Envelope | undefined> {\n if (stream.isTTY) return undefined;\n try {\n return parseEnvelope(await readStdin(stream));\n } catch {\n // Too large to be an envelope: a run by hand with something piped in.\n return undefined;\n }\n}\n","/**\n * What is set up, and so what `manni check` runs.\n *\n * There are no keys of the family's own. A domain is in play when its own\n * section of `manni.config.yaml` exists, or when the content carries its\n * declarations. Nothing manni would apply by default counts as set up:\n *\n * | Domain | In play when |\n * |---|---|\n * | meta | a file's schema set is more than the built-in defaults: `meta:` covers it, or it names its own `$schema` |\n * | cite | a page carries citations |\n * | lint | `lint:` exists |\n * | docevals | a page resolves evals, from `docevals:` or its own declarations |\n * | term | the collections hold a term |\n * | graph | `graph:` exists |\n * | tracevals | `tracevals.runtime` exists; it judges the turn a Stop or SubagentStop hook ends |\n * | a11y | never run by `check`: it needs a running site |\n *\n * Only members of a declared collection are file-checked. tracevals judges a\n * turn, not files, so it needs no collection.\n */\nimport { relative, resolve, sep } from \"node:path\";\nimport { parse as parseYaml } from \"yaml\";\nimport type { CollectionConfig } from \"../../shared/collections.js\";\nimport {\n findFamilyConfigFile,\n readFamilyConfigFile,\n type ConfigFile,\n} from \"../../shared/config-file.js\";\nimport { ToolError } from \"../../shared/errors.js\";\nimport { memberOf, retainMembers } from \"../../meta/core/collections.js\";\nimport { resolveTargetSet } from \"../../meta/internal.js\";\n\n/** An operational error of `manni check` or `manni status`: exit 2. */\nexport class FamilyError extends ToolError {\n constructor(\n message: string,\n /** Set for the two conditions a hook answers with silence. */\n readonly quiet = false,\n ) {\n super(message);\n this.name = \"FamilyError\";\n }\n}\n\nexport function noConfigError(cwd: string): FamilyError {\n return new FamilyError(\n `No manni.config.yaml found from ${cwd} up to the repository root. manni check runs the checks it sets up.`,\n true,\n );\n}\n\nexport function nothingSetUpError(): FamilyError {\n return new FamilyError(\n \"Nothing is set up to check in manni.config.yaml. manni status says what each domain needs.\",\n true,\n );\n}\n\n/** The domains `check` can run, in the order it runs and reports them. */\nexport const DOMAINS = [\"meta\", \"cite\", \"lint\", \"docevals\", \"term\", \"graph\"] as const;\nexport type Domain = (typeof DOMAINS)[number];\n\n/** Each domain's check, as `check` names it. */\nexport const COMMANDS: Readonly<Record<Domain, string>> = {\n meta: \"meta validate\",\n cite: \"cite check\",\n lint: \"lint check\",\n docevals: \"docevals run\",\n term: \"term check\",\n graph: \"graph check\",\n};\n\n/** Why a domain is not in play, as both `check` and `status` say it. */\nexport const NOT_SET_UP: Readonly<Record<Domain, string>> = {\n meta: \"no meta: section\",\n cite: \"no page carries citations\",\n lint: \"no lint: section\",\n docevals: \"no page resolves any evals\",\n term: \"no terms in any collection\",\n graph: \"no graph: section\",\n};\n\n/** Why `meta` skips files when `meta:` exists but covers none of them. */\nexport const META_DEFAULTS_ONLY = \"only the built-in default schemas cover these files\";\n\n/**\n * The domains `check` does not run here, and what to run instead. tracevals\n * leaves this list when `tracevals.runtime` exists (`Family.runtime`).\n */\nexport const NOT_CHECKED: ReadonlyArray<readonly [string, string]> = [\n [\"a11y\", \"run manni a11y check against a running site\"],\n [\"tracevals\", \"run manni tracevals run over sessions\"],\n];\n\n/** `1 page`, `2 pages`. */\nexport function plural(n: number, one: string, many = `${one}s`): string {\n return `${String(n)} ${n === 1 ? one : many}`;\n}\n\nexport interface Family {\n file: ConfigFile;\n /**\n * The config each domain core is handed, so every one reads this file\n * rather than discovering its own: as typed, or as discovery found it,\n * relative to `cwd`.\n */\n configPath: string;\n /** The top-level keys of the file: `meta`, `lint`, `graph`, … */\n sections: ReadonlySet<string>;\n /** `tracevals.runtime` exists: tracevals judges each turn under the hooks. */\n runtime: boolean;\n collections: readonly CollectionConfig[];\n}\n\nfunction toError(message: string): FamilyError {\n return new FamilyError(message);\n}\n\nexport async function loadFamily(cwd: string, configPath?: string): Promise<Family> {\n const file =\n configPath === undefined\n ? await findFamilyConfigFile(cwd, toError)\n : await readFamilyConfigFile(configPath, cwd, toError);\n if (file === null) throw noConfigError(cwd);\n // Already parsed once by the loader, which would have thrown on bad YAML.\n const doc = parseYaml(file.text) as unknown;\n const top = record(doc);\n const sections = new Set(top === undefined ? [] : Object.keys(top));\n const tracevals = record(top?.tracevals);\n // The old `conformance` key counts too. tracevals' loader refuses it and\n // names `runtime`, and only a tracevals in play loads that config, so a\n // config not yet migrated reaches `status` as an error, not as a silent skip.\n const runtime = tracevals?.runtime !== undefined || tracevals?.conformance !== undefined;\n return { file, configPath: configPath ?? file.source, sections, runtime, collections: file.collections };\n}\n\nfunction record(value: unknown): Record<string, unknown> | undefined {\n return value !== null && typeof value === \"object\" && !Array.isArray(value)\n ? (value as Record<string, unknown>)\n : undefined;\n}\n\n/** A path as a label relative to `cwd`, posix, the way the domains print one. */\nexport function labelFrom(cwd: string, path: string): string {\n return relative(cwd, path).split(sep).join(\"/\");\n}\n\n/** The collections a file at `label` (relative to `cwd`) belongs to. */\nexport function collectionsOf(family: Family, cwd: string, label: string): string[] {\n return memberOf(family.collections, family.file.dir, cwd, label);\n}\n\n/** Every member of every collection, labelled from `cwd`. */\nexport async function listMembers(family: Family, cwd: string): Promise<string[]> {\n const dir = family.file.dir;\n const { files } = await resolveTargetSet({\n inputs: family.collections.flatMap((c) => c.paths),\n cwd: dir,\n allowEmpty: true,\n });\n return retainMembers(files, (label) => memberOf(family.collections, dir, dir, label)).map(\n (label) => labelFrom(cwd, resolve(dir, label)),\n );\n}\n","/**\n * `manni check`: every check the repository has set up, and nothing else.\n *\n * It owns no checks. Each one is a domain's own command core, run in process\n * with the family config handed to it, and each report is that domain's own\n * reporter's output. What this adds is the choice of what runs (`in-play.ts`),\n * the scope, and one verdict over all of it.\n *\n * Scope:\n *\n * - `all`: every in-play check over every collection, per-file and set-wide.\n * Each domain runs bare, exactly as its own CI step would.\n * - `paths`: the per-file checks on the collection members among the paths.\n * - `changed`: the per-file checks on the git working tree's changes, plus\n * `cite` set-wide. `term` runs set-wide too when a collection document\n * changed or was removed. `graph` never runs here; only `all` checks it.\n * A clean tree runs nothing.\n *\n * `cite` is per-file on paths and set-wide otherwise: a source edit can drift\n * any page's citation, so after a session the whole set is what is checked.\n */\nimport { basename, extname, resolve } from \"node:path\";\nimport pkg from \"../../../package.json\" with { type: \"json\" };\nimport { ToolError, errorMessage } from \"../../shared/errors.js\";\nimport { warn } from \"../../shared/warn.js\";\nimport { resolveTargetSet } from \"../../meta/internal.js\";\nimport { supportedExtensions } from \"../../meta/extractors/index.js\";\nimport type { TurnCheckInput, TurnCheckResult } from \"../../tracevals/commands/check.js\";\nimport { changedFiles } from \"../core/changed.js\";\nimport { sayOnce } from \"../core/said-once.js\";\nimport type { Envelope } from \"../core/envelope.js\";\nimport {\n COMMANDS,\n DOMAINS,\n META_DEFAULTS_ONLY,\n NOT_SET_UP,\n collectionsOf,\n labelFrom,\n listMembers,\n loadFamily,\n nothingSetUpError,\n plural,\n type Domain,\n type Family,\n} from \"../core/in-play.js\";\nimport { withSharedWalks } from \"../../meta/core/load-files.js\";\n\nexport const CHECK_FORMATS = [\"pretty\", \"json\", \"github\"] as const;\nexport type CheckFormat = (typeof CHECK_FORMATS)[number];\n\nexport type Scope =\n | { kind: \"all\" }\n | { kind: \"paths\"; paths: string[] }\n | { kind: \"changed\" };\n\nexport interface FamilyCheckOptions {\n /** Where paths resolve and the domains run. Default `process.cwd()`. */\n cwd?: string;\n /** `-c, --config`. */\n configPath?: string;\n scope: Scope;\n /**\n * Leave out a named path that does not exist, rather than failing on it. A\n * hook names a file the edit may have just removed.\n */\n allowMissing?: boolean;\n /** Diagnostics: the outside-every-collection notice, and the domains' own. */\n onNotice?: (message: string) => void;\n}\n\n/** A check that ran. `render` is the domain's own reporter. */\nexport interface RanCheck {\n command: string;\n status: \"pass\" | \"fail\";\n render: (format: CheckFormat, color: boolean) => string;\n}\n\n/** A check that did not run: not in play, or it could not. */\nexport interface NotRunCheck {\n command: string;\n status: \"skipped\" | \"error\";\n message: string;\n}\n\nexport type CheckOutcome = RanCheck | NotRunCheck;\n\nexport interface FamilyCheckRun {\n status: \"pass\" | \"fail\";\n /** The collection members the per-file checks covered, labelled from `cwd`. */\n files: string[];\n checks: CheckOutcome[];\n}\n\ntype Outcome =\n | { skipped: string }\n | { failed: boolean; render: (format: CheckFormat, color: boolean) => string };\n\ninterface Context {\n family: Family;\n cwd: string;\n /** The per-file inputs, or `[]` for a bare run over the collections. */\n inputs: string[];\n onNotice: (message: string) => void;\n}\n\n/**\n * Each domain's command core and reporter are imported where it runs: a hook\n * checks one page with four domains, and the other two (the RDF stack among\n * them) are worth not loading.\n */\nasync function runDomain(domain: Domain, ctx: Context): Promise<Outcome> {\n const { family, cwd, inputs, onNotice } = ctx;\n const configPath = family.configPath;\n switch (domain) {\n case \"meta\": {\n const [{ runValidate }, { render: renderMeta }] = await Promise.all([\n import(\"../../meta/commands/validate.js\"),\n import(\"../../meta/reporters/index.js\"),\n ]);\n const run = await runValidate({ inputs, configPath, cwd, skipDefaultOnly: true, onNotice });\n if (run.results.length === 0) {\n return { skipped: family.sections.has(\"meta\") ? META_DEFAULTS_ONLY : NOT_SET_UP.meta };\n }\n return {\n failed: run.summary.failed > 0,\n render: (format, color) =>\n renderMeta(format, run.results, run.summary, { color, quiet: true, frame: run.frame, onNotice }),\n };\n }\n case \"cite\": {\n const [{ runCheck: runCite }, { renderCheckPretty: citePretty }, { renderCheckJson: citeJson }, { renderCheckGithub: citeGithub }] =\n await Promise.all([\n import(\"../../cite/commands/check.js\"),\n import(\"../../cite/reporters/pretty.js\"),\n import(\"../../cite/reporters/json.js\"),\n import(\"../../cite/reporters/github.js\"),\n ]);\n const run = await runCite({ inputs, configPath, cwd, onNotice });\n if (!run.pages.some((p) => p.citations.length > 0 || p.findings.length > 0)) {\n return { skipped: NOT_SET_UP.cite };\n }\n return {\n failed: run.summary.failed > 0,\n render: (format, color) =>\n format === \"json\"\n ? citeJson(run)\n : format === \"github\"\n ? citeGithub(run)\n : citePretty(run, { color, quiet: true }),\n };\n }\n case \"lint\": {\n if (!family.sections.has(\"lint\")) return { skipped: NOT_SET_UP.lint };\n const [{ runLint }, { render: renderLint }] = await Promise.all([\n import(\"../../lint/commands/lint.js\"),\n import(\"../../lint/reporters/index.js\"),\n ]);\n const run = await runLint({ inputs, configPath, cwd, onNotice });\n return {\n failed: run.summary.failed > 0,\n render: (format, color) => renderLint(run, format, { color }),\n };\n }\n case \"docevals\": {\n const [{ runRun: runDocevals }, { render: renderDocevals }, { DocevalsError }] = await Promise.all([\n import(\"../../docevals/commands/run.js\"),\n import(\"../../docevals/reporters/index.js\"),\n import(\"../../docevals/types.js\"),\n ]);\n let report;\n try {\n report = await runDocevals(inputs, {\n config: configPath,\n cwd,\n deterministicOnly: true,\n generate: false,\n execution: false,\n toolVersion: pkg.version,\n });\n } catch (err) {\n if (err instanceof DocevalsError && err.code === \"nothing-resolved\") {\n return { skipped: NOT_SET_UP.docevals };\n }\n throw err;\n }\n return {\n failed: report.exitCode !== 0,\n render: (format, color) => renderDocevals(report, format, { color }),\n };\n }\n case \"term\": {\n const [{ runCheck: runTerm }, { renderFindingsPretty: termPretty }, { renderFindingsJson: termJson }, { renderFindingsGithub: termGithub }] =\n await Promise.all([\n import(\"../../term/commands/check.js\"),\n import(\"../../term/reporters/pretty.js\"),\n import(\"../../term/reporters/json.js\"),\n import(\"../../term/reporters/github.js\"),\n ]);\n const report = await runTerm({ inputs, configPath, cwd, allowEmpty: true, onNotice });\n if (report.terms === 0) return { skipped: NOT_SET_UP.term };\n return {\n failed: report.summary.failed > 0,\n render: (format, color) =>\n format === \"json\"\n ? termJson(report)\n : format === \"github\"\n ? termGithub(report)\n : termPretty(report, { color, references: true }),\n };\n }\n case \"graph\": {\n if (!family.sections.has(\"graph\")) return { skipped: NOT_SET_UP.graph };\n const [{ buildGraph }, { runCheck: runGraph, renderCheck: renderGraph }] = await Promise.all([\n import(\"../../graph/commands/build.js\"),\n import(\"../../graph/commands/check.js\"),\n ]);\n const built = await buildGraph({ config: configPath, cwd });\n for (const warning of built.warnings) onNotice(warning);\n const report = await runGraph({ config: configPath, cwd, turtle: built.turtle });\n return {\n failed: report.exitCode !== 0,\n render: (format) => renderGraph(report, format),\n };\n }\n }\n}\n\nasync function outcome(domain: Domain, ctx: Context): Promise<CheckOutcome> {\n const command = COMMANDS[domain];\n try {\n const result = await runDomain(domain, ctx);\n if (\"skipped\" in result) return { command, status: \"skipped\", message: result.skipped };\n return { command, status: result.failed ? \"fail\" : \"pass\", render: result.render };\n } catch (err) {\n return { command, status: \"error\", message: errorMessage(err) };\n }\n}\n\n/** A hook or a git status names files by any extension; a walk keeps the documents. */\nfunction isDocument(label: string): boolean {\n return supportedExtensions().includes(extname(label).toLowerCase());\n}\n\n/** Every domain walks the same collections, so the run shares one walk per target set. */\nexport function runFamilyCheck(opts: FamilyCheckOptions): Promise<FamilyCheckRun> {\n return withSharedWalks(() => checkUnshared(opts));\n}\n\nasync function checkUnshared(opts: FamilyCheckOptions): Promise<FamilyCheckRun> {\n const cwd = resolve(opts.cwd ?? process.cwd());\n const onNotice = opts.onNotice ?? ((): void => undefined);\n const family = await loadFamily(cwd, opts.configPath);\n if (family.collections.length === 0) throw nothingSetUpError();\n const isMember = (label: string): boolean => collectionsOf(family, cwd, label).length > 0;\n\n let files: string[];\n let domains: Domain[];\n let inputs: string[];\n switch (opts.scope.kind) {\n case \"all\":\n files = await listMembers(family, cwd);\n inputs = [];\n domains = [...DOMAINS];\n break;\n case \"paths\": {\n const { files: named } = await resolveTargetSet({\n inputs: opts.scope.paths,\n cwd,\n ...(opts.allowMissing === true ? { allowEmpty: true } : {}),\n });\n const outside = named.filter((label) => !isMember(label));\n if (outside.length > 0) {\n onNotice(`Skipped ${plural(outside.length, \"file\")} outside every collection: ${outside.join(\", \")}`);\n }\n // A collection globbed wide holds assets too; only documents are checked.\n files = named.filter((label) => isMember(label) && isDocument(label));\n inputs = files;\n domains = files.length > 0 ? [\"meta\", \"cite\", \"lint\", \"docevals\"] : [];\n break;\n }\n case \"changed\": {\n const changed = await changedFiles(cwd);\n if (!changed.dirty) return { status: \"pass\", files: [], checks: [] };\n const memberDocuments = (paths: string[]): string[] =>\n paths.map((path) => labelFrom(cwd, path)).filter((l) => isDocument(l) && isMember(l));\n files = memberDocuments(changed.files);\n inputs = files;\n // term reads only collection documents, so a session that changed or\n // removed none of them leaves the glossary as it was. graph never runs\n // here: it is the slowest set-wide check, and its findings span pages\n // rather than the one an agent just wrote, so a bare run (CI) owns it.\n const pageChanged = files.length > 0 || memberDocuments(changed.removed).length > 0;\n domains = [\n ...(files.length > 0 ? ([\"meta\", \"lint\", \"docevals\"] as const) : []),\n \"cite\",\n ...(pageChanged ? ([\"term\"] as const) : []),\n ];\n break;\n }\n }\n\n const checks: CheckOutcome[] = [];\n for (const domain of domains) {\n // The set-wide checks run bare, over every collection, whatever the scope.\n const setWide = domain === \"term\" || domain === \"graph\" || (domain === \"cite\" && opts.scope.kind !== \"paths\");\n checks.push(await outcome(domain, { family, cwd, inputs: setWide ? [] : inputs, onNotice }));\n }\n if (opts.scope.kind === \"all\" && checks.every((c) => c.status === \"skipped\")) {\n throw nothingSetUpError();\n }\n return { status: checks.some((c) => c.status === \"fail\") ? \"fail\" : \"pass\", files, checks };\n}\n\n/** The exit code a run by hand ends with: 2 when a check could not run. */\nexport function exitCodeFor(run: FamilyCheckRun): 0 | 1 | 2 {\n if (run.checks.some((c) => c.status === \"error\")) return 2;\n return run.status === \"fail\" ? 1 : 0;\n}\n\nfunction isRan(check: CheckOutcome): check is RanCheck {\n return check.status === \"pass\" || check.status === \"fail\";\n}\n\n/** The first line of a message, for a one-line context. */\nfunction firstLine(message: string): string {\n return message.split(\"\\n\", 1)[0] ?? \"\";\n}\n\n/** What an agent is handed when a hook blocks: the failing checks' reports, nothing else. */\nfunction renderFailures(run: FamilyCheckRun): string {\n return run.checks\n .filter((c): c is RanCheck => c.status === \"fail\")\n .map((c) => `${c.command}\\n${c.render(\"pretty\", false)}`)\n .join(\"\\n\\n\");\n}\n\nexport function renderPretty(run: FamilyCheckRun, color: boolean): string {\n const blocks: string[] = [];\n for (const check of run.checks) {\n if (isRan(check)) blocks.push(`${check.command}\\n${check.render(\"pretty\", color)}`);\n }\n const notRun = run.checks.filter((c): c is NotRunCheck => !isRan(c));\n if (notRun.length > 0) {\n const width = Math.max(...notRun.map((c) => c.command.length)) + 3;\n blocks.push(\n notRun\n .map((c) => `${c.status.padEnd(9)}${c.command.padEnd(width)}${firstLine(c.message)}`)\n .join(\"\\n\"),\n );\n }\n const count = (status: CheckOutcome[\"status\"]): number =>\n run.checks.filter((c) => c.status === status).length;\n const errors = count(\"error\");\n blocks.push(\n `${plural(run.checks.length, \"check\")} over ${plural(run.files.length, \"file\")}: ` +\n `${String(count(\"fail\"))} failed, ${String(count(\"skipped\"))} skipped` +\n (errors > 0 ? `, ${String(errors)} could not run` : \"\"),\n );\n return blocks.join(\"\\n\\n\");\n}\n\n/** A check's JSON entry: its own report, or why there is none. */\nfunction jsonEntry(c: CheckOutcome): object {\n if (!isRan(c)) return { command: c.command, status: c.status, message: c.message };\n try {\n return { command: c.command, status: c.status, report: JSON.parse(c.render(\"json\", false)) as unknown };\n } catch {\n // One reporter's bad output must not take the other checks' reports with it.\n // `error` on purpose, whatever the run's own status: with no report to\n // embed, a `pass` or `fail` here would be a verdict nobody can inspect.\n // The reference documents `error` for this case too.\n return { command: c.command, status: \"error\", message: `${c.command} -f json printed output that is not JSON` };\n }\n}\n\nexport function renderJson(run: FamilyCheckRun): string {\n return JSON.stringify(\n {\n status: run.status,\n files: run.files,\n checks: run.checks.map(jsonEntry),\n },\n null,\n 2,\n );\n}\n\nexport function renderGithub(run: FamilyCheckRun): string {\n return run.checks\n .filter(isRan)\n .map((c) => c.render(\"github\", false))\n .filter((text) => text.length > 0)\n .join(\"\\n\");\n}\n\nexport function render(run: FamilyCheckRun, format: CheckFormat, color: boolean): string {\n return format === \"json\" ? renderJson(run) : format === \"github\" ? renderGithub(run) : renderPretty(run, color);\n}\n\n/** What a hook command ends with: its exit code, and what it prints where. */\nexport interface HookReply {\n exitCode: 0 | 2;\n stdout?: string;\n stderr?: string;\n}\n\n/** The PostToolUse tools whose edit `check` answers. */\nexport const EDIT_TOOLS: readonly string[] = [\"Edit\", \"Write\", \"MultiEdit\", \"NotebookEdit\"];\n\n/**\n * The hook protocol's answer to a run. Never exit 2 for a check that could\n * not run: 2 means \"block\" to Claude Code, and an operational error is not\n * the agent's to fix.\n */\nexport function hookReply(run: FamilyCheckRun, envelope: Envelope): HookReply {\n const failed = run.status === \"fail\";\n if (envelope.event === \"PostToolUse\") {\n const files = run.files.join(\", \");\n if (failed) {\n return {\n exitCode: 2,\n stderr: `manni found errors in ${files}. Fix them before you continue.\\n\\n${renderFailures(run)}\\n`,\n };\n }\n const errors = run.checks.filter((c): c is NotRunCheck => c.status === \"error\");\n if (errors.length === 0) return { exitCode: 0 };\n const additionalContext = errors\n .map((c) => `manni ${c.command} could not check ${files}: ${firstLine(c.message)}`)\n .join(\"\\n\");\n return {\n exitCode: 0,\n stdout: `${JSON.stringify({ hookSpecificOutput: { hookEventName: \"PostToolUse\", additionalContext } })}\\n`,\n };\n }\n if (envelope.event === \"Stop\") return turnReply(run, undefined, envelope);\n return { exitCode: 0 };\n}\n\n/** What tracevals found in the turn a Stop or SubagentStop ended, for the reply. */\nexport interface TurnVerdict {\n /** Rules broken with a confident verdict: how many, the report, the trace judged. */\n broken?: { rules: number; report: string; trace: string };\n /** A skip not yet said this session. */\n skipMessage?: string;\n}\n\n/**\n * The reply to a Stop or a SubagentStop: 0078's file checks first, then the\n * turn. One block carries both reasons; after the repair pass, one message\n * carries both sentences. Always exit 0, as 0078's Stop is.\n */\nexport function turnReply(\n run: FamilyCheckRun | undefined,\n turn: TurnVerdict | undefined,\n envelope: Envelope,\n): HookReply {\n const reasons: string[] = [];\n const messages: string[] = [];\n if (run?.status === \"fail\") {\n if (envelope.stopHookActive) {\n messages.push(\"manni still reports errors after one repair pass. Run manni check to see them.\");\n } else {\n reasons.push(`manni found errors in the files you changed. Fix them, then finish.\\n\\n${renderFailures(run)}`);\n }\n }\n if (turn?.broken !== undefined) {\n const { rules, report, trace } = turn.broken;\n if (envelope.stopHookActive) {\n messages.push(\n `tracevals still finds broken rules after one repair pass. Run manni tracevals check ${trace} to see them.`,\n );\n } else {\n reasons.push(\n `This turn broke ${plural(rules, \"rule\")} from the files and requests that governed it. ` +\n `Fix the work, or say why the rule does not apply here, then finish.\\n\\n${report}`,\n );\n }\n }\n if (turn?.skipMessage !== undefined) messages.push(turn.skipMessage);\n if (reasons.length === 0 && messages.length === 0) return { exitCode: 0 };\n const reply = {\n ...(reasons.length > 0 ? { decision: \"block\", reason: reasons.join(\"\\n\\n\") } : {}),\n ...(messages.length > 0 ? { systemMessage: messages.join(\" \") } : {}),\n };\n return { exitCode: 0, stdout: `${JSON.stringify(reply)}\\n` };\n}\n\n/** Test seams `checkTurn` takes; production builds each from config. */\nexport type TurnSeams = Partial<Pick<TurnCheckInput, \"judge\" | \"extractor\" | \"localModels\" | \"env\">>;\n\n/**\n * Judge the turn a Stop or SubagentStop ended, with every gate of proposal\n * 0079. Silent (`undefined`) when tracevals is not in play, the turn is clean\n * or only needs review, a skip was already said this session, or the run\n * could not happen: an operational failure is not the agent's to fix.\n */\nexport async function runTurnCheck(\n envelope: Envelope,\n cwd: string,\n seams: TurnSeams = {},\n): Promise<TurnVerdict | undefined> {\n const subagent = envelope.event === \"SubagentStop\";\n const judged = subagent ? envelope.agentTranscriptPath : envelope.transcriptPath;\n if (judged === undefined) return undefined;\n const trace = resolve(cwd, judged);\n const sessionId = envelope.sessionId ?? basename(trace, \".jsonl\");\n let result: TurnCheckResult;\n let renderTurn: (typeof import(\"../../tracevals/reporters/runtime.js\"))[\"renderCheck\"];\n try {\n // Loaded here, as every domain is, so a run that never judges a turn never\n // loads tracevals.\n const [{ checkTurn }, reporters] = await Promise.all([\n import(\"../../tracevals/commands/check.js\"),\n import(\"../../tracevals/reporters/runtime.js\"),\n ]);\n renderTurn = reporters.renderCheck;\n result = await checkTurn({\n transcriptPath: resolve(cwd, envelope.transcriptPath ?? judged),\n ...(subagent ? { agentTranscriptPath: trace } : {}),\n ...(subagent && envelope.agentId !== undefined ? { agentId: envelope.agentId } : {}),\n ...(subagent && envelope.agentType !== undefined ? { agentType: envelope.agentType } : {}),\n ...(envelope.lastAssistantMessage !== undefined\n ? { lastAssistantMessage: envelope.lastAssistantMessage }\n : {}),\n sessionId,\n cwd,\n inLoop: true,\n ...seams,\n });\n } catch (err) {\n // An operational failure is not the agent's to fix, so it stays silent, as\n // 0078's Stop failures do. Anything else is a bug: say so on stderr, which\n // a hook that exits 0 sends to the debug log, and still never block.\n if (!(err instanceof ToolError)) warn(`the turn check failed unexpectedly: ${errorMessage(err)}`);\n return undefined;\n }\n const { skipped } = result;\n if (skipped?.message !== undefined) {\n return sayOnce(cwd, sessionId, skipped.gate) ? { skipMessage: skipped.message } : undefined;\n }\n if (result.exitCode !== 1 || result.report === undefined) return undefined;\n return {\n broken: {\n rules: result.report.summary.fail,\n report: renderTurn(result.report, { color: false }),\n trace: judged,\n },\n };\n}\n\n/** The reply when the run itself could not happen, under a hook. */\nexport function hookFailure(message: string, envelope: Envelope, file: string | undefined): HookReply {\n if (envelope.event !== \"PostToolUse\" || file === undefined) return { exitCode: 0 };\n const additionalContext = `manni check could not check ${file}: ${firstLine(message)}`;\n return {\n exitCode: 0,\n stdout: `${JSON.stringify({ hookSpecificOutput: { hookEventName: \"PostToolUse\", additionalContext } })}\\n`,\n };\n}\n","/**\n * The files a session changed: the git working tree against `HEAD`.\n *\n * Modified, added, renamed (by the new name) and untracked files, staged or\n * not. A deleted file, or a renamed one's old name, is named apart, since\n * there is nothing left to check. Paths come back absolute, resolved from\n * `cwd`: porcelain status names them from the repository root whatever\n * directory git ran in.\n */\nimport { execFile } from \"node:child_process\";\nimport { posix, resolve } from \"node:path\";\nimport { promisify } from \"node:util\";\n\nconst run = promisify(execFile);\n\nasync function git(args: string[], cwd: string): Promise<string> {\n // shell:false: nothing here is ever parsed as shell syntax.\n const { stdout } = await run(\"git\", args, {\n cwd,\n shell: false,\n windowsHide: true,\n maxBuffer: 64 * 1024 * 1024,\n });\n return stdout;\n}\n\n/** Parse `git status --porcelain=v1 -z` into repository-relative paths. */\nexport function parsePorcelain(output: string): { files: string[]; removed: string[] } {\n const fields = output.split(\"\\0\");\n const files: string[] = [];\n const removed: string[] = [];\n for (let i = 0; i < fields.length; i++) {\n const entry = fields[i] ?? \"\";\n if (entry.length < 4) continue;\n const xy = entry.slice(0, 2);\n const path = entry.slice(3);\n // A rename or copy is followed by its old name, which is not a change to\n // check. A rename's old name is gone; a copy's is still there.\n if (xy.includes(\"R\") || xy.includes(\"C\")) {\n i++;\n if (xy.includes(\"R\")) removed.push(fields[i] ?? \"\");\n }\n // `RD`, a staged rename then deleted in the tree, removes both names:\n // the old one above and the new one here. Two files, not one twice.\n if (xy.includes(\"D\")) removed.push(path);\n else files.push(path);\n }\n return { files, removed };\n}\n\nexport interface ChangedTree {\n /** The changed files left to check, absolute. */\n files: string[];\n /** The files the tree no longer has: deleted, or renamed away. Absolute. */\n removed: string[];\n /**\n * Whether the tree differs from `HEAD` at all. A deletion alone leaves no\n * file to check, but it can still break a citation to what it removed.\n */\n dirty: boolean;\n}\n\nexport async function changedFiles(cwd: string): Promise<ChangedTree> {\n // Rebased through `cwd`'s own prefix rather than resolved from the\n // top-level git prints: on Windows that is the long spelling of a path the\n // caller may hold in its 8.3 short form, and the two would never compare.\n const prefix = (await git([\"rev-parse\", \"--show-prefix\"], cwd)).trim();\n const status = await git(\n [\"status\", \"--porcelain=v1\", \"-z\", \"--untracked-files=all\"],\n cwd,\n );\n const { files, removed } = parsePorcelain(status);\n const absolute = (path: string): string => resolve(cwd, posix.relative(prefix, path));\n return { files: files.map(absolute), removed: removed.map(absolute), dirty: status.length > 0 };\n}\n","/**\n * What a hook has already told the user this session (proposal 0079: \"A skip\n * message is said once per session\").\n *\n * Each hook is a process of its own, and parallel subagents end in parallel\n * SubagentStop hooks, so the memory is one marker file per message, created\n * exclusively. The process whose create succeeds is the one that says it, so\n * no two hooks can both read \"not said yet\".\n */\nimport { mkdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { DEFAULT_CAPTURE_DIR } from \"../../tracevals/capture/types.js\";\nimport { idHash } from \"../../tracevals/rules/ledger.js\";\n\n/**\n * `<project>/.manni/tracevals/sessions/<session hash>.<key>.said`. The session\n * id is hashed, so nothing in it can climb out of the directory and two ids\n * never share a marker. The key is a gate name, which is already safe.\n */\nexport function saidPath(projectDir: string, sessionId: string, key: string): string {\n return join(projectDir, DEFAULT_CAPTURE_DIR, `${idHash(sessionId)}.${key}.said`);\n}\n\n/**\n * True the first time `key` comes up in a session, and records it. A marker\n * that cannot be written says the message rather than lose it.\n */\nexport function sayOnce(projectDir: string, sessionId: string, key: string): boolean {\n const path = saidPath(projectDir, sessionId, key);\n try {\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, \"\", { flag: \"wx\" });\n return true;\n } catch (err) {\n // EEXIST: another hook said it first. Anything else is an unwritable\n // project, which repeats the message each stop rather than lose it.\n return (err as NodeJS.ErrnoException).code !== \"EEXIST\";\n }\n}\n","/**\n * `manni status`: what is set up here, and so what `manni check` runs.\n *\n * It reads the same table `check` does (`in-play.ts`), counting what the\n * content declares where a domain is in play by declaration: the pages that\n * name their own `$schema`, carry citations or resolve evals, and the terms.\n * It checks nothing, so it exits 0 whatever it finds.\n */\nimport { appendFileSync, existsSync, readFileSync } from \"node:fs\";\nimport { extname, resolve } from \"node:path\";\nimport pkg from \"../../../package.json\" with { type: \"json\" };\nimport { errorMessage } from \"../../shared/errors.js\";\nimport { extractorForExtension } from \"../../meta/extractors/index.js\";\nimport type { HostStatus } from \"../../tracevals/rules/host.js\";\nimport type { Envelope } from \"../core/envelope.js\";\nimport {\n COMMANDS,\n DOMAINS,\n NOT_CHECKED,\n NOT_SET_UP,\n collectionsOf,\n listMembers,\n loadFamily,\n plural,\n type Domain,\n type Family,\n} from \"../core/in-play.js\";\nimport { withSharedWalks } from \"../../meta/core/load-files.js\";\n\nexport const STATUS_FORMATS = [\"pretty\", \"json\"] as const;\nexport type StatusFormat = (typeof STATUS_FORMATS)[number];\n\nexport type DomainState = \"in-play\" | \"not-set-up\" | \"not-checked\" | \"unknown\";\n\nexport interface ModelRole {\n provider: string;\n model: string;\n}\n\nexport interface DomainRow {\n name: string;\n status: DomainState;\n reason: string;\n /** tracevals in play: the model judging inside a hook, and the one extracting rules. */\n models?: { hook: ModelRole; extraction: ModelRole };\n /** tracevals in play with a model host running: each model it holds. */\n host?: HostStatus[\"models\"];\n}\n\nexport interface StatusReport {\n version: string;\n /** The config file, as discovery found it or as it was typed. */\n config: string;\n collections: { name: string; files: number }[];\n domains: DomainRow[];\n}\n\nexport interface StatusOptions {\n cwd?: string;\n configPath?: string;\n /** Test seam: the running model host. Default: ask the inference library. */\n hostStatus?: () => Promise<HostStatus | null>;\n}\n\n/**\n * tracevals' row when `tracevals.runtime` exists: both models, resolved\n * the way `check` and `prepare` resolve them, and the host when one runs.\n */\nasync function tracevalsRow(cwd: string, opts: StatusOptions): Promise<DomainRow> {\n try {\n const [\n { discoverConfig },\n { assertProviderSelection, resolveSelectionIdentity, selectHookProvider, selectProvider },\n { hostStatus },\n ] = await Promise.all([\n import(\"../../tracevals/core/config.js\"),\n import(\"../../tracevals/judge/provider.js\"),\n import(\"../../tracevals/rules/host.js\"),\n ]);\n const { config } = await discoverConfig(cwd, opts.configPath === undefined ? {} : { configPath: opts.configPath });\n const hook = await resolveSelectionIdentity(config, selectHookProvider(config));\n const selection = selectProvider(config);\n assertProviderSelection(selection);\n const extraction = await resolveSelectionIdentity(config, selection);\n const host = await (opts.hostStatus ?? hostStatus)().catch(() => null);\n return {\n name: \"tracevals\",\n status: \"in-play\",\n reason: `hook: ${hook.provider} ${hook.model} · extraction: ${extraction.provider} ${extraction.model}`,\n models: {\n hook: { provider: hook.provider, model: hook.model },\n extraction: { provider: extraction.provider, model: extraction.model },\n },\n ...(host === null || host.models.length === 0 ? {} : { host: host.models }),\n };\n } catch (err) {\n const message = errorMessage(err).split(\"\\n\", 1)[0] ?? \"\";\n return { name: \"tracevals\", status: \"unknown\", reason: `manni tracevals check could not run: ${message}` };\n }\n}\n\n/** `1 page names`, `3 pages name`: a count and the verb that agrees with it. */\nfunction pages(n: number, one: string, many: string): string {\n return n === 1 ? `1 page ${one}` : `${String(n)} pages ${many}`;\n}\n\n/** The pages naming their own `$schema`, read the way `meta validate` extracts them. */\nfunction ownSchemaCount(cwd: string, members: readonly string[]): number {\n let n = 0;\n for (const label of members) {\n const extractor = extractorForExtension(extname(label));\n if (extractor === undefined) continue;\n try {\n const { data } = extractor.extract(readFileSync(resolve(cwd, label), \"utf8\"), label);\n if (data.$schema !== undefined) n++;\n } catch {\n // A page that does not parse names nothing; `meta validate` reports it.\n }\n }\n return n;\n}\n\n/**\n * The pages carrying citations, read the way `cite check` reads them: its\n * targets, its manifests, its entry rules. Nothing is classified, so no claim\n * or source is looked at and no git history is read.\n */\nasync function citedPages(cwd: string, configPath: string): Promise<number> {\n // Imported where they run, so `manni check` never loads them.\n const { prepareRun, readTarget } = await import(\"../../cite/commands/check.js\");\n const { readPage } = await import(\"../../cite/core/page.js\");\n const prepared = await prepareRun({ inputs: [], configPath, cwd, checkSources: false }, \"checked\", \"check\");\n let n = 0;\n for (const file of prepared.files) {\n const content = await readTarget(prepared.run, file);\n const { citations } = (await prepared.setupFor(file, content)).options;\n const read = readPage(file, content, { markers: false, ...(citations === undefined ? {} : { citations }) });\n if (read.citations.length > 0) n++;\n }\n return n;\n}\n\nasync function row(domain: Domain, family: Family, cwd: string, members: readonly string[]): Promise<DomainRow> {\n const configPath = family.configPath;\n const inPlay = (reason: string): DomainRow => ({ name: domain, status: \"in-play\", reason });\n const notSetUp: DomainRow = { name: domain, status: \"not-set-up\", reason: NOT_SET_UP[domain] };\n const section = family.sections.has(domain);\n switch (domain) {\n case \"meta\": {\n if (section) return inPlay(\"meta: section\");\n const n = ownSchemaCount(cwd, members);\n return n > 0 ? inPlay(pages(n, \"names its own $schema\", \"name their own $schema\")) : notSetUp;\n }\n case \"cite\": {\n const n = await citedPages(cwd, configPath);\n return n > 0 ? inPlay(pages(n, \"carries citations\", \"carry citations\")) : notSetUp;\n }\n case \"docevals\": {\n const { runList: listEvals } = await import(\"../../docevals/commands/list.js\");\n const { plans } = await listEvals([], { config: configPath, cwd });\n const n = plans.filter((p) => !p.skip && p.evals.length > 0).length;\n if (n === 0) return notSetUp;\n return inPlay(section ? \"docevals: section\" : pages(n, \"declares evals\", \"declare evals\"));\n }\n case \"term\": {\n const { runList: listTerms } = await import(\"../../term/commands/list.js\");\n const { terms } = await listTerms({ inputs: [], configPath, cwd, allowEmpty: true });\n return terms.length > 0 ? inPlay(plural(terms.length, \"term\")) : notSetUp;\n }\n case \"lint\":\n case \"graph\":\n return section ? inPlay(`${domain}: section`) : notSetUp;\n }\n}\n\n/** Every domain walks the same collections, so the run shares one walk per target set. */\nexport function runStatus(opts: StatusOptions = {}): Promise<StatusReport> {\n return withSharedWalks(() => statusUnshared(opts));\n}\n\nasync function statusUnshared(opts: StatusOptions): Promise<StatusReport> {\n const cwd = resolve(opts.cwd ?? process.cwd());\n const family = await loadFamily(cwd, opts.configPath);\n const members = family.collections.length === 0 ? [] : await listMembers(family, cwd);\n const domains: DomainRow[] = [];\n for (const domain of DOMAINS) {\n // `check` only reads collection members, so with no collections every\n // domain has nothing to check, whatever sections the config carries.\n if (family.collections.length === 0) {\n domains.push({ name: domain, status: \"not-set-up\", reason: \"no collections: in manni.config.yaml\" });\n continue;\n }\n try {\n domains.push(await row(domain, family, cwd, members));\n } catch (err) {\n // Status checks nothing, so a domain that cannot read its own setup is\n // reported in its row rather than ending the run, as unknown: whether it is\n // set up is the thing it could not read.\n const message = errorMessage(err).split(\"\\n\", 1)[0] ?? \"\";\n domains.push({ name: domain, status: \"unknown\", reason: `manni ${COMMANDS[domain]} could not run: ${message}` });\n }\n }\n for (const [name, reason] of NOT_CHECKED) {\n domains.push(\n name === \"tracevals\" && family.runtime\n ? await tracevalsRow(cwd, opts)\n : { name, status: \"not-checked\", reason },\n );\n }\n return {\n version: pkg.version,\n config: family.file.source,\n collections: family.collections.map((c) => ({\n name: c.name,\n files: members.filter((label) => collectionsOf(family, cwd, label).includes(c.name)).length,\n })),\n domains,\n };\n}\n\nconst STATE_LABEL: Readonly<Record<DomainState, string>> = {\n \"in-play\": \"in play\",\n \"not-set-up\": \"not set up\",\n \"not-checked\": \"not checked\",\n unknown: \"unknown\",\n};\n\nexport function renderStatus(report: StatusReport, format: StatusFormat): string {\n if (format === \"json\") return JSON.stringify(report, null, 2);\n const head = [\n `manni ${report.version}`,\n `config ${report.config}`,\n ...report.collections.map((c) => `collection ${c.name} (${plural(c.files, \"file\")})`),\n ].join(\" \");\n // tracevals in play judges each turn, which is what its row says.\n const label = (d: DomainRow): string => (d.models !== undefined ? \"judges each turn\" : STATE_LABEL[d.status]);\n const width = Math.max(14, ...report.domains.map((d) => label(d).length + 3));\n const rows = report.domains.flatMap((d) => [\n `${d.name.padEnd(11)}${label(d).padEnd(width)}${d.reason}`,\n ...(d.host ?? []).map(\n (m) =>\n `${\"\".padEnd(11)}${\"model host\".padEnd(width)}${m.model} loaded, ${plural(m.sessions, \"session\")}, ` +\n `idle ${String(Math.floor(m.idleMs / 60_000))}m`,\n ),\n ]);\n return [head, \"\", ...rows].join(\"\\n\");\n}\n\n/**\n * The plugin skill the briefing points an agent at, as `<plugin>:<skill>`.\n * `test/plugin.test.ts` checks both halves against `plugin/manni`.\n */\nexport const FIX_SKILL = \"manni:fix\";\n\n/** The set-wide checks a stop runs when a collection document changed, as the briefing names them. */\nconst PAGE_WIDE: ReadonlyArray<readonly [Domain, string]> = [[\"term\", \"the glossary\"]];\n\n/** `a`, `a or b`, `a, b or c`: a list in prose, joined by `conjunction`. */\nfunction prose(items: readonly string[], conjunction: string): string {\n return items.length <= 1\n ? (items[0] ?? \"\")\n : `${items.slice(0, -1).join(\", \")} ${conjunction} ${items.at(-1) ?? \"\"}`;\n}\n\n/** What an agent is told at the start of a session, after the table. */\nexport function agentLines(report: StatusReport): string {\n const names = prose(report.collections.map((c) => c.name), \"or\");\n const inPlay = new Set(report.domains.filter((d) => d.status === \"in-play\").map((d) => d.name));\n // A stop checks every citation whenever the tree changed: a source edit can drift any of them.\n const plus = inPlay.has(\"cite\") ? \", plus every citation\" : \"\";\n const pageWide = PAGE_WIDE.filter(([domain]) => inPlay.has(domain)).map(([, what]) => what);\n const also = pageWide.length === 0 ? \"\" : ` It checks ${prose(pageWide, \"and\")} too when you changed a page.`;\n return [\n `After you edit a file in ${names}, manni check runs on it, and errors come back to you at once.`,\n `Before you finish, manni check runs on every file you changed${plus}.${also} You get one repair pass.`,\n `The ${FIX_SKILL} skill says how to repair each finding.`,\n ].join(\"\\n\");\n}\n\n/** A model id as Claude Code spells one, and nothing a shell would read as more. */\nconst MODEL_ID = /^[A-Za-z0-9._:/@-]+$/;\n\n/**\n * Append `export MANNI_GENERATED_BY=<model>` to `$CLAUDE_ENV_FILE`, so every\n * command the session runs records which model wrote what. Only when the\n * envelope names the model, the file is offered, and nobody set the variable.\n */\nexport function exportGeneratedBy(envelope: Envelope, env: NodeJS.ProcessEnv = process.env): boolean {\n const file = env.CLAUDE_ENV_FILE;\n // A context-window suffix such as `[1m]` is a session setting, not the model.\n const model = envelope.model?.replace(/\\[[^\\]]*\\]$/, \"\");\n if (model === undefined || !MODEL_ID.test(model)) return false;\n if (file === undefined || file === \"\" || env.MANNI_GENERATED_BY !== undefined) return false;\n const existing = existsSync(file) ? readFileSync(file, \"utf8\") : \"\";\n const lead = existing === \"\" || existing.endsWith(\"\\n\") ? \"\" : \"\\n\";\n appendFileSync(file, `${lead}export MANNI_GENERATED_BY=${model}\\n`, \"utf8\");\n return true;\n}\n"],"mappings":"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","names":["resolve","record","resolve","resolve","run","resolve","extname","resolve","extname","resolve","resolve","run"]}
@@ -1,31 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- NAMES_ITS_SUBJECT,
4
- findingMessage,
5
- renderCheckGithub
6
- } from "./chunk-GEMXGXPR.js";
7
- import "./chunk-YUZ2ECZY.js";
8
- import "./chunk-OVOYKWCM.js";
9
- import "./chunk-VKWZCEWB.js";
10
- import "./chunk-IKEWBMCN.js";
11
- import "./chunk-M6GH3FGJ.js";
12
- import "./chunk-IN6DWNVE.js";
13
- import "./chunk-QCCAHV6A.js";
14
- import "./chunk-X6WLCNKC.js";
15
- import "./chunk-3XGGF5JW.js";
16
- import "./chunk-YEUYKR62.js";
17
- import "./chunk-RNVYGWIC.js";
18
- import "./chunk-MNH7QO4Z.js";
19
- import "./chunk-XKBEHKWO.js";
20
- import "./chunk-HX44GB4Z.js";
21
- import "./chunk-QCHVR4ZM.js";
22
- import "./chunk-KX5IYIOO.js";
23
- import "./chunk-OWBRDNRZ.js";
24
- import "./chunk-G3T47CFV.js";
25
- import "./chunk-2H7UOFLK.js";
26
- export {
27
- NAMES_ITS_SUBJECT,
28
- findingMessage,
29
- renderCheckGithub
30
- };
31
- //# sourceMappingURL=github-63CZJGZS.js.map
@@ -1,26 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- renderFindingsGithub
4
- } from "./chunk-5EB6RIXJ.js";
5
- import "./chunk-YEUQ7OKT.js";
6
- import "./chunk-77AINBYM.js";
7
- import "./chunk-IKEWBMCN.js";
8
- import "./chunk-M6GH3FGJ.js";
9
- import "./chunk-IN6DWNVE.js";
10
- import "./chunk-QCCAHV6A.js";
11
- import "./chunk-X6WLCNKC.js";
12
- import "./chunk-3XGGF5JW.js";
13
- import "./chunk-YEUYKR62.js";
14
- import "./chunk-RNVYGWIC.js";
15
- import "./chunk-MNH7QO4Z.js";
16
- import "./chunk-XKBEHKWO.js";
17
- import "./chunk-HX44GB4Z.js";
18
- import "./chunk-QCHVR4ZM.js";
19
- import "./chunk-KX5IYIOO.js";
20
- import "./chunk-OWBRDNRZ.js";
21
- import "./chunk-G3T47CFV.js";
22
- import "./chunk-2H7UOFLK.js";
23
- export {
24
- renderFindingsGithub
25
- };
26
- //# sourceMappingURL=github-IYOVHWHG.js.map
@@ -1,29 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- STDIN_LABEL,
4
- runLint
5
- } from "./chunk-TMI2YF6D.js";
6
- import "./chunk-35WTFPQS.js";
7
- import "./chunk-TIUTIOFB.js";
8
- import "./chunk-TBAMBLF3.js";
9
- import "./chunk-YGFIQ6Y5.js";
10
- import "./chunk-M6GH3FGJ.js";
11
- import "./chunk-IN6DWNVE.js";
12
- import "./chunk-QCCAHV6A.js";
13
- import "./chunk-X6WLCNKC.js";
14
- import "./chunk-3XGGF5JW.js";
15
- import "./chunk-YEUYKR62.js";
16
- import "./chunk-RNVYGWIC.js";
17
- import "./chunk-MNH7QO4Z.js";
18
- import "./chunk-XKBEHKWO.js";
19
- import "./chunk-HX44GB4Z.js";
20
- import "./chunk-QCHVR4ZM.js";
21
- import "./chunk-KX5IYIOO.js";
22
- import "./chunk-OWBRDNRZ.js";
23
- import "./chunk-G3T47CFV.js";
24
- import "./chunk-2H7UOFLK.js";
25
- export {
26
- STDIN_LABEL,
27
- runLint
28
- };
29
- //# sourceMappingURL=lint-TBE35CCW.js.map
@@ -1,30 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- renderList,
4
- runList
5
- } from "./chunk-UDUHRXJ4.js";
6
- import "./chunk-Q2H7J3FF.js";
7
- import "./chunk-XG6PVB5S.js";
8
- import "./chunk-YNHZHSSM.js";
9
- import "./chunk-ZXRAE55H.js";
10
- import "./chunk-SE4JN5XN.js";
11
- import "./chunk-M6GH3FGJ.js";
12
- import "./chunk-IN6DWNVE.js";
13
- import "./chunk-QCCAHV6A.js";
14
- import "./chunk-X6WLCNKC.js";
15
- import "./chunk-3XGGF5JW.js";
16
- import "./chunk-YEUYKR62.js";
17
- import "./chunk-RNVYGWIC.js";
18
- import "./chunk-MNH7QO4Z.js";
19
- import "./chunk-XKBEHKWO.js";
20
- import "./chunk-HX44GB4Z.js";
21
- import "./chunk-QCHVR4ZM.js";
22
- import "./chunk-KX5IYIOO.js";
23
- import "./chunk-OWBRDNRZ.js";
24
- import "./chunk-G3T47CFV.js";
25
- import "./chunk-2H7UOFLK.js";
26
- export {
27
- renderList,
28
- runList
29
- };
30
- //# sourceMappingURL=list-IZ4RIM72.js.map
@@ -1,28 +0,0 @@
1
- #!/usr/bin/env node
2
- import {
3
- LIST_FORMATS,
4
- runList
5
- } from "./chunk-23UAGEKP.js";
6
- import "./chunk-YEUQ7OKT.js";
7
- import "./chunk-77AINBYM.js";
8
- import "./chunk-IKEWBMCN.js";
9
- import "./chunk-M6GH3FGJ.js";
10
- import "./chunk-IN6DWNVE.js";
11
- import "./chunk-QCCAHV6A.js";
12
- import "./chunk-X6WLCNKC.js";
13
- import "./chunk-3XGGF5JW.js";
14
- import "./chunk-YEUYKR62.js";
15
- import "./chunk-RNVYGWIC.js";
16
- import "./chunk-MNH7QO4Z.js";
17
- import "./chunk-XKBEHKWO.js";
18
- import "./chunk-HX44GB4Z.js";
19
- import "./chunk-QCHVR4ZM.js";
20
- import "./chunk-KX5IYIOO.js";
21
- import "./chunk-OWBRDNRZ.js";
22
- import "./chunk-G3T47CFV.js";
23
- import "./chunk-2H7UOFLK.js";
24
- export {
25
- LIST_FORMATS,
26
- runList
27
- };
28
- //# sourceMappingURL=list-TNEJ3J77.js.map