@hawkeyexl/manni 4.3.1 → 4.4.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 (224) hide show
  1. package/README.md +9 -1
  2. package/dist/batch-DFRCLY77.js +36 -0
  3. package/dist/build-Q5C6SX5J.js +31 -0
  4. package/dist/calibrate-XQILKXS3.js +31 -0
  5. package/dist/capture-JQMOC3BW.js +32 -0
  6. package/dist/check-HYNGXYJV.js +18 -0
  7. package/dist/check-HYNGXYJV.js.map +1 -0
  8. package/dist/check-NFZQLJKN.js +27 -0
  9. package/dist/check-NFZQLJKN.js.map +1 -0
  10. package/dist/check-U54XV6BP.js +40 -0
  11. package/dist/check-U54XV6BP.js.map +1 -0
  12. package/dist/chunk-252LNOEG.js +622 -0
  13. package/dist/chunk-252LNOEG.js.map +1 -0
  14. package/dist/chunk-2H7UOFLK.js +11 -0
  15. package/dist/chunk-2H7UOFLK.js.map +1 -0
  16. package/dist/chunk-2U3ORT6D.js +230 -0
  17. package/dist/chunk-2U3ORT6D.js.map +1 -0
  18. package/dist/chunk-3AFUD75K.js +23 -0
  19. package/dist/chunk-3AFUD75K.js.map +1 -0
  20. package/dist/{chunk-3R23C5DT.js → chunk-4TSWU2SU.js} +2 -14
  21. package/dist/chunk-4TSWU2SU.js.map +1 -0
  22. package/dist/chunk-5KHIFVD2.js +1192 -0
  23. package/dist/chunk-5KHIFVD2.js.map +1 -0
  24. package/dist/chunk-5YXBLLAC.js +2165 -0
  25. package/dist/chunk-5YXBLLAC.js.map +1 -0
  26. package/dist/chunk-644JVKJ4.js +3872 -0
  27. package/dist/chunk-644JVKJ4.js.map +1 -0
  28. package/dist/chunk-6OYEI2VV.js +88 -0
  29. package/dist/chunk-6OYEI2VV.js.map +1 -0
  30. package/dist/chunk-77AINBYM.js +19 -0
  31. package/dist/chunk-77AINBYM.js.map +1 -0
  32. package/dist/chunk-77HX34KD.js +1287 -0
  33. package/dist/chunk-77HX34KD.js.map +1 -0
  34. package/dist/{chunk-CFDUZRM2.js → chunk-7QMCHA4N.js} +32 -240
  35. package/dist/chunk-7QMCHA4N.js.map +1 -0
  36. package/dist/chunk-BUXDLRDT.js +455 -0
  37. package/dist/chunk-BUXDLRDT.js.map +1 -0
  38. package/dist/chunk-C6OH6CNF.js +388 -0
  39. package/dist/chunk-C6OH6CNF.js.map +1 -0
  40. package/dist/chunk-CK7SKVHR.js +1042 -0
  41. package/dist/chunk-CK7SKVHR.js.map +1 -0
  42. package/dist/chunk-CYWHFSRT.js +6737 -0
  43. package/dist/chunk-CYWHFSRT.js.map +1 -0
  44. package/dist/chunk-ERMSO34F.js +17 -0
  45. package/dist/chunk-ERMSO34F.js.map +1 -0
  46. package/dist/{chunk-IOYXPBCL.js → chunk-G3T47CFV.js} +1 -7
  47. package/dist/{chunk-IOYXPBCL.js.map → chunk-G3T47CFV.js.map} +1 -1
  48. package/dist/chunk-G7NJSREW.js +979 -0
  49. package/dist/chunk-G7NJSREW.js.map +1 -0
  50. package/dist/chunk-GLP5PSXB.js +72 -0
  51. package/dist/chunk-GLP5PSXB.js.map +1 -0
  52. package/dist/chunk-H2DLH2JI.js +198 -0
  53. package/dist/chunk-H2DLH2JI.js.map +1 -0
  54. package/dist/chunk-H6FZ66XR.js +634 -0
  55. package/dist/chunk-H6FZ66XR.js.map +1 -0
  56. package/dist/{chunk-KJR7OVDX.js → chunk-IEQHSCZG.js} +56 -137
  57. package/dist/chunk-IEQHSCZG.js.map +1 -0
  58. package/dist/chunk-IKEWBMCN.js +98 -0
  59. package/dist/chunk-IKEWBMCN.js.map +1 -0
  60. package/dist/chunk-JOHKIAVH.js +5440 -0
  61. package/dist/chunk-JOHKIAVH.js.map +1 -0
  62. package/dist/chunk-JVTNMVYU.js +10921 -0
  63. package/dist/chunk-JVTNMVYU.js.map +1 -0
  64. package/dist/chunk-K3D6FPV6.js +164 -0
  65. package/dist/chunk-K3D6FPV6.js.map +1 -0
  66. package/dist/{chunk-UBMMXS2Y.js → chunk-KCGV52AM.js} +69 -48
  67. package/dist/{chunk-UBMMXS2Y.js.map → chunk-KCGV52AM.js.map} +1 -1
  68. package/dist/chunk-LAKAWRV5.js +1651 -0
  69. package/dist/chunk-LAKAWRV5.js.map +1 -0
  70. package/dist/chunk-LJ2RDH3F.js +49 -0
  71. package/dist/chunk-LJ2RDH3F.js.map +1 -0
  72. package/dist/chunk-M2JCK5F6.js +805 -0
  73. package/dist/chunk-M2JCK5F6.js.map +1 -0
  74. package/dist/chunk-MNH7QO4Z.js +15 -0
  75. package/dist/chunk-MNH7QO4Z.js.map +1 -0
  76. package/dist/{chunk-HAPTXWU2.js → chunk-MYC3O5EJ.js} +4 -4
  77. package/dist/chunk-MYMBCTDE.js +387 -0
  78. package/dist/chunk-MYMBCTDE.js.map +1 -0
  79. package/dist/chunk-NCPWXHDO.js +683 -0
  80. package/dist/chunk-NCPWXHDO.js.map +1 -0
  81. package/dist/chunk-NWZ2SLYL.js +2957 -0
  82. package/dist/chunk-NWZ2SLYL.js.map +1 -0
  83. package/dist/chunk-OBFENF3U.js +934 -0
  84. package/dist/chunk-OBFENF3U.js.map +1 -0
  85. package/dist/chunk-OWBRDNRZ.js +16 -0
  86. package/dist/chunk-OWBRDNRZ.js.map +1 -0
  87. package/dist/{chunk-KTSJ2ZHA.js → chunk-PAU352SV.js} +5 -3
  88. package/dist/{chunk-KTSJ2ZHA.js.map → chunk-PAU352SV.js.map} +1 -1
  89. package/dist/chunk-PCE7QHXJ.js +68 -0
  90. package/dist/chunk-PCE7QHXJ.js.map +1 -0
  91. package/dist/chunk-PCHZY2I7.js +299 -0
  92. package/dist/chunk-PCHZY2I7.js.map +1 -0
  93. package/dist/chunk-PHF3D7ER.js +1042 -0
  94. package/dist/chunk-PHF3D7ER.js.map +1 -0
  95. package/dist/chunk-Q35YIDBV.js +1202 -0
  96. package/dist/chunk-Q35YIDBV.js.map +1 -0
  97. package/dist/chunk-RLR4TKUZ.js +4398 -0
  98. package/dist/chunk-RLR4TKUZ.js.map +1 -0
  99. package/dist/chunk-RNVYGWIC.js +30 -0
  100. package/dist/chunk-RNVYGWIC.js.map +1 -0
  101. package/dist/chunk-SE4JN5XN.js +19 -0
  102. package/dist/chunk-SE4JN5XN.js.map +1 -0
  103. package/dist/chunk-TIUTIOFB.js +25 -0
  104. package/dist/chunk-TIUTIOFB.js.map +1 -0
  105. package/dist/chunk-TU2WUBVZ.js +2 -0
  106. package/dist/chunk-TU2WUBVZ.js.map +1 -0
  107. package/dist/chunk-TZOYZK2E.js +98 -0
  108. package/dist/chunk-TZOYZK2E.js.map +1 -0
  109. package/dist/chunk-UKZNLVJW.js +17 -0
  110. package/dist/chunk-UKZNLVJW.js.map +1 -0
  111. package/dist/chunk-UZC7LDAQ.js +178 -0
  112. package/dist/chunk-UZC7LDAQ.js.map +1 -0
  113. package/dist/chunk-V46OILVC.js +3090 -0
  114. package/dist/chunk-V46OILVC.js.map +1 -0
  115. package/dist/chunk-WQE54PNH.js +1975 -0
  116. package/dist/chunk-WQE54PNH.js.map +1 -0
  117. package/dist/chunk-X3BPBDGQ.js +52 -0
  118. package/dist/chunk-X3BPBDGQ.js.map +1 -0
  119. package/dist/chunk-XSLV76YK.js +54 -0
  120. package/dist/chunk-XSLV76YK.js.map +1 -0
  121. package/dist/{chunk-5HNHEUD5.js → chunk-XYLUCIKQ.js} +3 -3
  122. package/dist/chunk-YEUYKR62.js +72 -0
  123. package/dist/chunk-YEUYKR62.js.map +1 -0
  124. package/dist/{chunk-G5CM2VGQ.js → chunk-YFQBFNQS.js} +8 -94
  125. package/dist/chunk-YFQBFNQS.js.map +1 -0
  126. package/dist/chunk-YIL4XLLJ.js +1661 -0
  127. package/dist/chunk-YIL4XLLJ.js.map +1 -0
  128. package/dist/chunk-YNHZHSSM.js +41 -0
  129. package/dist/chunk-YNHZHSSM.js.map +1 -0
  130. package/dist/chunk-YTCZRLTU.js +96 -0
  131. package/dist/chunk-YTCZRLTU.js.map +1 -0
  132. package/dist/chunk-YYBFZLAJ.js +374 -0
  133. package/dist/chunk-YYBFZLAJ.js.map +1 -0
  134. package/dist/chunk-ZXRAE55H.js +31 -0
  135. package/dist/chunk-ZXRAE55H.js.map +1 -0
  136. package/dist/cli-2QPR2OZG.js +232 -0
  137. package/dist/cli-2QPR2OZG.js.map +1 -0
  138. package/dist/cli-4IOPGZHR.js +1203 -0
  139. package/dist/cli-4IOPGZHR.js.map +1 -0
  140. package/dist/cli-5FL73WHA.js +346 -0
  141. package/dist/cli-5FL73WHA.js.map +1 -0
  142. package/dist/cli-C262QOWM.js +739 -0
  143. package/dist/cli-C262QOWM.js.map +1 -0
  144. package/dist/cli-LJLLIQB2.js +423 -0
  145. package/dist/cli-LJLLIQB2.js.map +1 -0
  146. package/dist/cli-OFPZ5MAS.js +626 -0
  147. package/dist/cli-OFPZ5MAS.js.map +1 -0
  148. package/dist/cli-SHSMSRQY.js +28 -0
  149. package/dist/cli-SHSMSRQY.js.map +1 -0
  150. package/dist/cli-SRHFUZHA.js +473 -0
  151. package/dist/cli-SRHFUZHA.js.map +1 -0
  152. package/dist/cli-URZQXL4K.js +552 -0
  153. package/dist/cli-URZQXL4K.js.map +1 -0
  154. package/dist/cli.d.ts +12 -2
  155. package/dist/cli.js +109 -7661
  156. package/dist/cli.js.map +1 -1
  157. package/dist/docmeta.js +15 -3
  158. package/dist/docmeta.js.map +1 -1
  159. package/dist/github-FE6KCNYJ.js +27 -0
  160. package/dist/github-FE6KCNYJ.js.map +1 -0
  161. package/dist/github-QXL3VMK2.js +32 -0
  162. package/dist/github-QXL3VMK2.js.map +1 -0
  163. package/dist/index.d.ts +65 -3
  164. package/dist/index.js +407 -337
  165. package/dist/index.js.map +1 -1
  166. package/dist/json-7WV7KL6H.js +17 -0
  167. package/dist/json-7WV7KL6H.js.map +1 -0
  168. package/dist/json-SGZ6ZRFD.js +35 -0
  169. package/dist/json-SGZ6ZRFD.js.map +1 -0
  170. package/dist/lint-DL4LJRAY.js +28 -0
  171. package/dist/lint-DL4LJRAY.js.map +1 -0
  172. package/dist/list-6BAXTZUM.js +29 -0
  173. package/dist/list-6BAXTZUM.js.map +1 -0
  174. package/dist/list-7BKNYPSB.js +31 -0
  175. package/dist/list-7BKNYPSB.js.map +1 -0
  176. package/dist/page-3U2GCFNE.js +41 -0
  177. package/dist/page-3U2GCFNE.js.map +1 -0
  178. package/dist/picker-3XF36MJF.js +14 -0
  179. package/dist/picker-3XF36MJF.js.map +1 -0
  180. package/dist/pretty-2H57QVTY.js +43 -0
  181. package/dist/pretty-2H57QVTY.js.map +1 -0
  182. package/dist/pretty-N6DO4OOL.js +37 -0
  183. package/dist/pretty-N6DO4OOL.js.map +1 -0
  184. package/dist/reporters-M6LJ2IYU.js +21 -0
  185. package/dist/reporters-M6LJ2IYU.js.map +1 -0
  186. package/dist/reporters-N6GHXSS7.js +42 -0
  187. package/dist/reporters-N6GHXSS7.js.map +1 -0
  188. package/dist/reporters-UCNEV7PH.js +71 -0
  189. package/dist/reporters-UCNEV7PH.js.map +1 -0
  190. package/dist/run-XZDAREJE.js +33 -0
  191. package/dist/run-XZDAREJE.js.map +1 -0
  192. package/dist/term-5ICGKPC3.js +1592 -0
  193. package/dist/term-5ICGKPC3.js.map +1 -0
  194. package/dist/types-Y6TXHM7M.js +10 -0
  195. package/dist/types-Y6TXHM7M.js.map +1 -0
  196. package/dist/validate-GQRM77YN.js +16 -0
  197. package/dist/validate-GQRM77YN.js.map +1 -0
  198. package/package.json +1 -1
  199. package/plugin/manni/.claude-plugin/plugin.json +9 -0
  200. package/plugin/manni/hooks/hooks.json +52 -0
  201. package/plugin/manni/skills/check/SKILL.md +20 -0
  202. package/plugin/manni/skills/evals/SKILL.md +27 -0
  203. package/plugin/manni/skills/fix/SKILL.md +56 -0
  204. package/plugin/manni/skills/setup/SKILL.md +41 -0
  205. package/dist/batch-A5HZKYIW.js +0 -18
  206. package/dist/calibrate-S5K6QHUY.js +0 -13
  207. package/dist/capture-OZEZDABQ.js +0 -15
  208. package/dist/chunk-3R23C5DT.js.map +0 -1
  209. package/dist/chunk-CFDUZRM2.js.map +0 -1
  210. package/dist/chunk-G5CM2VGQ.js.map +0 -1
  211. package/dist/chunk-KJR7OVDX.js.map +0 -1
  212. package/dist/chunk-V4KUVE47.js +0 -27170
  213. package/dist/chunk-V4KUVE47.js.map +0 -1
  214. package/dist/chunk-ZQBTK3DO.js +0 -26518
  215. package/dist/chunk-ZQBTK3DO.js.map +0 -1
  216. package/dist/picker-6HRMETE7.js +0 -12
  217. package/plugin/tracevals/.claude-plugin/plugin.json +0 -9
  218. package/plugin/tracevals/hooks/hooks.json +0 -17
  219. /package/dist/{batch-A5HZKYIW.js.map → batch-DFRCLY77.js.map} +0 -0
  220. /package/dist/{calibrate-S5K6QHUY.js.map → build-Q5C6SX5J.js.map} +0 -0
  221. /package/dist/{capture-OZEZDABQ.js.map → calibrate-XQILKXS3.js.map} +0 -0
  222. /package/dist/{picker-6HRMETE7.js.map → capture-JQMOC3BW.js.map} +0 -0
  223. /package/dist/{chunk-HAPTXWU2.js.map → chunk-MYC3O5EJ.js.map} +0 -0
  224. /package/dist/{chunk-5HNHEUD5.js.map → chunk-XYLUCIKQ.js.map} +0 -0
@@ -0,0 +1 @@
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/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 type CheckFormat,\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/** The check a hook asks for, or `undefined` when this event is not one `check` answers. */\nfunction 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\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 if (asked === undefined) return;\n try {\n const 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 send(hookReply(run, envelope));\n } catch (err) {\n if (err instanceof FamilyError && err.quiet) return;\n send(hookFailure(errorMessage(err), envelope, asked.file));\n }\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}\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 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 };\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 * | a11y, tracevals | never run by `check`: they need a running site, sessions or a model |\n *\n * Only members of a declared collection are checked.\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/** The two domains `check` never runs, and what to run instead. */\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 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 sections =\n doc !== null && typeof doc === \"object\" && !Array.isArray(doc)\n ? new Set(Object.keys(doc))\n : new Set<string>();\n return { file, configPath: configPath ?? file.source, sections, collections: file.collections };\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 { extname, resolve } from \"node:path\";\nimport pkg from \"../../../package.json\" with { type: \"json\" };\nimport { errorMessage } from \"../../shared/errors.js\";\nimport { resolveTargetSet } from \"../../meta/internal.js\";\nimport { supportedExtensions } from \"../../meta/extractors/index.js\";\nimport { changedFiles } from \"../core/changed.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\" && failed) {\n const reply = envelope.stopHookActive\n ? { systemMessage: \"manni still reports errors after one repair pass. Run manni check to see them.\" }\n : {\n decision: \"block\",\n reason: `manni found errors in the files you changed. Fix them, then finish.\\n\\n${renderFailures(run)}`,\n };\n return { exitCode: 0, stdout: `${JSON.stringify(reply)}\\n` };\n }\n return { exitCode: 0 };\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 * `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 { 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 DomainRow {\n name: string;\n status: DomainState;\n reason: string;\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}\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) domains.push({ name, status: \"not-checked\", reason });\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 const rows = report.domains.map(\n (d) => `${d.name.padEnd(11)}${STATE_LABEL[d.status].padEnd(14)}${d.reason}`,\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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAWA,SAAS,WAAAA,gBAAe;AACxB,SAAS,SAAS,cAAc;;;ACehC,SAAS,IAAI,OAAoC;AAC/C,SAAO,OAAO,UAAU,YAAY,MAAM,SAAS,IAAI,QAAQ;AACjE;AAEA,SAAS,OAAO,OAAqD;AACnE,SAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,IACrE,QACD;AACN;AAGO,SAAS,cAAc,MAAoC;AAChE,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,IAAI;AAAA,EAC1B,QAAQ;AACN,WAAO;AAAA,EACT;AACA,QAAM,MAAM,OAAO,MAAM;AACzB,QAAM,QAAQ,IAAI,KAAK,eAAe;AACtC,MAAI,QAAQ,UAAa,UAAU,OAAW,QAAO;AACrD,QAAM,QAAQ,OAAO,IAAI,UAAU;AACnC,QAAM,WAAW,IAAI,OAAO,SAAS,KAAK,IAAI,OAAO,aAAa;AAClE,QAAM,MAAM,IAAI,IAAI,GAAG;AACvB,QAAM,WAAW,IAAI,IAAI,SAAS;AAClC,QAAM,QAAQ,IAAI,IAAI,KAAK,KAAK,IAAI,OAAO,IAAI,KAAK,GAAG,EAAE;AACzD,SAAO;AAAA,IACL;AAAA,IACA,gBAAgB,IAAI,qBAAqB;AAAA,IACzC,GAAI,QAAQ,SAAY,CAAC,IAAI,EAAE,IAAI;AAAA,IACnC,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,IAC7C,GAAI,aAAa,SAAY,CAAC,IAAI,EAAE,SAAS;AAAA,IAC7C,GAAI,UAAU,SAAY,CAAC,IAAI,EAAE,MAAM;AAAA,EACzC;AACF;AAGA,eAAsB,aACpB,SAA4B,QAAQ,OACL;AAC/B,MAAI,OAAO,MAAO,QAAO;AACzB,MAAI;AACF,WAAO,cAAc,MAAM,UAAU,MAAM,CAAC;AAAA,EAC9C,QAAQ;AAEN,WAAO;AAAA,EACT;AACF;;;ACvDA,SAAS,UAAU,SAAS,WAAW;AACvC,SAAS,SAAS,iBAAiB;AAY5B,IAAM,cAAN,cAA0B,UAAU;AAAA,EACzC,YACE,SAES,QAAQ,OACjB;AACA,UAAM,OAAO;AAFJ;AAGT,SAAK,OAAO;AAAA,EACd;AAAA,EAJW;AAKb;AAEO,SAAS,cAAc,KAA0B;AACtD,SAAO,IAAI;AAAA,IACT,mCAAmC,GAAG;AAAA,IACtC;AAAA,EACF;AACF;AAEO,SAAS,oBAAiC;AAC/C,SAAO,IAAI;AAAA,IACT;AAAA,IACA;AAAA,EACF;AACF;AAGO,IAAM,UAAU,CAAC,QAAQ,QAAQ,QAAQ,YAAY,QAAQ,OAAO;AAIpE,IAAM,WAA6C;AAAA,EACxD,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,OAAO;AACT;AAGO,IAAM,aAA+C;AAAA,EAC1D,MAAM;AAAA,EACN,MAAM;AAAA,EACN,MAAM;AAAA,EACN,UAAU;AAAA,EACV,MAAM;AAAA,EACN,OAAO;AACT;AAGO,IAAM,qBAAqB;AAG3B,IAAM,cAAwD;AAAA,EACnE,CAAC,QAAQ,6CAA6C;AAAA,EACtD,CAAC,aAAa,uCAAuC;AACvD;AAGO,SAAS,OAAO,GAAW,KAAa,OAAO,GAAG,GAAG,KAAa;AACvE,SAAO,GAAG,OAAO,CAAC,CAAC,IAAI,MAAM,IAAI,MAAM,IAAI;AAC7C;AAeA,SAAS,QAAQ,SAA8B;AAC7C,SAAO,IAAI,YAAY,OAAO;AAChC;AAEA,eAAsB,WAAW,KAAa,YAAsC;AAClF,QAAM,OACJ,eAAe,SACX,MAAM,qBAAqB,KAAK,OAAO,IACvC,MAAM,qBAAqB,YAAY,KAAK,OAAO;AACzD,MAAI,SAAS,KAAM,OAAM,cAAc,GAAG;AAE1C,QAAM,MAAM,UAAU,KAAK,IAAI;AAC/B,QAAM,WACJ,QAAQ,QAAQ,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG,IACzD,IAAI,IAAI,OAAO,KAAK,GAAG,CAAC,IACxB,oBAAI,IAAY;AACtB,SAAO,EAAE,MAAM,YAAY,cAAc,KAAK,QAAQ,UAAU,aAAa,KAAK,YAAY;AAChG;AAGO,SAAS,UAAU,KAAa,MAAsB;AAC3D,SAAO,SAAS,KAAK,IAAI,EAAE,MAAM,GAAG,EAAE,KAAK,GAAG;AAChD;AAGO,SAAS,cAAc,QAAgB,KAAa,OAAyB;AAClF,SAAO,SAAS,OAAO,aAAa,OAAO,KAAK,KAAK,KAAK,KAAK;AACjE;AAGA,eAAsB,YAAY,QAAgB,KAAgC;AAChF,QAAM,MAAM,OAAO,KAAK;AACxB,QAAM,EAAE,MAAM,IAAI,MAAM,iBAAiB;AAAA,IACvC,QAAQ,OAAO,YAAY,QAAQ,CAAC,MAAM,EAAE,KAAK;AAAA,IACjD,KAAK;AAAA,IACL,YAAY;AAAA,EACd,CAAC;AACD,SAAO,cAAc,OAAO,CAAC,UAAU,SAAS,OAAO,aAAa,KAAK,KAAK,KAAK,CAAC,EAAE;AAAA,IACpF,CAAC,UAAU,UAAU,KAAK,QAAQ,KAAK,KAAK,CAAC;AAAA,EAC/C;AACF;;;AC/HA,SAAS,SAAS,WAAAC,gBAAe;;;ACZjC,SAAS,gBAAgB;AACzB,SAAS,OAAO,WAAAC,gBAAe;AAC/B,SAAS,iBAAiB;AAE1B,IAAM,MAAM,UAAU,QAAQ;AAE9B,eAAe,IAAI,MAAgB,KAA8B;AAE/D,QAAM,EAAE,OAAO,IAAI,MAAM,IAAI,OAAO,MAAM;AAAA,IACxC;AAAA,IACA,OAAO;AAAA,IACP,aAAa;AAAA,IACb,WAAW,KAAK,OAAO;AAAA,EACzB,CAAC;AACD,SAAO;AACT;AAGO,SAAS,eAAe,QAAwD;AACrF,QAAM,SAAS,OAAO,MAAM,IAAI;AAChC,QAAM,QAAkB,CAAC;AACzB,QAAM,UAAoB,CAAC;AAC3B,WAAS,IAAI,GAAG,IAAI,OAAO,QAAQ,KAAK;AACtC,UAAM,QAAQ,OAAO,CAAC,KAAK;AAC3B,QAAI,MAAM,SAAS,EAAG;AACtB,UAAM,KAAK,MAAM,MAAM,GAAG,CAAC;AAC3B,UAAM,OAAO,MAAM,MAAM,CAAC;AAG1B,QAAI,GAAG,SAAS,GAAG,KAAK,GAAG,SAAS,GAAG,GAAG;AACxC;AACA,UAAI,GAAG,SAAS,GAAG,EAAG,SAAQ,KAAK,OAAO,CAAC,KAAK,EAAE;AAAA,IACpD;AAGA,QAAI,GAAG,SAAS,GAAG,EAAG,SAAQ,KAAK,IAAI;AAAA,QAClC,OAAM,KAAK,IAAI;AAAA,EACtB;AACA,SAAO,EAAE,OAAO,QAAQ;AAC1B;AAcA,eAAsB,aAAa,KAAmC;AAIpE,QAAM,UAAU,MAAM,IAAI,CAAC,aAAa,eAAe,GAAG,GAAG,GAAG,KAAK;AACrE,QAAM,SAAS,MAAM;AAAA,IACnB,CAAC,UAAU,kBAAkB,MAAM,uBAAuB;AAAA,IAC1D;AAAA,EACF;AACA,QAAM,EAAE,OAAO,QAAQ,IAAI,eAAe,MAAM;AAChD,QAAM,WAAW,CAAC,SAAyBA,SAAQ,KAAK,MAAM,SAAS,QAAQ,IAAI,CAAC;AACpF,SAAO,EAAE,OAAO,MAAM,IAAI,QAAQ,GAAG,SAAS,QAAQ,IAAI,QAAQ,GAAG,OAAO,OAAO,SAAS,EAAE;AAChG;;;AD9BO,IAAM,gBAAgB,CAAC,UAAU,QAAQ,QAAQ;AA+DxD,eAAe,UAAU,QAAgB,KAAgC;AACvE,QAAM,EAAE,QAAQ,KAAK,QAAQ,SAAS,IAAI;AAC1C,QAAM,aAAa,OAAO;AAC1B,UAAQ,QAAQ;AAAA,IACd,KAAK,QAAQ;AACX,YAAM,CAAC,EAAE,YAAY,GAAG,EAAE,QAAQ,WAAW,CAAC,IAAI,MAAM,QAAQ,IAAI;AAAA,QAClE,OAAO,wBAAiC;AAAA,QACxC,OAAO,yBAA+B;AAAA,MACxC,CAAC;AACD,YAAMC,OAAM,MAAM,YAAY,EAAE,QAAQ,YAAY,KAAK,iBAAiB,MAAM,SAAS,CAAC;AAC1F,UAAIA,KAAI,QAAQ,WAAW,GAAG;AAC5B,eAAO,EAAE,SAAS,OAAO,SAAS,IAAI,MAAM,IAAI,qBAAqB,WAAW,KAAK;AAAA,MACvF;AACA,aAAO;AAAA,QACL,QAAQA,KAAI,QAAQ,SAAS;AAAA,QAC7B,QAAQ,CAAC,QAAQ,UACf,WAAW,QAAQA,KAAI,SAASA,KAAI,SAAS,EAAE,OAAO,OAAO,MAAM,OAAOA,KAAI,OAAO,SAAS,CAAC;AAAA,MACnG;AAAA,IACF;AAAA,IACA,KAAK,QAAQ;AACX,YAAM,CAAC,EAAE,UAAU,QAAQ,GAAG,EAAE,mBAAmB,WAAW,GAAG,EAAE,iBAAiB,SAAS,GAAG,EAAE,mBAAmB,WAAW,CAAC,IAC/H,MAAM,QAAQ,IAAI;AAAA,QAChB,OAAO,qBAA8B;AAAA,QACrC,OAAO,sBAAgC;AAAA,QACvC,OAAO,oBAA8B;AAAA,QACrC,OAAO,sBAAgC;AAAA,MACzC,CAAC;AACH,YAAMA,OAAM,MAAM,QAAQ,EAAE,QAAQ,YAAY,KAAK,SAAS,CAAC;AAC/D,UAAI,CAACA,KAAI,MAAM,KAAK,CAAC,MAAM,EAAE,UAAU,SAAS,KAAK,EAAE,SAAS,SAAS,CAAC,GAAG;AAC3E,eAAO,EAAE,SAAS,WAAW,KAAK;AAAA,MACpC;AACA,aAAO;AAAA,QACL,QAAQA,KAAI,QAAQ,SAAS;AAAA,QAC7B,QAAQ,CAAC,QAAQ,UACf,WAAW,SACP,SAASA,IAAG,IACZ,WAAW,WACT,WAAWA,IAAG,IACd,WAAWA,MAAK,EAAE,OAAO,OAAO,KAAK,CAAC;AAAA,MAChD;AAAA,IACF;AAAA,IACA,KAAK,QAAQ;AACX,UAAI,CAAC,OAAO,SAAS,IAAI,MAAM,EAAG,QAAO,EAAE,SAAS,WAAW,KAAK;AACpE,YAAM,CAAC,EAAE,QAAQ,GAAG,EAAE,QAAQ,WAAW,CAAC,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC9D,OAAO,oBAA6B;AAAA,QACpC,OAAO,yBAA+B;AAAA,MACxC,CAAC;AACD,YAAMA,OAAM,MAAM,QAAQ,EAAE,QAAQ,YAAY,KAAK,SAAS,CAAC;AAC/D,aAAO;AAAA,QACL,QAAQA,KAAI,QAAQ,SAAS;AAAA,QAC7B,QAAQ,CAAC,QAAQ,UAAU,WAAWA,MAAK,QAAQ,EAAE,MAAM,CAAC;AAAA,MAC9D;AAAA,IACF;AAAA,IACA,KAAK,YAAY;AACf,YAAM,CAAC,EAAE,QAAQ,YAAY,GAAG,EAAE,QAAQ,eAAe,GAAG,EAAE,cAAc,CAAC,IAAI,MAAM,QAAQ,IAAI;AAAA,QACjG,OAAO,mBAAgC;AAAA,QACvC,OAAO,yBAAmC;AAAA,QAC1C,OAAO,qBAAyB;AAAA,MAClC,CAAC;AACD,UAAI;AACJ,UAAI;AACF,iBAAS,MAAM,YAAY,QAAQ;AAAA,UACjC,QAAQ;AAAA,UACR;AAAA,UACA,mBAAmB;AAAA,UACnB,UAAU;AAAA,UACV,WAAW;AAAA,UACX,aAAa,gBAAI;AAAA,QACnB,CAAC;AAAA,MACH,SAAS,KAAK;AACZ,YAAI,eAAe,iBAAiB,IAAI,SAAS,oBAAoB;AACnE,iBAAO,EAAE,SAAS,WAAW,SAAS;AAAA,QACxC;AACA,cAAM;AAAA,MACR;AACA,aAAO;AAAA,QACL,QAAQ,OAAO,aAAa;AAAA,QAC5B,QAAQ,CAAC,QAAQ,UAAU,eAAe,QAAQ,QAAQ,EAAE,MAAM,CAAC;AAAA,MACrE;AAAA,IACF;AAAA,IACA,KAAK,QAAQ;AACX,YAAM,CAAC,EAAE,UAAU,QAAQ,GAAG,EAAE,sBAAsB,WAAW,GAAG,EAAE,oBAAoB,SAAS,GAAG,EAAE,sBAAsB,WAAW,CAAC,IACxI,MAAM,QAAQ,IAAI;AAAA,QAChB,OAAO,qBAA8B;AAAA,QACrC,OAAO,sBAAgC;AAAA,QACvC,OAAO,oBAA8B;AAAA,QACrC,OAAO,sBAAgC;AAAA,MACzC,CAAC;AACH,YAAM,SAAS,MAAM,QAAQ,EAAE,QAAQ,YAAY,KAAK,YAAY,MAAM,SAAS,CAAC;AACpF,UAAI,OAAO,UAAU,EAAG,QAAO,EAAE,SAAS,WAAW,KAAK;AAC1D,aAAO;AAAA,QACL,QAAQ,OAAO,QAAQ,SAAS;AAAA,QAChC,QAAQ,CAAC,QAAQ,UACf,WAAW,SACP,SAAS,MAAM,IACf,WAAW,WACT,WAAW,MAAM,IACjB,WAAW,QAAQ,EAAE,OAAO,YAAY,KAAK,CAAC;AAAA,MACxD;AAAA,IACF;AAAA,IACA,KAAK,SAAS;AACZ,UAAI,CAAC,OAAO,SAAS,IAAI,OAAO,EAAG,QAAO,EAAE,SAAS,WAAW,MAAM;AACtE,YAAM,CAAC,EAAE,WAAW,GAAG,EAAE,UAAU,UAAU,aAAa,YAAY,CAAC,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC3F,OAAO,qBAA+B;AAAA,QACtC,OAAO,qBAA+B;AAAA,MACxC,CAAC;AACD,YAAM,QAAQ,MAAM,WAAW,EAAE,QAAQ,YAAY,IAAI,CAAC;AAC1D,iBAAW,WAAW,MAAM,SAAU,UAAS,OAAO;AACtD,YAAM,SAAS,MAAM,SAAS,EAAE,QAAQ,YAAY,KAAK,QAAQ,MAAM,OAAO,CAAC;AAC/E,aAAO;AAAA,QACL,QAAQ,OAAO,aAAa;AAAA,QAC5B,QAAQ,CAAC,WAAW,YAAY,QAAQ,MAAM;AAAA,MAChD;AAAA,IACF;AAAA,EACF;AACF;AAEA,eAAe,QAAQ,QAAgB,KAAqC;AAC1E,QAAM,UAAU,SAAS,MAAM;AAC/B,MAAI;AACF,UAAM,SAAS,MAAM,UAAU,QAAQ,GAAG;AAC1C,QAAI,aAAa,OAAQ,QAAO,EAAE,SAAS,QAAQ,WAAW,SAAS,OAAO,QAAQ;AACtF,WAAO,EAAE,SAAS,QAAQ,OAAO,SAAS,SAAS,QAAQ,QAAQ,OAAO,OAAO;AAAA,EACnF,SAAS,KAAK;AACZ,WAAO,EAAE,SAAS,QAAQ,SAAS,SAAS,aAAa,GAAG,EAAE;AAAA,EAChE;AACF;AAGA,SAAS,WAAW,OAAwB;AAC1C,SAAO,oBAAoB,EAAE,SAAS,QAAQ,KAAK,EAAE,YAAY,CAAC;AACpE;AAGO,SAAS,eAAe,MAAmD;AAChF,SAAO,gBAAgB,MAAM,cAAc,IAAI,CAAC;AAClD;AAEA,eAAe,cAAc,MAAmD;AAC9E,QAAM,MAAMC,SAAQ,KAAK,OAAO,QAAQ,IAAI,CAAC;AAC7C,QAAM,WAAW,KAAK,aAAa,MAAY;AAC/C,QAAM,SAAS,MAAM,WAAW,KAAK,KAAK,UAAU;AACpD,MAAI,OAAO,YAAY,WAAW,EAAG,OAAM,kBAAkB;AAC7D,QAAM,WAAW,CAAC,UAA2B,cAAc,QAAQ,KAAK,KAAK,EAAE,SAAS;AAExF,MAAI;AACJ,MAAI;AACJ,MAAI;AACJ,UAAQ,KAAK,MAAM,MAAM;AAAA,IACvB,KAAK;AACH,cAAQ,MAAM,YAAY,QAAQ,GAAG;AACrC,eAAS,CAAC;AACV,gBAAU,CAAC,GAAG,OAAO;AACrB;AAAA,IACF,KAAK,SAAS;AACZ,YAAM,EAAE,OAAO,MAAM,IAAI,MAAM,iBAAiB;AAAA,QAC9C,QAAQ,KAAK,MAAM;AAAA,QACnB;AAAA,QACA,GAAI,KAAK,iBAAiB,OAAO,EAAE,YAAY,KAAK,IAAI,CAAC;AAAA,MAC3D,CAAC;AACD,YAAM,UAAU,MAAM,OAAO,CAAC,UAAU,CAAC,SAAS,KAAK,CAAC;AACxD,UAAI,QAAQ,SAAS,GAAG;AACtB,iBAAS,WAAW,OAAO,QAAQ,QAAQ,MAAM,CAAC,8BAA8B,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,MACtG;AAEA,cAAQ,MAAM,OAAO,CAAC,UAAU,SAAS,KAAK,KAAK,WAAW,KAAK,CAAC;AACpE,eAAS;AACT,gBAAU,MAAM,SAAS,IAAI,CAAC,QAAQ,QAAQ,QAAQ,UAAU,IAAI,CAAC;AACrE;AAAA,IACF;AAAA,IACA,KAAK,WAAW;AACd,YAAM,UAAU,MAAM,aAAa,GAAG;AACtC,UAAI,CAAC,QAAQ,MAAO,QAAO,EAAE,QAAQ,QAAQ,OAAO,CAAC,GAAG,QAAQ,CAAC,EAAE;AACnE,YAAM,kBAAkB,CAAC,UACvB,MAAM,IAAI,CAAC,SAAS,UAAU,KAAK,IAAI,CAAC,EAAE,OAAO,CAAC,MAAM,WAAW,CAAC,KAAK,SAAS,CAAC,CAAC;AACtF,cAAQ,gBAAgB,QAAQ,KAAK;AACrC,eAAS;AAKT,YAAM,cAAc,MAAM,SAAS,KAAK,gBAAgB,QAAQ,OAAO,EAAE,SAAS;AAClF,gBAAU;AAAA,QACR,GAAI,MAAM,SAAS,IAAK,CAAC,QAAQ,QAAQ,UAAU,IAAc,CAAC;AAAA,QAClE;AAAA,QACA,GAAI,cAAe,CAAC,MAAM,IAAc,CAAC;AAAA,MAC3C;AACA;AAAA,IACF;AAAA,EACF;AAEA,QAAM,SAAyB,CAAC;AAChC,aAAW,UAAU,SAAS;AAE5B,UAAM,UAAU,WAAW,UAAU,WAAW,WAAY,WAAW,UAAU,KAAK,MAAM,SAAS;AACrG,WAAO,KAAK,MAAM,QAAQ,QAAQ,EAAE,QAAQ,KAAK,QAAQ,UAAU,CAAC,IAAI,QAAQ,SAAS,CAAC,CAAC;AAAA,EAC7F;AACA,MAAI,KAAK,MAAM,SAAS,SAAS,OAAO,MAAM,CAAC,MAAM,EAAE,WAAW,SAAS,GAAG;AAC5E,UAAM,kBAAkB;AAAA,EAC1B;AACA,SAAO,EAAE,QAAQ,OAAO,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM,IAAI,SAAS,QAAQ,OAAO,OAAO;AAC5F;AAGO,SAAS,YAAYD,MAAgC;AAC1D,MAAIA,KAAI,OAAO,KAAK,CAAC,MAAM,EAAE,WAAW,OAAO,EAAG,QAAO;AACzD,SAAOA,KAAI,WAAW,SAAS,IAAI;AACrC;AAEA,SAAS,MAAM,OAAwC;AACrD,SAAO,MAAM,WAAW,UAAU,MAAM,WAAW;AACrD;AAGA,SAAS,UAAU,SAAyB;AAC1C,SAAO,QAAQ,MAAM,MAAM,CAAC,EAAE,CAAC,KAAK;AACtC;AAGA,SAAS,eAAeA,MAA6B;AACnD,SAAOA,KAAI,OACR,OAAO,CAAC,MAAqB,EAAE,WAAW,MAAM,EAChD,IAAI,CAAC,MAAM,GAAG,EAAE,OAAO;AAAA,EAAK,EAAE,OAAO,UAAU,KAAK,CAAC,EAAE,EACvD,KAAK,MAAM;AAChB;AAEO,SAAS,aAAaA,MAAqB,OAAwB;AACxE,QAAM,SAAmB,CAAC;AAC1B,aAAW,SAASA,KAAI,QAAQ;AAC9B,QAAI,MAAM,KAAK,EAAG,QAAO,KAAK,GAAG,MAAM,OAAO;AAAA,EAAK,MAAM,OAAO,UAAU,KAAK,CAAC,EAAE;AAAA,EACpF;AACA,QAAM,SAASA,KAAI,OAAO,OAAO,CAAC,MAAwB,CAAC,MAAM,CAAC,CAAC;AACnE,MAAI,OAAO,SAAS,GAAG;AACrB,UAAM,QAAQ,KAAK,IAAI,GAAG,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ,MAAM,CAAC,IAAI;AACjE,WAAO;AAAA,MACL,OACG,IAAI,CAAC,MAAM,GAAG,EAAE,OAAO,OAAO,CAAC,CAAC,GAAG,EAAE,QAAQ,OAAO,KAAK,CAAC,GAAG,UAAU,EAAE,OAAO,CAAC,EAAE,EACnF,KAAK,IAAI;AAAA,IACd;AAAA,EACF;AACA,QAAM,QAAQ,CAAC,WACbA,KAAI,OAAO,OAAO,CAAC,MAAM,EAAE,WAAW,MAAM,EAAE;AAChD,QAAM,SAAS,MAAM,OAAO;AAC5B,SAAO;AAAA,IACL,GAAG,OAAOA,KAAI,OAAO,QAAQ,OAAO,CAAC,SAAS,OAAOA,KAAI,MAAM,QAAQ,MAAM,CAAC,KACzE,OAAO,MAAM,MAAM,CAAC,CAAC,YAAY,OAAO,MAAM,SAAS,CAAC,CAAC,cAC3D,SAAS,IAAI,KAAK,OAAO,MAAM,CAAC,mBAAmB;AAAA,EACxD;AACA,SAAO,OAAO,KAAK,MAAM;AAC3B;AAGA,SAAS,UAAU,GAAyB;AAC1C,MAAI,CAAC,MAAM,CAAC,EAAG,QAAO,EAAE,SAAS,EAAE,SAAS,QAAQ,EAAE,QAAQ,SAAS,EAAE,QAAQ;AACjF,MAAI;AACF,WAAO,EAAE,SAAS,EAAE,SAAS,QAAQ,EAAE,QAAQ,QAAQ,KAAK,MAAM,EAAE,OAAO,QAAQ,KAAK,CAAC,EAAa;AAAA,EACxG,QAAQ;AAKN,WAAO,EAAE,SAAS,EAAE,SAAS,QAAQ,SAAS,SAAS,GAAG,EAAE,OAAO,2CAA2C;AAAA,EAChH;AACF;AAEO,SAAS,WAAWA,MAA6B;AACtD,SAAO,KAAK;AAAA,IACV;AAAA,MACE,QAAQA,KAAI;AAAA,MACZ,OAAOA,KAAI;AAAA,MACX,QAAQA,KAAI,OAAO,IAAI,SAAS;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;AAEO,SAAS,aAAaA,MAA6B;AACxD,SAAOA,KAAI,OACR,OAAO,KAAK,EACZ,IAAI,CAAC,MAAM,EAAE,OAAO,UAAU,KAAK,CAAC,EACpC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,EAChC,KAAK,IAAI;AACd;AAEO,SAAS,OAAOA,MAAqB,QAAqB,OAAwB;AACvF,SAAO,WAAW,SAAS,WAAWA,IAAG,IAAI,WAAW,WAAW,aAAaA,IAAG,IAAI,aAAaA,MAAK,KAAK;AAChH;AAUO,IAAM,aAAgC,CAAC,QAAQ,SAAS,aAAa,cAAc;AAOnF,SAAS,UAAUA,MAAqB,UAA+B;AAC5E,QAAM,SAASA,KAAI,WAAW;AAC9B,MAAI,SAAS,UAAU,eAAe;AACpC,UAAM,QAAQA,KAAI,MAAM,KAAK,IAAI;AACjC,QAAI,QAAQ;AACV,aAAO;AAAA,QACL,UAAU;AAAA,QACV,QAAQ,yBAAyB,KAAK;AAAA;AAAA,EAAsC,eAAeA,IAAG,CAAC;AAAA;AAAA,MACjG;AAAA,IACF;AACA,UAAM,SAASA,KAAI,OAAO,OAAO,CAAC,MAAwB,EAAE,WAAW,OAAO;AAC9E,QAAI,OAAO,WAAW,EAAG,QAAO,EAAE,UAAU,EAAE;AAC9C,UAAM,oBAAoB,OACvB,IAAI,CAAC,MAAM,SAAS,EAAE,OAAO,oBAAoB,KAAK,KAAK,UAAU,EAAE,OAAO,CAAC,EAAE,EACjF,KAAK,IAAI;AACZ,WAAO;AAAA,MACL,UAAU;AAAA,MACV,QAAQ,GAAG,KAAK,UAAU,EAAE,oBAAoB,EAAE,eAAe,eAAe,kBAAkB,EAAE,CAAC,CAAC;AAAA;AAAA,IACxG;AAAA,EACF;AACA,MAAI,SAAS,UAAU,UAAU,QAAQ;AACvC,UAAM,QAAQ,SAAS,iBACnB,EAAE,eAAe,iFAAiF,IAClG;AAAA,MACE,UAAU;AAAA,MACV,QAAQ;AAAA;AAAA,EAA0E,eAAeA,IAAG,CAAC;AAAA,IACvG;AACJ,WAAO,EAAE,UAAU,GAAG,QAAQ,GAAG,KAAK,UAAU,KAAK,CAAC;AAAA,EAAK;AAAA,EAC7D;AACA,SAAO,EAAE,UAAU,EAAE;AACvB;AAGO,SAAS,YAAY,SAAiB,UAAoB,MAAqC;AACpG,MAAI,SAAS,UAAU,iBAAiB,SAAS,OAAW,QAAO,EAAE,UAAU,EAAE;AACjF,QAAM,oBAAoB,+BAA+B,IAAI,KAAK,UAAU,OAAO,CAAC;AACpF,SAAO;AAAA,IACL,UAAU;AAAA,IACV,QAAQ,GAAG,KAAK,UAAU,EAAE,oBAAoB,EAAE,eAAe,eAAe,kBAAkB,EAAE,CAAC,CAAC;AAAA;AAAA,EACxG;AACF;;;AE3bA,SAAS,gBAAgB,YAAY,oBAAoB;AACzD,SAAS,WAAAE,UAAS,WAAAC,gBAAe;AAmB1B,IAAM,iBAAiB,CAAC,UAAU,MAAM;AAyB/C,SAAS,MAAM,GAAW,KAAa,MAAsB;AAC3D,SAAO,MAAM,IAAI,UAAU,GAAG,KAAK,GAAG,OAAO,CAAC,CAAC,UAAU,IAAI;AAC/D;AAGA,SAAS,eAAe,KAAa,SAAoC;AACvE,MAAI,IAAI;AACR,aAAW,SAAS,SAAS;AAC3B,UAAM,YAAY,sBAAsBC,SAAQ,KAAK,CAAC;AACtD,QAAI,cAAc,OAAW;AAC7B,QAAI;AACF,YAAM,EAAE,KAAK,IAAI,UAAU,QAAQ,aAAaC,SAAQ,KAAK,KAAK,GAAG,MAAM,GAAG,KAAK;AACnF,UAAI,KAAK,YAAY,OAAW;AAAA,IAClC,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO;AACT;AAOA,eAAe,WAAW,KAAa,YAAqC;AAE1E,QAAM,EAAE,YAAY,WAAW,IAAI,MAAM,OAAO,qBAA8B;AAC9E,QAAM,EAAE,SAAS,IAAI,MAAM,OAAO,oBAAyB;AAC3D,QAAM,WAAW,MAAM,WAAW,EAAE,QAAQ,CAAC,GAAG,YAAY,KAAK,cAAc,MAAM,GAAG,WAAW,OAAO;AAC1G,MAAI,IAAI;AACR,aAAW,QAAQ,SAAS,OAAO;AACjC,UAAM,UAAU,MAAM,WAAW,SAAS,KAAK,IAAI;AACnD,UAAM,EAAE,UAAU,KAAK,MAAM,SAAS,SAAS,MAAM,OAAO,GAAG;AAC/D,UAAM,OAAO,SAAS,MAAM,SAAS,EAAE,SAAS,OAAO,GAAI,cAAc,SAAY,CAAC,IAAI,EAAE,UAAU,EAAG,CAAC;AAC1G,QAAI,KAAK,UAAU,SAAS,EAAG;AAAA,EACjC;AACA,SAAO;AACT;AAEA,eAAe,IAAI,QAAgB,QAAgB,KAAa,SAAgD;AAC9G,QAAM,aAAa,OAAO;AAC1B,QAAM,SAAS,CAAC,YAA+B,EAAE,MAAM,QAAQ,QAAQ,WAAW,OAAO;AACzF,QAAM,WAAsB,EAAE,MAAM,QAAQ,QAAQ,cAAc,QAAQ,WAAW,MAAM,EAAE;AAC7F,QAAM,UAAU,OAAO,SAAS,IAAI,MAAM;AAC1C,UAAQ,QAAQ;AAAA,IACd,KAAK,QAAQ;AACX,UAAI,QAAS,QAAO,OAAO,eAAe;AAC1C,YAAM,IAAI,eAAe,KAAK,OAAO;AACrC,aAAO,IAAI,IAAI,OAAO,MAAM,GAAG,yBAAyB,wBAAwB,CAAC,IAAI;AAAA,IACvF;AAAA,IACA,KAAK,QAAQ;AACX,YAAM,IAAI,MAAM,WAAW,KAAK,UAAU;AAC1C,aAAO,IAAI,IAAI,OAAO,MAAM,GAAG,qBAAqB,iBAAiB,CAAC,IAAI;AAAA,IAC5E;AAAA,IACA,KAAK,YAAY;AACf,YAAM,EAAE,SAAS,UAAU,IAAI,MAAM,OAAO,oBAAiC;AAC7E,YAAM,EAAE,MAAM,IAAI,MAAM,UAAU,CAAC,GAAG,EAAE,QAAQ,YAAY,IAAI,CAAC;AACjE,YAAM,IAAI,MAAM,OAAO,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC,EAAE;AAC7D,UAAI,MAAM,EAAG,QAAO;AACpB,aAAO,OAAO,UAAU,sBAAsB,MAAM,GAAG,kBAAkB,eAAe,CAAC;AAAA,IAC3F;AAAA,IACA,KAAK,QAAQ;AACX,YAAM,EAAE,SAAS,UAAU,IAAI,MAAM,OAAO,oBAA6B;AACzE,YAAM,EAAE,MAAM,IAAI,MAAM,UAAU,EAAE,QAAQ,CAAC,GAAG,YAAY,KAAK,YAAY,KAAK,CAAC;AACnF,aAAO,MAAM,SAAS,IAAI,OAAO,OAAO,MAAM,QAAQ,MAAM,CAAC,IAAI;AAAA,IACnE;AAAA,IACA,KAAK;AAAA,IACL,KAAK;AACH,aAAO,UAAU,OAAO,GAAG,MAAM,WAAW,IAAI;AAAA,EACpD;AACF;AAGO,SAAS,UAAU,OAAsB,CAAC,GAA0B;AACzE,SAAO,gBAAgB,MAAM,eAAe,IAAI,CAAC;AACnD;AAEA,eAAe,eAAe,MAA4C;AACxE,QAAM,MAAMA,SAAQ,KAAK,OAAO,QAAQ,IAAI,CAAC;AAC7C,QAAM,SAAS,MAAM,WAAW,KAAK,KAAK,UAAU;AACpD,QAAM,UAAU,OAAO,YAAY,WAAW,IAAI,CAAC,IAAI,MAAM,YAAY,QAAQ,GAAG;AACpF,QAAM,UAAuB,CAAC;AAC9B,aAAW,UAAU,SAAS;AAG5B,QAAI,OAAO,YAAY,WAAW,GAAG;AACnC,cAAQ,KAAK,EAAE,MAAM,QAAQ,QAAQ,cAAc,QAAQ,uCAAuC,CAAC;AACnG;AAAA,IACF;AACA,QAAI;AACF,cAAQ,KAAK,MAAM,IAAI,QAAQ,QAAQ,KAAK,OAAO,CAAC;AAAA,IACtD,SAAS,KAAK;AAIZ,YAAM,UAAU,aAAa,GAAG,EAAE,MAAM,MAAM,CAAC,EAAE,CAAC,KAAK;AACvD,cAAQ,KAAK,EAAE,MAAM,QAAQ,QAAQ,WAAW,QAAQ,SAAS,SAAS,MAAM,CAAC,mBAAmB,OAAO,GAAG,CAAC;AAAA,IACjH;AAAA,EACF;AACA,aAAW,CAAC,MAAM,MAAM,KAAK,YAAa,SAAQ,KAAK,EAAE,MAAM,QAAQ,eAAe,OAAO,CAAC;AAC9F,SAAO;AAAA,IACL,SAAS,gBAAI;AAAA,IACb,QAAQ,OAAO,KAAK;AAAA,IACpB,aAAa,OAAO,YAAY,IAAI,CAAC,OAAO;AAAA,MAC1C,MAAM,EAAE;AAAA,MACR,OAAO,QAAQ,OAAO,CAAC,UAAU,cAAc,QAAQ,KAAK,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,EAAE;AAAA,IACvF,EAAE;AAAA,IACF;AAAA,EACF;AACF;AAEA,IAAM,cAAqD;AAAA,EACzD,WAAW;AAAA,EACX,cAAc;AAAA,EACd,eAAe;AAAA,EACf,SAAS;AACX;AAEO,SAAS,aAAa,QAAsB,QAA8B;AAC/E,MAAI,WAAW,OAAQ,QAAO,KAAK,UAAU,QAAQ,MAAM,CAAC;AAC5D,QAAM,OAAO;AAAA,IACX,SAAS,OAAO,OAAO;AAAA,IACvB,UAAU,OAAO,MAAM;AAAA,IACvB,GAAG,OAAO,YAAY,IAAI,CAAC,MAAM,cAAc,EAAE,IAAI,KAAK,OAAO,EAAE,OAAO,MAAM,CAAC,GAAG;AAAA,EACtF,EAAE,KAAK,KAAK;AACZ,QAAM,OAAO,OAAO,QAAQ;AAAA,IAC1B,CAAC,MAAM,GAAG,EAAE,KAAK,OAAO,EAAE,CAAC,GAAG,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,MAAM;AAAA,EAC3E;AACA,SAAO,CAAC,MAAM,IAAI,GAAG,IAAI,EAAE,KAAK,IAAI;AACtC;AAMO,IAAM,YAAY;AAGzB,IAAM,YAAsD,CAAC,CAAC,QAAQ,cAAc,CAAC;AAGrF,SAAS,MAAM,OAA0B,aAA6B;AACpE,SAAO,MAAM,UAAU,IAClB,MAAM,CAAC,KAAK,KACb,GAAG,MAAM,MAAM,GAAG,EAAE,EAAE,KAAK,IAAI,CAAC,IAAI,WAAW,IAAI,MAAM,GAAG,EAAE,KAAK,EAAE;AAC3E;AAGO,SAAS,WAAW,QAA8B;AACvD,QAAM,QAAQ,MAAM,OAAO,YAAY,IAAI,CAAC,MAAM,EAAE,IAAI,GAAG,IAAI;AAC/D,QAAM,SAAS,IAAI,IAAI,OAAO,QAAQ,OAAO,CAAC,MAAM,EAAE,WAAW,SAAS,EAAE,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC;AAE9F,QAAM,OAAO,OAAO,IAAI,MAAM,IAAI,0BAA0B;AAC5D,QAAM,WAAW,UAAU,OAAO,CAAC,CAAC,MAAM,MAAM,OAAO,IAAI,MAAM,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,MAAM,IAAI;AAC1F,QAAM,OAAO,SAAS,WAAW,IAAI,KAAK,cAAc,MAAM,UAAU,KAAK,CAAC;AAC9E,SAAO;AAAA,IACL,4BAA4B,KAAK;AAAA,IACjC,gEAAgE,IAAI,IAAI,IAAI;AAAA,IAC5E,OAAO,SAAS;AAAA,EAClB,EAAE,KAAK,IAAI;AACb;AAGA,IAAM,WAAW;AAOV,SAAS,kBAAkB,UAAoB,MAAyB,QAAQ,KAAc;AACnG,QAAM,OAAO,IAAI;AAEjB,QAAM,QAAQ,SAAS,OAAO,QAAQ,eAAe,EAAE;AACvD,MAAI,UAAU,UAAa,CAAC,SAAS,KAAK,KAAK,EAAG,QAAO;AACzD,MAAI,SAAS,UAAa,SAAS,MAAM,IAAI,uBAAuB,OAAW,QAAO;AACtF,QAAM,WAAW,WAAW,IAAI,IAAI,aAAa,MAAM,MAAM,IAAI;AACjE,QAAM,OAAO,aAAa,MAAM,SAAS,SAAS,IAAI,IAAI,KAAK;AAC/D,iBAAe,MAAM,GAAG,IAAI,6BAA6B,KAAK;AAAA,GAAM,MAAM;AAC1E,SAAO;AACT;;;ALrLA,SAAS,KAAK,OAAwB;AACpC,MAAI,MAAM,WAAW,OAAW,SAAQ,OAAO,MAAM,MAAM,MAAM;AACjE,MAAI,MAAM,WAAW,OAAW,SAAQ,OAAO,MAAM,MAAM,MAAM;AACjE,UAAQ,WAAW,MAAM;AAC3B;AAGA,SAAS,UAAU,UAAoB,KAA0D;AAC/F,MAAI,SAAS,UAAU,OAAQ,QAAO,EAAE,OAAO,EAAE,MAAM,UAAU,EAAE;AACnE,MAAI,SAAS,UAAU,cAAe,QAAO;AAC7C,MAAI,SAAS,aAAa,UAAa,CAAC,WAAW,SAAS,SAAS,QAAQ,EAAG,QAAO;AACvF,MAAI,SAAS,aAAa,OAAW,QAAO;AAC5C,QAAM,OAAO,UAAU,KAAKC,SAAQ,KAAK,SAAS,QAAQ,CAAC;AAC3D,SAAO,EAAE,OAAO,EAAE,MAAM,SAAS,OAAO,CAAC,IAAI,EAAE,GAAG,KAAK;AACzD;AAEA,eAAe,eAAe,OAAiB,SAA0B,UAAmC;AAC1G,QAAM,MAAMA,SAAQ,SAAS,OAAO,QAAQ,IAAI,CAAC;AAEjD,QAAM,QACJ,MAAM,SAAS,IAAI,EAAE,OAAO,EAAE,MAAM,SAAS,MAAM,GAAG,MAAM,MAAM,KAAK,IAAI,EAAE,IAAI,UAAU,UAAU,GAAG;AAC1G,MAAI,UAAU,OAAW;AACzB,MAAI;AACF,UAAMC,OAAM,MAAM,eAAe;AAAA,MAC/B;AAAA,MACA,OAAO,MAAM;AAAA,MACb,cAAc;AAAA,MACd,GAAI,QAAQ,WAAW,SAAY,CAAC,IAAI,EAAE,YAAY,QAAQ,OAAO;AAAA;AAAA,MAErE,UAAU,MAAM;AAAA,IAClB,CAAC;AACD,SAAK,UAAUA,MAAK,QAAQ,CAAC;AAAA,EAC/B,SAAS,KAAK;AACZ,QAAI,eAAe,eAAe,IAAI,MAAO;AAC7C,SAAK,YAAY,aAAa,GAAG,GAAG,UAAU,MAAM,IAAI,CAAC;AAAA,EAC3D;AACF;AAEO,SAAS,aAAsB;AACpC,SAAO,IAAI,QAAQ,OAAO,EACvB,YAAY,8DAA8D,EAC1E,SAAS,cAAc,4FAA4F,EACnH,OAAO,uBAAuB,6BAA6B,EAC3D;AAAA,IACC,IAAI,OAAO,yBAAyB,gCAAgC,EACjE,QAAQ,aAAa,EACrB,QAAQ,QAAQ;AAAA,EACrB,EACC,OAAO,cAAc,wBAAwB,EAC7C,mBAAmB,wBAAwB,EAC3C,aAAa,EACb;AAAA,IACC;AAAA,IACA;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,EAAE,KAAK,IAAI;AAAA,EACb,EACC,OAAO,OAAO,OAAiB,YAA6B;AAC3D,UAAM,WAAW,MAAM,aAAa;AACpC,QAAI,aAAa,QAAW;AAC1B,YAAM,eAAe,OAAO,SAAS,QAAQ;AAC7C;AAAA,IACF;AACA,QAAI;AACF,YAAMA,OAAM,MAAM,eAAe;AAAA,QAC/B,OAAO,MAAM,SAAS,IAAI,EAAE,MAAM,SAAS,MAAM,IAAI,EAAE,MAAM,MAAM;AAAA,QACnE,GAAI,QAAQ,WAAW,SAAY,CAAC,IAAI,EAAE,YAAY,QAAQ,OAAO;AAAA,QACrE,UAAU;AAAA,MACZ,CAAC;AACD,iBAAW,SAASA,KAAI,QAAQ;AAC9B,YAAI,MAAM,WAAW,SAAS;AAC5B,kBAAQ,OAAO,MAAM,GAAG,YAAY,CAAC,IAAI,MAAM,OAAO,mBAAmB,MAAM,OAAO;AAAA,CAAI;AAAA,QAC5F;AAAA,MACF;AACA,YAAM,QAAQ,YAAY,EAAE,SAAS,CAAC,QAAQ,OAAO,OAAO,QAAQ,OAAO,MAAM,CAAC;AAClF,YAAM,OAAO,OAAOA,MAAK,QAAQ,QAAQ,KAAK;AAC9C,UAAI,KAAK,SAAS,EAAG,SAAQ,OAAO,MAAM,GAAG,IAAI;AAAA,CAAI;AACrD,cAAQ,WAAW,YAAYA,IAAG;AAAA,IACpC,SAAS,KAAK;AACZ,WAAK,GAAG;AAAA,IACV;AAAA,EACF,CAAC;AACL;AAEO,SAAS,cAAuB;AACrC,SAAO,IAAI,QAAQ,QAAQ,EACxB,YAAY,uDAAuD,EACnE,OAAO,uBAAuB,6BAA6B,EAC3D;AAAA,IACC,IAAI,OAAO,yBAAyB,QAAQ,EAAE,QAAQ,cAAc,EAAE,QAAQ,QAAQ;AAAA,EACxF,EACC,mBAAmB,wBAAwB,EAC3C,aAAa,EACb,OAAO,OAAO,YAA8B;AAC3C,UAAM,WAAW,MAAM,aAAa;AACpC,UAAM,eAAe,QAAQ,WAAW,SAAY,CAAC,IAAI,EAAE,YAAY,QAAQ,OAAO;AACtF,QAAI,UAAU,UAAU,gBAAgB;AACtC,UAAI;AACF,cAAM,SAAS,MAAM,UAAU,EAAE,KAAKD,SAAQ,SAAS,OAAO,QAAQ,IAAI,CAAC,GAAG,GAAG,aAAa,CAAC;AAE/F,cAAM,QAAQ,OAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,WAAW,SAAS,IAAI;AAAA;AAAA,EAAO,WAAW,MAAM,CAAC,KAAK;AACjG,gBAAQ,OAAO,MAAM,GAAG,aAAa,QAAQ,QAAQ,CAAC,GAAG,KAAK;AAAA,CAAI;AAClE,0BAAkB,QAAQ;AAAA,MAC5B,QAAQ;AAAA,MAER;AACA;AAAA,IACF;AACA,QAAI;AACF,YAAM,SAAS,MAAM,UAAU,YAAY;AAC3C,cAAQ,OAAO,MAAM,GAAG,aAAa,QAAQ,QAAQ,MAAM,CAAC;AAAA,CAAI;AAAA,IAClE,SAAS,KAAK;AACZ,WAAK,GAAG;AAAA,IACV;AAAA,EACF,CAAC;AACL;","names":["resolve","resolve","resolve","run","resolve","extname","resolve","extname","resolve","resolve","run"]}
@@ -0,0 +1,423 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ renderList,
4
+ runFill,
5
+ runList
6
+ } from "./chunk-5KHIFVD2.js";
7
+ import "./chunk-XYLUCIKQ.js";
8
+ import {
9
+ CALIBRATE_FORMATS,
10
+ REPORT_FORMATS,
11
+ SUMMARY_FORMATS,
12
+ parseFormat,
13
+ runRun
14
+ } from "./chunk-IEQHSCZG.js";
15
+ import "./chunk-7QMCHA4N.js";
16
+ import "./chunk-4TSWU2SU.js";
17
+ import {
18
+ TracevalsError
19
+ } from "./chunk-UKZNLVJW.js";
20
+ import "./chunk-LJ2RDH3F.js";
21
+ import {
22
+ allowExecutionMessage,
23
+ isExecutionGrant
24
+ } from "./chunk-YNHZHSSM.js";
25
+ import "./chunk-GLP5PSXB.js";
26
+ import "./chunk-77AINBYM.js";
27
+ import "./chunk-TU2WUBVZ.js";
28
+ import "./chunk-H2DLH2JI.js";
29
+ import {
30
+ terminalConfirm
31
+ } from "./chunk-CYWHFSRT.js";
32
+ import "./chunk-K3D6FPV6.js";
33
+ import {
34
+ collect,
35
+ configOption
36
+ } from "./chunk-V46OILVC.js";
37
+ import "./chunk-RLR4TKUZ.js";
38
+ import "./chunk-C6OH6CNF.js";
39
+ import "./chunk-JVTNMVYU.js";
40
+ import {
41
+ fail
42
+ } from "./chunk-YEUYKR62.js";
43
+ import {
44
+ colorFor
45
+ } from "./chunk-RNVYGWIC.js";
46
+ import "./chunk-MNH7QO4Z.js";
47
+ import {
48
+ LOCAL_FLAG_HELP,
49
+ notice
50
+ } from "./chunk-Q35YIDBV.js";
51
+ import {
52
+ package_default
53
+ } from "./chunk-UZC7LDAQ.js";
54
+ import "./chunk-OWBRDNRZ.js";
55
+ import "./chunk-G3T47CFV.js";
56
+ import "./chunk-2H7UOFLK.js";
57
+
58
+ // src/tracevals/cli.ts
59
+ import { Command } from "commander";
60
+ var { version } = package_default;
61
+ function buildProgram() {
62
+ const program = new Command();
63
+ program.name("tracevals").description(
64
+ "Deterministic and LLM-as-judge adherence evals for AI agent session traces."
65
+ ).version(version).option("--no-color", "disable colored output").showHelpAfterError("(add --help for usage)").exitOverride();
66
+ function collectGrant(value, previous) {
67
+ if (!isExecutionGrant(value)) fail(new TracevalsError(allowExecutionMessage(value)));
68
+ return [...previous, value];
69
+ }
70
+ function addConfigFlags(cmd) {
71
+ return cmd.option("-c, --config <path>", "Path to manni.config.yaml").option("--no-config", "Ignore any discovered config file");
72
+ }
73
+ function configOptions(opts) {
74
+ const { configPath, noConfig } = configOption(opts.config);
75
+ return {
76
+ ...configPath === void 0 ? {} : { config: configPath },
77
+ ...noConfig === true ? { noConfig } : {}
78
+ };
79
+ }
80
+ function parseFormatArg(name, allowed) {
81
+ return (value) => {
82
+ try {
83
+ return parseFormat(value, allowed, name);
84
+ } catch (e) {
85
+ fail(e);
86
+ }
87
+ };
88
+ }
89
+ const range = (min, max) => Number.isFinite(max) ? `between ${min} and ${max}` : `of at least ${min}`;
90
+ function numeric(name, value, min, max = Number.POSITIVE_INFINITY) {
91
+ if (value === void 0) return;
92
+ if (Number.isFinite(value) && value >= min && value <= max) return;
93
+ throw new TracevalsError(
94
+ `${name} must be a number ${range(min, max)}, got ${value}`
95
+ );
96
+ }
97
+ function whole(name, value, min, max = Number.POSITIVE_INFINITY) {
98
+ if (value === void 0) return;
99
+ if (Number.isInteger(value) && value >= min && value <= max) return;
100
+ throw new TracevalsError(
101
+ `${name} must be a whole number ${range(min, max)}, got ${value}`
102
+ );
103
+ }
104
+ function sharedRunOptions(opts) {
105
+ whole("--runs", opts.runs, 1);
106
+ whole("--limit", opts.limit, 1);
107
+ whole("--max-turns", opts.maxTurns, 1);
108
+ return {
109
+ ...configOptions(opts),
110
+ project: opts.project,
111
+ provider: opts.provider,
112
+ model: opts.model,
113
+ local: opts.local,
114
+ // `undefined` rather than `false` when absent, so a future config
115
+ // `offline:` still decides on a run where the flag was never typed.
116
+ offline: opts.offline ? true : void 0,
117
+ runs: opts.runs,
118
+ deterministicOnly: opts.deterministicOnly,
119
+ noCache: opts.cache === false,
120
+ maxTurns: opts.maxTurns,
121
+ format: opts.format ?? "pretty",
122
+ output: opts.output,
123
+ // Undefined when neither spelling is passed, so the config still decides.
124
+ // Both spellings are declared for precisely that reason: commander
125
+ // defaults a lone `--no-x` to `true`, which makes the config's own value
126
+ // unreachable from the command line.
127
+ failOnReview: opts.failOnReview,
128
+ // Commander's default is `[]`, which is "no flag", not "run nothing": only
129
+ // a list someone typed narrows the run, and `--no-execution` runs none.
130
+ ...opts.execution === false ? { allowExecution: [] } : (opts.allowExecution ?? []).length > 0 ? { allowExecution: opts.allowExecution } : {},
131
+ reportUnusedArtifacts: opts.reportUnusedArtifacts,
132
+ ...opts.require !== void 0 ? { require: opts.require } : {},
133
+ ...opts.allProjects !== void 0 ? { allProjects: opts.allProjects } : {},
134
+ ...opts.newerThan !== void 0 ? { newerThan: opts.newerThan } : {},
135
+ ...opts.limit !== void 0 ? { limit: opts.limit } : {}
136
+ };
137
+ }
138
+ async function executeRun(traces, opts, color) {
139
+ const shared = {
140
+ ...sharedRunOptions(opts),
141
+ color,
142
+ // Run-only, both of them: `--history` is a point in one session's
143
+ // timeline, and a manifest belongs to exactly one session (ADR 01024).
144
+ history: opts.history,
145
+ ...opts.manifest !== void 0 ? { manifest: opts.manifest } : {}
146
+ };
147
+ const selecting = opts.allProjects === true || opts.newerThan !== void 0 || opts.limit !== void 0;
148
+ if (traces.length > 1 || selecting) {
149
+ if (opts.manifest !== void 0) {
150
+ throw new TracevalsError(
151
+ "--manifest names one session's manifest, so it cannot be used with a corpus; drop it and each trace will find its own"
152
+ );
153
+ }
154
+ const { runBatch } = await import("./batch-DFRCLY77.js");
155
+ const { report: report2, rendered: rendered2 } = await runBatch({
156
+ ...shared,
157
+ ...traces.length > 0 ? { traces } : {}
158
+ });
159
+ console.log(rendered2);
160
+ process.exitCode = report2.exitCode;
161
+ return;
162
+ }
163
+ let trace = traces[0];
164
+ if (trace === void 0) {
165
+ if (!process.stdout.isTTY || !process.stdin.isTTY) {
166
+ throw new TracevalsError(
167
+ "no trace given; pass a trace file or run `manni tracevals list`"
168
+ );
169
+ }
170
+ const { pickTrace } = await import("./picker-3XF36MJF.js");
171
+ trace = await pickTrace();
172
+ }
173
+ const { report, rendered } = await runRun({ ...shared, tracePath: trace });
174
+ console.log(rendered);
175
+ process.exitCode = report.exitCode;
176
+ }
177
+ function addRunFlags(cmd, options = {}) {
178
+ const withHistory = options.history !== false;
179
+ const formats = options.formats ?? REPORT_FORMATS;
180
+ const base = addConfigFlags(cmd).option(
181
+ "--project <dir>",
182
+ "artifact-lookup root (overrides the trace's recorded cwd)"
183
+ ).option(
184
+ "--provider <name>",
185
+ "Judge provider: auto (default) | anthropic | openai | claude-cli | llama-cpp"
186
+ ).option(
187
+ "--model <model>",
188
+ "Model override; needs a named provider, from here or config"
189
+ ).option("--local", LOCAL_FLAG_HELP).option("--runs <n>", "ensemble runs per eval", (v) => Number(v)).option("--deterministic-only", "skip LLM-judged evals").option(
190
+ "--offline",
191
+ "never fetch a remote manifest; read external metadata from local manifests"
192
+ ).option("--no-cache", "bypass the judge cache").option(
193
+ "--max-turns <n>",
194
+ "Stop after this many ensemble runs (a cached ensemble costs none)",
195
+ (v) => Number(v)
196
+ ).option(
197
+ "-f, --format <format>",
198
+ `Output format: ${formats.join(" | ")}`,
199
+ parseFormatArg("--format", formats),
200
+ "pretty"
201
+ ).option("-o, --output <file>", "also write the report to a file").option(
202
+ "--report-unused-artifacts",
203
+ "list every skill and agent the session was offered and never used"
204
+ ).option("--fail-on-review", "Exit 1 when any eval lands in the human-review zone (the default)").option("--no-fail-on-review", "Do not fail the run on evals left for human review").option(
205
+ "--allow-execution <kind>",
206
+ "Run only these execution grants (repeatable): frontmatter-commands",
207
+ collectGrant,
208
+ []
209
+ ).option("--no-execution", "Clear every execution grant for this run").option(
210
+ "--require <module>",
211
+ "load a grader plugin; repeatable, and added to config plugins",
212
+ collect,
213
+ []
214
+ ).option("--all-projects", "evaluate every project's traces in the session store").option(
215
+ "--newer-than <duration>",
216
+ "only traces modified within this window, such as 30m, 24h, 7d or 2w"
217
+ ).option("--limit <n>", "maximum traces to evaluate", (v) => Number(v));
218
+ return withHistory ? base.option(
219
+ "--history",
220
+ "append to history and compare with the previous run"
221
+ ) : base;
222
+ }
223
+ addRunFlags(
224
+ // No `isDefault` (proposal 0034): `run` is a verb, so a bare
225
+ // `manni tracevals` prints the help and exits 2, and a trace path with no
226
+ // verb is commander's unknown-command refusal rather than a silent run.
227
+ program.command("run [traces...]").description(
228
+ "Evaluate one or more traces against the skills and instructions they used"
229
+ )
230
+ ).option(
231
+ "--manifest <file>",
232
+ "session manifest to compare artifacts against; without it one is looked for beside the trace and under the project"
233
+ ).action(async (traces, opts, command) => {
234
+ try {
235
+ await executeRun(traces, opts, colorFor(command, process.stdout.isTTY));
236
+ } catch (e) {
237
+ fail(e);
238
+ }
239
+ });
240
+ addRunFlags(
241
+ program.command("calibrate [traces...]").description(
242
+ "Measure judged and graded verdicts against a labels file: false passes, false fails, and review volume"
243
+ ).option(
244
+ "--labels <file>",
245
+ "calibration labels sidecar (default: calibrate.labels)"
246
+ ).option(
247
+ "--sweep",
248
+ "re-score the corpus across the configured grid of zones and ensemble sizes, from cached verdicts"
249
+ ).option(
250
+ "--max-false-pass <n>",
251
+ "exit 1 above this many false passes",
252
+ (v) => Number(v)
253
+ ).option(
254
+ "--max-false-fail <n>",
255
+ "exit 1 above this many false fails",
256
+ (v) => Number(v)
257
+ ).option(
258
+ "--max-review <n>",
259
+ "exit 1 above this many needs-review outcomes",
260
+ (v) => Number(v)
261
+ ),
262
+ { history: false, formats: CALIBRATE_FORMATS }
263
+ ).action(
264
+ async (traces, opts, command) => {
265
+ try {
266
+ const shared = {
267
+ ...sharedRunOptions(opts),
268
+ color: colorFor(command, process.stdout.isTTY)
269
+ };
270
+ whole("--max-false-pass", opts.maxFalsePass, 0);
271
+ whole("--max-false-fail", opts.maxFalseFail, 0);
272
+ whole("--max-review", opts.maxReview, 0);
273
+ const { runCalibrate } = await import("./calibrate-XQILKXS3.js");
274
+ const { report, rendered } = await runCalibrate({
275
+ ...shared,
276
+ ...traces.length > 0 ? { traces } : {},
277
+ ...opts.labels !== void 0 ? { labels: opts.labels } : {},
278
+ ...opts.sweep !== void 0 ? { sweep: opts.sweep } : {},
279
+ ...opts.maxFalsePass !== void 0 ? { maxFalsePass: opts.maxFalsePass } : {},
280
+ ...opts.maxFalseFail !== void 0 ? { maxFalseFail: opts.maxFalseFail } : {},
281
+ ...opts.maxReview !== void 0 ? { maxReview: opts.maxReview } : {}
282
+ });
283
+ console.log(rendered);
284
+ process.exitCode = report.exitCode;
285
+ } catch (e) {
286
+ fail(e);
287
+ }
288
+ }
289
+ );
290
+ addConfigFlags(
291
+ program.command("fill [paths...]").description(
292
+ "Propose evals for skills, agent definitions, and project rules, and write those above the confidence threshold"
293
+ )
294
+ ).option("--project <dir>", "project root to scan (default: current directory)").option("--exclude <glob>", "Glob to exclude (repeatable)", collect, []).option("--dry-run", "report proposals without writing them").option(
295
+ "--confidence <n>",
296
+ "minimum confidence to write (0-1)",
297
+ (v) => parseFloat(v)
298
+ ).option(
299
+ "--max-evals <n>",
300
+ "maximum evals per artifact, including existing ones",
301
+ (v) => Number(v)
302
+ ).option(
303
+ "--max-turns <n>",
304
+ "Stop after this many inference calls (a cached artifact costs none)",
305
+ (v) => Number(v)
306
+ ).option("--no-cache", "bypass the proposal cache").option(
307
+ "--provider <name>",
308
+ "Provider: auto (default) | anthropic | openai | claude-cli | llama-cpp"
309
+ ).option(
310
+ "--model <model>",
311
+ "Model override; needs a named provider, from here or config"
312
+ ).option("--local", LOCAL_FLAG_HELP).option(
313
+ "--offline",
314
+ "never fetch a remote manifest; read external metadata from local manifests"
315
+ ).option(
316
+ "--require <module>",
317
+ "load a grader plugin; repeatable, and added to config plugins",
318
+ collect,
319
+ []
320
+ ).option(
321
+ "-f, --format <format>",
322
+ `Output format: ${SUMMARY_FORMATS.join(" | ")}`,
323
+ parseFormatArg("--format", SUMMARY_FORMATS),
324
+ "pretty"
325
+ ).action(async (paths, opts, command) => {
326
+ try {
327
+ numeric("--confidence", opts.confidence, 0, 1);
328
+ whole("--max-evals", opts.maxEvals, 1);
329
+ whole("--max-turns", opts.maxTurns, 1);
330
+ const { report, rendered } = await runFill({
331
+ ...configOptions(opts),
332
+ ...paths.length > 0 ? { paths } : {},
333
+ ...opts.project !== void 0 ? { project: opts.project } : {},
334
+ ...opts.exclude !== void 0 ? { exclude: opts.exclude } : {},
335
+ ...opts.dryRun !== void 0 ? { dryRun: opts.dryRun } : {},
336
+ ...opts.confidence !== void 0 ? { confidence: opts.confidence } : {},
337
+ ...opts.maxEvals !== void 0 ? { maxEvals: opts.maxEvals } : {},
338
+ ...opts.maxTurns !== void 0 ? { maxTurns: opts.maxTurns } : {},
339
+ ...opts.cache === false ? { noCache: true } : {},
340
+ ...opts.provider !== void 0 ? { provider: opts.provider } : {},
341
+ ...opts.model !== void 0 ? { model: opts.model } : {},
342
+ ...opts.local !== void 0 ? { local: opts.local } : {},
343
+ ...opts.offline === true ? { offline: true } : {},
344
+ ...opts.require !== void 0 ? { require: opts.require } : {},
345
+ // P1 (proposal 0047): offered only on a terminal, where there is
346
+ // someone to answer. Off one the block goes to the artifact and the
347
+ // W1 line says so.
348
+ confirm: terminalConfirm(),
349
+ onNotice: notice,
350
+ onRelocated: (result) => {
351
+ const manifests = result.manifests.map((m) => m.file).join(", ");
352
+ notice(`moved ${String(result.summary.moved)} value(s) into ${manifests}.`);
353
+ },
354
+ color: colorFor(command, process.stdout.isTTY)
355
+ });
356
+ console.log(
357
+ opts.format === "json" ? JSON.stringify(report, null, 2) : rendered
358
+ );
359
+ process.exitCode = report.exitCode;
360
+ } catch (e) {
361
+ fail(e);
362
+ }
363
+ });
364
+ addConfigFlags(
365
+ program.command("capture").description(
366
+ "Record a session manifest: sha256 of every instruction artifact plus the git SHA, read from a Claude Code hook payload on stdin"
367
+ )
368
+ ).option("--project <dir>", "project root to scan (default: the payload's cwd)").option("--session-id <id>", "session id (default: the payload's session_id)").option("-o, --out <file>", "write here instead of the configured directory").option(
369
+ "-f, --format <format>",
370
+ `Output format: ${SUMMARY_FORMATS.join(" | ")}`,
371
+ parseFormatArg("--format", SUMMARY_FORMATS),
372
+ "pretty"
373
+ ).action(async (opts) => {
374
+ try {
375
+ const { runCapture } = await import("./capture-JQMOC3BW.js");
376
+ const result = await runCapture({
377
+ version,
378
+ ...configOptions(opts),
379
+ ...opts.project !== void 0 ? { project: opts.project } : {},
380
+ ...opts.sessionId !== void 0 ? { sessionId: opts.sessionId } : {},
381
+ ...opts.out !== void 0 ? { out: opts.out } : {},
382
+ format: opts.format ?? "pretty"
383
+ });
384
+ if (result.stdout !== "") console.log(result.stdout);
385
+ if (result.stderr !== "") notice(result.stderr);
386
+ process.exitCode = result.exitCode;
387
+ } catch (e) {
388
+ fail(e);
389
+ }
390
+ });
391
+ program.command("list").description("List discoverable traces (Claude Code session files)").option(
392
+ "--project <dir>",
393
+ "project directory to scope to (default: current directory)"
394
+ ).option("--all-projects", "scan every project in the session store").option(
395
+ "--newer-than <duration>",
396
+ "only traces modified within this window, such as 30m, 24h, 7d or 2w"
397
+ ).option("--limit <n>", "maximum traces to list", (v) => Number(v)).option(
398
+ "-f, --format <format>",
399
+ `Output format: ${SUMMARY_FORMATS.join(" | ")}`,
400
+ parseFormatArg("--format", SUMMARY_FORMATS),
401
+ "pretty"
402
+ ).action(async (opts, command) => {
403
+ try {
404
+ whole("--limit", opts.limit, 1);
405
+ const run = await runList({
406
+ project: opts.project,
407
+ allProjects: opts.allProjects,
408
+ ...opts.newerThan !== void 0 ? { newerThan: opts.newerThan } : {},
409
+ limit: opts.limit
410
+ });
411
+ console.log(
412
+ opts.format === "json" ? JSON.stringify(run, null, 2) : renderList(run, { color: colorFor(command, process.stdout.isTTY) })
413
+ );
414
+ } catch (e) {
415
+ fail(e);
416
+ }
417
+ });
418
+ return program;
419
+ }
420
+ export {
421
+ buildProgram
422
+ };
423
+ //# sourceMappingURL=cli-LJLLIQB2.js.map