@hawkeyexl/manni 4.5.0 → 4.6.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 (215) hide show
  1. package/README.md +1 -1
  2. package/dist/batch-OZOACN4G.js +41 -0
  3. package/dist/build-Z5VOVADH.js +32 -0
  4. package/dist/calibrate-TZYT42DR.js +36 -0
  5. package/dist/capture-SL4MNDDP.js +34 -0
  6. package/dist/check-5OMA42Y6.js +26 -0
  7. package/dist/{check-ESNS7ZBC.js → check-OAJWC3WD.js} +7 -5
  8. package/dist/{check-RQIIIURI.js → check-PKY7KTQE.js} +13 -14
  9. package/dist/check-WB2QDHJQ.js +880 -0
  10. package/dist/check-WB2QDHJQ.js.map +1 -0
  11. package/dist/{chunk-F2OVHJNC.js → chunk-2JFPBZJK.js} +11 -11
  12. package/dist/{chunk-CP4ZM43V.js → chunk-2KRB3EG7.js} +2 -2
  13. package/dist/{chunk-QLUMKWQQ.js → chunk-2M6DVNI5.js} +10 -6
  14. package/dist/{chunk-QLUMKWQQ.js.map → chunk-2M6DVNI5.js.map} +1 -1
  15. package/dist/{chunk-HQFVJDEN.js → chunk-3NWX34ZI.js} +19 -19
  16. package/dist/{chunk-TCC737IS.js → chunk-5G53XATW.js} +4 -4
  17. package/dist/{chunk-B7XUEQF3.js → chunk-6KKZXB2O.js} +7 -5
  18. package/dist/{chunk-B7XUEQF3.js.map → chunk-6KKZXB2O.js.map} +1 -1
  19. package/dist/{chunk-SNEHX4VE.js → chunk-733Y2STG.js} +2 -2
  20. package/dist/{chunk-ELZ2IIOF.js → chunk-73TC4DYH.js} +2 -2
  21. package/dist/{chunk-QY3DOZMS.js → chunk-7WRP5FFP.js} +4 -4
  22. package/dist/{chunk-3R5Y3XOL.js → chunk-APKH2T6E.js} +29 -591
  23. package/dist/chunk-APKH2T6E.js.map +1 -0
  24. package/dist/{chunk-FLF6AECQ.js → chunk-B3TS4WRM.js} +17 -15
  25. package/dist/{chunk-FLF6AECQ.js.map → chunk-B3TS4WRM.js.map} +1 -1
  26. package/dist/chunk-BWCWTHYS.js +146 -0
  27. package/dist/chunk-BWCWTHYS.js.map +1 -0
  28. package/dist/{chunk-C6HZ6C5T.js → chunk-C3B2VJNC.js} +2 -2
  29. package/dist/{chunk-NN4ASVTY.js → chunk-C73RSUIC.js} +4 -4
  30. package/dist/chunk-CU57HT2E.js +116 -0
  31. package/dist/chunk-CU57HT2E.js.map +1 -0
  32. package/dist/chunk-CWXZ2MRT.js +222 -0
  33. package/dist/chunk-CWXZ2MRT.js.map +1 -0
  34. package/dist/{chunk-GAZFKZHM.js → chunk-DC5DDJVE.js} +6 -6
  35. package/dist/{chunk-52PDIZKV.js → chunk-ECVQNGTH.js} +3 -3
  36. package/dist/chunk-FLAO4ZS3.js +502 -0
  37. package/dist/chunk-FLAO4ZS3.js.map +1 -0
  38. package/dist/chunk-FQGLRJGX.js +174 -0
  39. package/dist/chunk-FQGLRJGX.js.map +1 -0
  40. package/dist/{chunk-XWFNO5PO.js → chunk-GAJIJKET.js} +3 -3
  41. package/dist/{chunk-QCBICNKC.js → chunk-GREQKO6M.js} +202 -54
  42. package/dist/chunk-GREQKO6M.js.map +1 -0
  43. package/dist/chunk-HX44GB4Z.js +30 -0
  44. package/dist/chunk-HX44GB4Z.js.map +1 -0
  45. package/dist/{chunk-7ZUCEMCY.js → chunk-IY7NYNPZ.js} +9 -11
  46. package/dist/{chunk-7ZUCEMCY.js.map → chunk-IY7NYNPZ.js.map} +1 -1
  47. package/dist/{chunk-527HHQPS.js → chunk-KCOFEWV5.js} +6 -4
  48. package/dist/{chunk-527HHQPS.js.map → chunk-KCOFEWV5.js.map} +1 -1
  49. package/dist/chunk-M2RLHZ4J.js +849 -0
  50. package/dist/chunk-M2RLHZ4J.js.map +1 -0
  51. package/dist/{chunk-K3U5F2QT.js → chunk-M6GSS72T.js} +12 -12
  52. package/dist/{chunk-UK2I3ACY.js → chunk-MHM4QEBV.js} +4 -4
  53. package/dist/{chunk-EL2BZTDL.js → chunk-MOWMCEOJ.js} +13 -11
  54. package/dist/{chunk-EL2BZTDL.js.map → chunk-MOWMCEOJ.js.map} +1 -1
  55. package/dist/{chunk-OIZ3XMKB.js → chunk-MWBJ3KTF.js} +4 -4
  56. package/dist/chunk-N7JSEDSC.js +233 -0
  57. package/dist/chunk-N7JSEDSC.js.map +1 -0
  58. package/dist/{chunk-MZC62HPZ.js → chunk-NBMPHD4I.js} +2 -2
  59. package/dist/{chunk-YA63PVWI.js → chunk-NHHOPZRA.js} +12 -10
  60. package/dist/{chunk-YA63PVWI.js.map → chunk-NHHOPZRA.js.map} +1 -1
  61. package/dist/{chunk-DX32P2DT.js → chunk-NTWW7J76.js} +2 -2
  62. package/dist/{chunk-6XTQDFGP.js → chunk-PCFG7E6B.js} +3 -3
  63. package/dist/{chunk-6XTQDFGP.js.map → chunk-PCFG7E6B.js.map} +1 -1
  64. package/dist/{chunk-SJO2FTPG.js → chunk-PL4UAF4S.js} +73 -1304
  65. package/dist/chunk-PL4UAF4S.js.map +1 -0
  66. package/dist/chunk-QCHVR4ZM.js +286 -0
  67. package/dist/chunk-QCHVR4ZM.js.map +1 -0
  68. package/dist/{chunk-JQU7FHYH.js → chunk-QW77LCOU.js} +10 -10
  69. package/dist/{chunk-IA7BMIPE.js → chunk-SM6NOMJS.js} +2 -2
  70. package/dist/{chunk-DE7JSWXV.js → chunk-SWSTHZBI.js} +8 -6
  71. package/dist/{chunk-DE7JSWXV.js.map → chunk-SWSTHZBI.js.map} +1 -1
  72. package/dist/{chunk-NGK3N6F2.js → chunk-T6SYGLWR.js} +3 -3
  73. package/dist/chunk-TH4JVQPF.js +133 -0
  74. package/dist/chunk-TH4JVQPF.js.map +1 -0
  75. package/dist/{chunk-TVIX653Q.js → chunk-TLXE7LYK.js} +4 -4
  76. package/dist/{chunk-HVFR66GQ.js → chunk-TUAAR3MM.js} +3280 -283
  77. package/dist/chunk-TUAAR3MM.js.map +1 -0
  78. package/dist/{chunk-TA42STP7.js → chunk-UAKNZVCD.js} +4 -4
  79. package/dist/{chunk-C3KI45RF.js → chunk-UJSGS2Y5.js} +4 -4
  80. package/dist/{chunk-ZX43SRZR.js → chunk-UWQ2UVHE.js} +8 -6
  81. package/dist/{chunk-ZX43SRZR.js.map → chunk-UWQ2UVHE.js.map} +1 -1
  82. package/dist/chunk-WQWKYAAK.js +86 -0
  83. package/dist/chunk-WQWKYAAK.js.map +1 -0
  84. package/dist/{chunk-LJ2RDH3F.js → chunk-XG6PVB5S.js} +1 -23
  85. package/dist/chunk-XG6PVB5S.js.map +1 -0
  86. package/dist/{chunk-Q35YIDBV.js → chunk-XKBEHKWO.js} +29 -264
  87. package/dist/chunk-XKBEHKWO.js.map +1 -0
  88. package/dist/chunk-XPEWUK7J.js +532 -0
  89. package/dist/chunk-XPEWUK7J.js.map +1 -0
  90. package/dist/{chunk-BOIF2XGG.js → chunk-XXDXIIQ4.js} +2 -2
  91. package/dist/chunk-YLK2J5YK.js +610 -0
  92. package/dist/chunk-YLK2J5YK.js.map +1 -0
  93. package/dist/{chunk-7OQAU4EA.js → chunk-Z4IZGEM3.js} +16 -12
  94. package/dist/{chunk-7OQAU4EA.js.map → chunk-Z4IZGEM3.js.map} +1 -1
  95. package/dist/{cli-E3H6ZP4I.js → cli-6EWVMEN6.js} +5 -3
  96. package/dist/{cli-E3H6ZP4I.js.map → cli-6EWVMEN6.js.map} +1 -1
  97. package/dist/{cli-MHTYPVOD.js → cli-6H7HVDMQ.js} +113 -20
  98. package/dist/{cli-MHTYPVOD.js.map → cli-6H7HVDMQ.js.map} +1 -1
  99. package/dist/{cli-HUIMNJT6.js → cli-EPVZHAZS.js} +19 -20
  100. package/dist/{cli-HUIMNJT6.js.map → cli-EPVZHAZS.js.map} +1 -1
  101. package/dist/{cli-6PGVHP7Y.js → cli-LUCSGTVI.js} +17 -19
  102. package/dist/{cli-6PGVHP7Y.js.map → cli-LUCSGTVI.js.map} +1 -1
  103. package/dist/{cli-PRZHQ3QB.js → cli-NIG4N3XM.js} +14 -15
  104. package/dist/{cli-PRZHQ3QB.js.map → cli-NIG4N3XM.js.map} +1 -1
  105. package/dist/{cli-TYGOHJOJ.js → cli-PSKNB66T.js} +225 -58
  106. package/dist/cli-PSKNB66T.js.map +1 -0
  107. package/dist/{cli-QKIJOXGW.js → cli-UO4NHIB3.js} +17 -17
  108. package/dist/{cli-AAG3N4NB.js → cli-UQ7A3YA2.js} +17 -18
  109. package/dist/{cli-AAG3N4NB.js.map → cli-UQ7A3YA2.js.map} +1 -1
  110. package/dist/{cli-YW6VWBHX.js → cli-YHYDLQAF.js} +10 -10
  111. package/dist/cli.js +11 -11
  112. package/dist/config-P4HDNTYD.js +26 -0
  113. package/dist/conformance-ZFCMKM6M.js +18 -0
  114. package/dist/docmeta.js +9 -9
  115. package/dist/github-7ZCH5PSO.js +26 -0
  116. package/dist/github-POT6724K.js +31 -0
  117. package/dist/host-6GURH5HE.js +23 -0
  118. package/dist/index.d.ts +72 -4
  119. package/dist/index.js +176 -166
  120. package/dist/index.js.map +1 -1
  121. package/dist/{json-4DCKDGUV.js → json-KT2K62L5.js} +12 -13
  122. package/dist/lint-5AQ5C2BV.js +29 -0
  123. package/dist/list-5JZKX2NK.js +28 -0
  124. package/dist/list-SWPFXQMU.js +30 -0
  125. package/dist/{page-QEDB7EVU.js → page-UPSXRP75.js} +11 -12
  126. package/dist/prepare-6GNEWCNH.js +155 -0
  127. package/dist/prepare-6GNEWCNH.js.map +1 -0
  128. package/dist/{pretty-SQX33UM2.js → pretty-Q6FQAOK4.js} +13 -14
  129. package/dist/{pretty-5DGEBZSV.js → pretty-SQRPFPSQ.js} +12 -13
  130. package/dist/provider-AMGRDY6V.js +34 -0
  131. package/dist/release-IECYCLTD.js +36 -0
  132. package/dist/release-IECYCLTD.js.map +1 -0
  133. package/dist/{reporters-OHSI3RMV.js → reporters-45MMC2ID.js} +11 -12
  134. package/dist/{reporters-YELDDYJD.js → reporters-XUV4MM64.js} +7 -5
  135. package/dist/reporters-XUV4MM64.js.map +1 -0
  136. package/dist/run-KMWY2IAN.js +32 -0
  137. package/dist/run-KMWY2IAN.js.map +1 -0
  138. package/dist/{term-2WMDZ4PY.js → term-PCJUCWNF.js} +16 -17
  139. package/dist/{term-2WMDZ4PY.js.map → term-PCJUCWNF.js.map} +1 -1
  140. package/dist/validate-IMNCZNWG.js +17 -0
  141. package/dist/validate-IMNCZNWG.js.map +1 -0
  142. package/package.json +2 -2
  143. package/plugin/manni/.claude-plugin/plugin.json +1 -1
  144. package/plugin/manni/hooks/hooks.json +47 -0
  145. package/dist/batch-GOE3UXOD.js +0 -36
  146. package/dist/build-M7BMEHL2.js +0 -33
  147. package/dist/calibrate-6RRAILUY.js +0 -31
  148. package/dist/capture-RJPQ6B4N.js +0 -32
  149. package/dist/check-BQD64X3N.js +0 -27
  150. package/dist/chunk-3R5Y3XOL.js.map +0 -1
  151. package/dist/chunk-3YHAYXBC.js +0 -164
  152. package/dist/chunk-3YHAYXBC.js.map +0 -1
  153. package/dist/chunk-HVFR66GQ.js.map +0 -1
  154. package/dist/chunk-LJ2RDH3F.js.map +0 -1
  155. package/dist/chunk-NAZRLJAK.js +0 -3090
  156. package/dist/chunk-NAZRLJAK.js.map +0 -1
  157. package/dist/chunk-Q35YIDBV.js.map +0 -1
  158. package/dist/chunk-QCBICNKC.js.map +0 -1
  159. package/dist/chunk-SJO2FTPG.js.map +0 -1
  160. package/dist/chunk-TU2WUBVZ.js +0 -2
  161. package/dist/cli-TYGOHJOJ.js.map +0 -1
  162. package/dist/github-3WMSTNTK.js +0 -32
  163. package/dist/github-OXSJQ4PS.js +0 -27
  164. package/dist/lint-YDHVVZHT.js +0 -30
  165. package/dist/list-3ZO2NIYO.js +0 -31
  166. package/dist/list-EJH6VAOW.js +0 -29
  167. package/dist/run-IP6NZHAG.js +0 -33
  168. package/dist/validate-G6HH3YXL.js +0 -16
  169. /package/dist/{batch-GOE3UXOD.js.map → batch-OZOACN4G.js.map} +0 -0
  170. /package/dist/{build-M7BMEHL2.js.map → build-Z5VOVADH.js.map} +0 -0
  171. /package/dist/{calibrate-6RRAILUY.js.map → calibrate-TZYT42DR.js.map} +0 -0
  172. /package/dist/{capture-RJPQ6B4N.js.map → capture-SL4MNDDP.js.map} +0 -0
  173. /package/dist/{check-BQD64X3N.js.map → check-5OMA42Y6.js.map} +0 -0
  174. /package/dist/{check-ESNS7ZBC.js.map → check-OAJWC3WD.js.map} +0 -0
  175. /package/dist/{check-RQIIIURI.js.map → check-PKY7KTQE.js.map} +0 -0
  176. /package/dist/{chunk-F2OVHJNC.js.map → chunk-2JFPBZJK.js.map} +0 -0
  177. /package/dist/{chunk-CP4ZM43V.js.map → chunk-2KRB3EG7.js.map} +0 -0
  178. /package/dist/{chunk-HQFVJDEN.js.map → chunk-3NWX34ZI.js.map} +0 -0
  179. /package/dist/{chunk-TCC737IS.js.map → chunk-5G53XATW.js.map} +0 -0
  180. /package/dist/{chunk-SNEHX4VE.js.map → chunk-733Y2STG.js.map} +0 -0
  181. /package/dist/{chunk-ELZ2IIOF.js.map → chunk-73TC4DYH.js.map} +0 -0
  182. /package/dist/{chunk-QY3DOZMS.js.map → chunk-7WRP5FFP.js.map} +0 -0
  183. /package/dist/{chunk-C6HZ6C5T.js.map → chunk-C3B2VJNC.js.map} +0 -0
  184. /package/dist/{chunk-NN4ASVTY.js.map → chunk-C73RSUIC.js.map} +0 -0
  185. /package/dist/{chunk-GAZFKZHM.js.map → chunk-DC5DDJVE.js.map} +0 -0
  186. /package/dist/{chunk-52PDIZKV.js.map → chunk-ECVQNGTH.js.map} +0 -0
  187. /package/dist/{chunk-XWFNO5PO.js.map → chunk-GAJIJKET.js.map} +0 -0
  188. /package/dist/{chunk-K3U5F2QT.js.map → chunk-M6GSS72T.js.map} +0 -0
  189. /package/dist/{chunk-UK2I3ACY.js.map → chunk-MHM4QEBV.js.map} +0 -0
  190. /package/dist/{chunk-OIZ3XMKB.js.map → chunk-MWBJ3KTF.js.map} +0 -0
  191. /package/dist/{chunk-MZC62HPZ.js.map → chunk-NBMPHD4I.js.map} +0 -0
  192. /package/dist/{chunk-DX32P2DT.js.map → chunk-NTWW7J76.js.map} +0 -0
  193. /package/dist/{chunk-JQU7FHYH.js.map → chunk-QW77LCOU.js.map} +0 -0
  194. /package/dist/{chunk-IA7BMIPE.js.map → chunk-SM6NOMJS.js.map} +0 -0
  195. /package/dist/{chunk-NGK3N6F2.js.map → chunk-T6SYGLWR.js.map} +0 -0
  196. /package/dist/{chunk-TVIX653Q.js.map → chunk-TLXE7LYK.js.map} +0 -0
  197. /package/dist/{chunk-TA42STP7.js.map → chunk-UAKNZVCD.js.map} +0 -0
  198. /package/dist/{chunk-C3KI45RF.js.map → chunk-UJSGS2Y5.js.map} +0 -0
  199. /package/dist/{chunk-BOIF2XGG.js.map → chunk-XXDXIIQ4.js.map} +0 -0
  200. /package/dist/{cli-QKIJOXGW.js.map → cli-UO4NHIB3.js.map} +0 -0
  201. /package/dist/{chunk-TU2WUBVZ.js.map → cli-YHYDLQAF.js.map} +0 -0
  202. /package/dist/{cli-YW6VWBHX.js.map → config-P4HDNTYD.js.map} +0 -0
  203. /package/dist/{github-3WMSTNTK.js.map → conformance-ZFCMKM6M.js.map} +0 -0
  204. /package/dist/{github-OXSJQ4PS.js.map → github-7ZCH5PSO.js.map} +0 -0
  205. /package/dist/{json-4DCKDGUV.js.map → github-POT6724K.js.map} +0 -0
  206. /package/dist/{lint-YDHVVZHT.js.map → host-6GURH5HE.js.map} +0 -0
  207. /package/dist/{list-3ZO2NIYO.js.map → json-KT2K62L5.js.map} +0 -0
  208. /package/dist/{list-EJH6VAOW.js.map → lint-5AQ5C2BV.js.map} +0 -0
  209. /package/dist/{page-QEDB7EVU.js.map → list-5JZKX2NK.js.map} +0 -0
  210. /package/dist/{pretty-5DGEBZSV.js.map → list-SWPFXQMU.js.map} +0 -0
  211. /package/dist/{pretty-SQX33UM2.js.map → page-UPSXRP75.js.map} +0 -0
  212. /package/dist/{reporters-OHSI3RMV.js.map → pretty-Q6FQAOK4.js.map} +0 -0
  213. /package/dist/{reporters-YELDDYJD.js.map → pretty-SQRPFPSQ.js.map} +0 -0
  214. /package/dist/{run-IP6NZHAG.js.map → provider-AMGRDY6V.js.map} +0 -0
  215. /package/dist/{validate-G6HH3YXL.js.map → reporters-45MMC2ID.js.map} +0 -0
@@ -0,0 +1,174 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/tracevals/graders/glob.ts
4
+ var literal = (ch) => ch.replace(/[.+^${}()|[\]\\]/g, "\\$&");
5
+ var compiled = /* @__PURE__ */ new Map();
6
+ function globToRegExp(glob) {
7
+ const cached = compiled.get(glob);
8
+ if (cached !== void 0) return cached;
9
+ const built = compile(glob);
10
+ compiled.set(glob, built);
11
+ return built;
12
+ }
13
+ function compile(glob) {
14
+ const spec = glob.replace(/\\/g, "/").toLowerCase().replace(/(?:\*\*\/)+/g, "**/");
15
+ let out = "";
16
+ for (let i = 0; i < spec.length; i += 1) {
17
+ const ch = spec[i];
18
+ if (ch === "?") {
19
+ out += "[^/]";
20
+ continue;
21
+ }
22
+ if (ch !== "*") {
23
+ out += literal(ch);
24
+ continue;
25
+ }
26
+ if (spec[i + 1] !== "*") {
27
+ out += "[^/]*";
28
+ continue;
29
+ }
30
+ i += 1;
31
+ if (spec[i + 1] === "/") {
32
+ i += 1;
33
+ if (out !== "") out += "(?:.*/)?";
34
+ } else if (out.endsWith("/")) {
35
+ out = `${out.slice(0, -1)}(?:/.*)?`;
36
+ } else {
37
+ out += ".*";
38
+ }
39
+ }
40
+ return new RegExp(`^(?:.*/)?${out}$`);
41
+ }
42
+ function normalizePath(path) {
43
+ return path.replace(/\\/g, "/").toLowerCase();
44
+ }
45
+ function matchesGlob(path, glob) {
46
+ return globToRegExp(glob).test(normalizePath(path));
47
+ }
48
+
49
+ // src/tracevals/graders/when.ts
50
+ var stringValue = (kind) => (value) => typeof value === "string" && value.length > 0 ? void 0 : `options.when.${kind} must be a string`;
51
+ var compiled2 = /* @__PURE__ */ new Map();
52
+ function compiledRe(pattern) {
53
+ const cached = compiled2.get(pattern);
54
+ if (cached !== void 0) return cached;
55
+ const built = new RegExp(pattern);
56
+ compiled2.set(pattern, built);
57
+ return built;
58
+ }
59
+ var CONDITIONS = {
60
+ "file-access": {
61
+ validate: stringValue("file-access"),
62
+ test: (value, window) => window.fileAccesses.some((a) => matchesGlob(a.path, value)),
63
+ reason: (value) => `no file matching "${value}" was accessed`
64
+ },
65
+ "tool-used": {
66
+ validate: stringValue("tool-used"),
67
+ test: (value, window) => window.toolCalls.some((c) => c.name === value),
68
+ reason: (value) => `the ${value} tool was never used`
69
+ },
70
+ "prompt-matches": {
71
+ validate: (value) => {
72
+ const shape = stringValue("prompt-matches")(value);
73
+ if (shape !== void 0) return shape;
74
+ try {
75
+ new RegExp(value);
76
+ } catch (err) {
77
+ return `options.when.prompt-matches is not a valid regular expression: ${err.message}`;
78
+ }
79
+ return void 0;
80
+ },
81
+ test: (value, window) => {
82
+ const re = compiledRe(value);
83
+ return window.userMessages.some((text) => re.test(text));
84
+ },
85
+ reason: (value) => `no prompt matched /${value}/`
86
+ },
87
+ "command-matches": {
88
+ validate: (value) => {
89
+ const shape = stringValue("command-matches")(value);
90
+ if (shape !== void 0) return shape;
91
+ try {
92
+ new RegExp(value);
93
+ } catch (err) {
94
+ return `options.when.command-matches is not a valid regular expression: ${err.message}`;
95
+ }
96
+ return void 0;
97
+ },
98
+ test: (value, window) => {
99
+ const re = compiledRe(value);
100
+ return window.toolCalls.some(
101
+ (c) => c.name === "Bash" && typeof c.input.command === "string" && re.test(c.input.command)
102
+ );
103
+ },
104
+ reason: (value) => `no Bash command matched /${value}/`
105
+ },
106
+ "turn-count-above": {
107
+ validate: (value) => {
108
+ if (typeof value !== "number" || !Number.isInteger(value)) {
109
+ return "options.when.turn-count-above must be a whole number";
110
+ }
111
+ if (value < 0) return "options.when.turn-count-above must be at least 0";
112
+ return void 0;
113
+ },
114
+ test: (value, window) => window.turnCount > value,
115
+ reason: (value, window) => `${window.turnCount} turn(s) is not more than ${value}`
116
+ }
117
+ };
118
+ var WHEN_CONDITIONS = Object.keys(
119
+ CONDITIONS
120
+ );
121
+ function validateWhen(options) {
122
+ const when = options.when;
123
+ if (when === void 0) return void 0;
124
+ if (typeof when !== "object" || when === null || Array.isArray(when)) {
125
+ return "options.when must be an object of conditions";
126
+ }
127
+ const conditions = when;
128
+ const keys = Object.keys(conditions);
129
+ if (keys.length === 0) {
130
+ return `options.when needs at least one of: ${WHEN_CONDITIONS.join(", ")}`;
131
+ }
132
+ for (const key of keys) {
133
+ const condition = CONDITIONS[key];
134
+ if (condition === void 0) {
135
+ return `options.when.${key} is not a known condition; expected one of: ${WHEN_CONDITIONS.join(", ")}`;
136
+ }
137
+ const invalid = condition.validate(conditions[key]);
138
+ if (invalid !== void 0) return invalid;
139
+ }
140
+ return void 0;
141
+ }
142
+ function evaluateWhen(options, window) {
143
+ const when = options.when;
144
+ if (when === void 0) return { armed: true };
145
+ for (const name of WHEN_CONDITIONS) {
146
+ const value = when[name];
147
+ if (value === void 0) continue;
148
+ const condition = CONDITIONS[name];
149
+ if (condition.test(value, window)) continue;
150
+ return {
151
+ armed: false,
152
+ reason: `trigger not met (${window.label}): ${condition.reason(value, window)}`
153
+ };
154
+ }
155
+ return { armed: true };
156
+ }
157
+ function rejectWhen(kind, options) {
158
+ if (options.when === void 0) return void 0;
159
+ return `options.when is not supported by the ${kind} grader, which grades the whole session rather than a window`;
160
+ }
161
+ function skippedTrigger(trigger) {
162
+ return { findings: [], skipped: trigger.reason ?? "trigger not met" };
163
+ }
164
+
165
+ export {
166
+ globToRegExp,
167
+ matchesGlob,
168
+ WHEN_CONDITIONS,
169
+ validateWhen,
170
+ evaluateWhen,
171
+ rejectWhen,
172
+ skippedTrigger
173
+ };
174
+ //# sourceMappingURL=chunk-FQGLRJGX.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tracevals/graders/glob.ts","../src/tracevals/graders/when.ts"],"sourcesContent":["/**\n * A small path glob, for grader options that name a set of files rather than\n * one (ADR 01016).\n *\n * Deliberately not a dependency: the syntax needed here is `**`, `*`, and `?`\n * over already-normalized paths, and a matcher that small is easier to pin than\n * to pick. Matching follows the same rule as the `file-access` grader's\n * suffix compare — separators normalized, case folded, anchored at a path\n * segment boundary — so `docs/**` reads the same whatever the checkout root is.\n * `file-access` reaches that rule by compiling its literal path through here,\n * so the two cannot drift.\n *\n * **The pattern is untrusted input.** It comes from the *evaluated* project's\n * front matter and is tested against every file access in a window, so a\n * pattern that compiles to nested optional-greedy groups is a denial of service\n * on the runner rather than a slow match. Two things keep that impossible: a\n * run of double-star segments collapses to one, so the optional greedy group\n * never nests, and compilation is memoised per pattern string.\n */\n\n/** Escapes every regex metacharacter; `*` and `?` are handled by the caller. */\nconst literal = (ch: string): string => ch.replace(/[.+^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n/**\n * Compiled patterns, keyed by the pattern string. Bounded because the key\n * space is: a run grades a fixed set of evals, each carrying a fixed set of\n * globs, and the compiled form depends on nothing else.\n */\nconst compiled = new Map<string, RegExp>();\n\nexport function globToRegExp(glob: string): RegExp {\n const cached = compiled.get(glob);\n if (cached !== undefined) return cached;\n const built = compile(glob);\n compiled.set(glob, built);\n return built;\n}\n\nfunction compile(glob: string): RegExp {\n // A run of `**/` means exactly what one does — \"any number of segments\" —\n // so collapsing it here is a normalization, not an approximation. Left\n // uncollapsed, each repeat added another optional greedy group over the same\n // input and the cost of a failed match grew multiplicatively.\n const spec = glob\n .replace(/\\\\/g, \"/\")\n .toLowerCase()\n .replace(/(?:\\*\\*\\/)+/g, \"**/\");\n let out = \"\";\n for (let i = 0; i < spec.length; i += 1) {\n const ch = spec[i] as string;\n if (ch === \"?\") {\n out += \"[^/]\";\n continue;\n }\n if (ch !== \"*\") {\n out += literal(ch);\n continue;\n }\n if (spec[i + 1] !== \"*\") {\n out += \"[^/]*\";\n continue;\n }\n // `**` spans separators, and must allow *zero* segments: `docs/**` has to\n // match `docs` itself, and `docs/**/x` has to match `docs/x`. Both cases\n // absorb one adjacent separator rather than requiring it.\n i += 1;\n if (spec[i + 1] === \"/\") {\n i += 1;\n // A leading `**/` is already covered by the unconditional ancestor\n // prefix below, so emitting a second optional group here would give the\n // engine two interchangeable ways to consume the same segments — the\n // shape that turns a failed match exponential.\n if (out !== \"\") out += \"(?:.*/)?\";\n } else if (out.endsWith(\"/\")) {\n out = `${out.slice(0, -1)}(?:/.*)?`;\n } else {\n out += \".*\";\n }\n }\n // Trace paths are absolute and machine-specific, so a spec matches any\n // ancestor prefix — but only whole segments, so `docs/**` does not match\n // `docsite/`.\n return new RegExp(`^(?:.*/)?${out}$`);\n}\n\n/** Separators normalized and case folded, the one way both matchers see paths. */\nexport function normalizePath(path: string): string {\n return path.replace(/\\\\/g, \"/\").toLowerCase();\n}\n\n/** True when `path` matches `glob`, both normalized the same way. */\nexport function matchesGlob(path: string, glob: string): boolean {\n return globToRegExp(glob).test(normalizePath(path));\n}\n","/**\n * Conditional triggers (ADR 01016): `options.when` arms an eval only for the\n * sessions it is about.\n *\n * The point is to make the *absence* of an artifact checkable. You cannot hang\n * an eval on a skill that never loaded — nothing resolves it, so nothing plans\n * it — but you can hang it on `CLAUDE.md`, which resolves for every session.\n * `when` is what lets that always-planned eval stay quiet on the sessions it\n * has nothing to say about.\n *\n * **A trigger that does not fire is `skipped`, never `pass`.** A check that\n * never armed has not been satisfied, and reporting it as a pass would make a\n * green report out of an eval that never ran — the same reasoning that makes an\n * empty window a skip (ADR 01015).\n *\n * **`when` is a general trigger, not one grader's feature.** Every windowed\n * grader routes its options through `validateWhen` and its window through\n * `evaluateWhen`, because `options` is an open bag: a grader that merely\n * ignored an unrecognised `when` would leave the eval armed on every session,\n * which is the exact failure this module exists to prevent. `cost` and\n * `json-output` are the abstainers, and they say so: both grade the whole\n * session rather than a window (ADR 01015), so there is nothing to evaluate a\n * predicate over, and `rejectWhen` turns the option into a loud error.\n *\n * Predicates are pure trace facts, evaluated over the artifact's window, and\n * every listed one must hold.\n *\n * `options` is an open object by schema decree — \"validated by the grader at\n * run time — a grader's options evolve on the grader's schedule\" — so this\n * costs no schema change and no upstream docmeta proposal (ADR 01010).\n */\nimport { matchesGlob } from \"./glob.js\";\nimport type { TraceWindow } from \"./util.js\";\nimport type { Options } from \"./util.js\";\n\n/**\n * One condition, defined once.\n *\n * The three facets used to live in three unlinked places — the name list, the\n * validator's type grouping, and the evaluator's if-chain — so adding a\n * condition meant three coordinated edits, and an incomplete one failed\n * *silently in the arming direction*: an unvalidated key would be rejected as\n * unknown, but an unevaluated one would simply never constrain anything.\n * Keeping them together makes an incomplete condition a type error.\n */\ninterface Condition {\n /** Rejects a malformed value without a trace, for `fill` (ADR 01004). */\n validate(value: unknown): string | undefined;\n /** True when the condition holds over the window. */\n test(value: unknown, window: TraceWindow): boolean;\n /** The half of the reason that names what was missing. */\n reason(value: unknown, window: TraceWindow): string;\n}\n\nconst stringValue =\n (kind: string) =>\n (value: unknown): string | undefined =>\n typeof value === \"string\" && value.length > 0\n ? undefined\n : `options.when.${kind} must be a string`;\n\n/**\n * Compiled once per pattern, as `globToRegExp` does. The pattern is fixed by\n * the artifact, so rebuilding it for every eval on every trace of a batch is\n * work with no new answer. No `g` flag here, so a shared instance carries no\n * `lastIndex` between calls.\n */\nconst compiled = new Map<string, RegExp>();\n\nfunction compiledRe(pattern: string): RegExp {\n const cached = compiled.get(pattern);\n if (cached !== undefined) return cached;\n const built = new RegExp(pattern);\n compiled.set(pattern, built);\n return built;\n}\n\nconst CONDITIONS = {\n \"file-access\": {\n validate: stringValue(\"file-access\"),\n test: (value, window) =>\n window.fileAccesses.some((a) => matchesGlob(a.path, value as string)),\n reason: (value) => `no file matching \"${value as string}\" was accessed`,\n },\n \"tool-used\": {\n validate: stringValue(\"tool-used\"),\n test: (value, window) => window.toolCalls.some((c) => c.name === value),\n reason: (value) => `the ${value as string} tool was never used`,\n },\n \"prompt-matches\": {\n validate: (value) => {\n const shape = stringValue(\"prompt-matches\")(value);\n if (shape !== undefined) return shape;\n try {\n new RegExp(value as string);\n } catch (err) {\n return `options.when.prompt-matches is not a valid regular expression: ${(err as Error).message}`;\n }\n return undefined;\n },\n test: (value, window) => {\n const re = compiledRe(value as string);\n return window.userMessages.some((text) => re.test(text));\n },\n reason: (value) => `no prompt matched /${value as string}/`,\n },\n \"command-matches\": {\n validate: (value) => {\n const shape = stringValue(\"command-matches\")(value);\n if (shape !== undefined) return shape;\n try {\n new RegExp(value as string);\n } catch (err) {\n return `options.when.command-matches is not a valid regular expression: ${(err as Error).message}`;\n }\n return undefined;\n },\n test: (value, window) => {\n const re = compiledRe(value as string);\n return window.toolCalls.some(\n (c) =>\n c.name === \"Bash\" &&\n typeof c.input.command === \"string\" &&\n re.test(c.input.command),\n );\n },\n reason: (value) => `no Bash command matched /${value as string}/`,\n },\n \"turn-count-above\": {\n validate: (value) => {\n if (typeof value !== \"number\" || !Number.isInteger(value)) {\n return \"options.when.turn-count-above must be a whole number\";\n }\n if (value < 0) return \"options.when.turn-count-above must be at least 0\";\n return undefined;\n },\n test: (value, window) => window.turnCount > (value as number),\n reason: (value, window) =>\n `${window.turnCount} turn(s) is not more than ${value as number}`,\n },\n} satisfies Record<string, Condition>;\n\n/** Every recognised condition. Unknown keys are an error, never ignored. */\nexport const WHEN_CONDITIONS = Object.keys(\n CONDITIONS,\n) as readonly WhenCondition[];\n\nexport type WhenCondition = keyof typeof CONDITIONS;\n\n/** What a trigger decided, and — when it did not fire — why. */\nexport interface TriggerResult {\n armed: boolean;\n /** Reason phrase for the skip; set only when `armed` is false. */\n reason?: string;\n}\n\n/**\n * Validate `options.when` without a trace, so `fill` can ground-check a\n * proposal before writing it (ADR 01004).\n *\n * An unrecognised condition is rejected rather than dropped. A silently\n * ignored `file-acess` would leave the eval armed on every session — the loud\n * failure is the safe one, and it mirrors how `metadata.eval*` reserves its\n * own prefix in `src/evals/extract.ts`.\n */\nexport function validateWhen(options: Options): string | undefined {\n const when = options.when;\n if (when === undefined) return undefined;\n if (typeof when !== \"object\" || when === null || Array.isArray(when)) {\n return \"options.when must be an object of conditions\";\n }\n const conditions = when as Record<string, unknown>;\n const keys = Object.keys(conditions);\n if (keys.length === 0) {\n // A trigger with no conditions arms on every session, which is the same as\n // having no trigger — but reads like a scoped check.\n return `options.when needs at least one of: ${WHEN_CONDITIONS.join(\", \")}`;\n }\n for (const key of keys) {\n const condition = (CONDITIONS as Record<string, Condition>)[key];\n if (condition === undefined) {\n return `options.when.${key} is not a known condition; expected one of: ${WHEN_CONDITIONS.join(\", \")}`;\n }\n const invalid = condition.validate(conditions[key]);\n if (invalid !== undefined) return invalid;\n }\n return undefined;\n}\n\n/**\n * Decide whether the trigger fires over a window. Conjunctive: the first\n * condition that fails names itself in the reason, so a skipped eval says\n * which half of its trigger was missing rather than only that it was.\n *\n * Evaluation walks `WHEN_CONDITIONS`, not the caller's key order, so the\n * reason a skip carries is stable across two spellings of the same trigger.\n */\nexport function evaluateWhen(options: Options, window: TraceWindow): TriggerResult {\n const when = options.when as Record<string, unknown> | undefined;\n if (when === undefined) return { armed: true };\n\n for (const name of WHEN_CONDITIONS) {\n const value = when[name];\n if (value === undefined) continue;\n const condition = CONDITIONS[name] as Condition;\n if (condition.test(value, window)) continue;\n return {\n armed: false,\n reason: `trigger not met (${window.label}): ${condition.reason(value, window)}`,\n };\n }\n\n return { armed: true };\n}\n\n/**\n * Reject `when` outright, for a grader that has no window to evaluate it over.\n *\n * Silence is the one answer not available. `options` is an open bag, so a\n * `when` a grader neither evaluates nor rejects validates clean and is\n * ignored — and an ignored trigger is an eval left armed on every session,\n * which is precisely the outcome its author wrote `when` to avoid. `cost` is\n * unwindowed by design (ADR 01015) and `json-output` reads the session's final\n * text; for both, the honest answer is that the option does not apply.\n */\nexport function rejectWhen(kind: string, options: Options): string | undefined {\n if (options.when === undefined) return undefined;\n return (\n `options.when is not supported by the ${kind} grader, ` +\n \"which grades the whole session rather than a window\"\n );\n}\n\n/**\n * The skip a grader returns for an unfired trigger. One helper rather than one\n * per grader, so every grader's wording — and the fact that it is a skip and\n * not a pass — comes from a single place.\n */\nexport function skippedTrigger(trigger: TriggerResult): {\n findings: never[];\n skipped: string;\n} {\n return { findings: [], skipped: trigger.reason ?? \"trigger not met\" };\n}\n"],"mappings":"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","names":["compiled"]}
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  resultFor,
4
4
  splitBaselined
5
- } from "./chunk-NGK3N6F2.js";
5
+ } from "./chunk-T6SYGLWR.js";
6
6
  import {
7
7
  errorSite
8
- } from "./chunk-TA42STP7.js";
8
+ } from "./chunk-UAKNZVCD.js";
9
9
  import {
10
10
  escapeWorkflowCommandMessage,
11
11
  escapeWorkflowCommandProperty
@@ -51,4 +51,4 @@ export {
51
51
  findingMessage,
52
52
  renderCheckGithub
53
53
  };
54
- //# sourceMappingURL=chunk-XWFNO5PO.js.map
54
+ //# sourceMappingURL=chunk-GAJIJKET.js.map
@@ -1,58 +1,39 @@
1
1
  #!/usr/bin/env node
2
- import {
3
- externalWriteWarning,
4
- externalWriteWarnings,
5
- manifestKeyLine,
6
- mergeMetaProvenance,
7
- offerExternalHomes
8
- } from "./chunk-3YHAYXBC.js";
9
2
  import {
10
3
  DERIVED_ROWS,
11
4
  DERIVED_VIEW,
12
- RESOLVED_VIEW,
13
- STDIN_REQUIRES_AS,
14
- assertSourcesAvailable,
15
- commandsOf,
16
- createDerivedView,
17
- createResolvedView,
18
- deriveForTable,
19
- deriveMetadata,
20
- derivedColumns,
21
- fieldsForSql,
22
- machinesOf,
23
- mapConcurrent,
24
- mentionsDerived,
25
- mentionsResolved,
26
- provenanceFenced,
27
- provenanceManifests,
28
- provenancePlace,
29
- readerManifests,
30
- readerPlace,
31
- stampManifests
32
- } from "./chunk-NAZRLJAK.js";
33
- import {
34
5
  ENCRYPTED_PLACEHOLDER,
35
6
  ENCRYPTION_KEY_ENV,
36
7
  EncryptionRefusal,
37
8
  META_CONTEXT,
38
9
  PATH_JOIN,
39
10
  RESERVED,
11
+ RESOLVED_VIEW,
12
+ STDIN_REQUIRES_AS,
40
13
  SYSTEM_COLUMNS,
41
14
  Validator,
42
15
  applyRelocation,
43
16
  assertSingleStatement,
17
+ assertSourcesAvailable,
44
18
  bindValue,
45
19
  collectCollections,
46
20
  collectNamedParameters,
47
21
  collectionNames,
22
+ commandsOf,
48
23
  committedKeyWarning,
49
24
  compareProvenance,
50
25
  compileWithFormats,
51
26
  corpusDataColumns,
52
27
  createCollectionViews,
28
+ createDerivedView,
53
29
  createDocsTable,
30
+ createResolvedView,
31
+ deriveForTable,
32
+ deriveMetadata,
33
+ derivedColumns,
54
34
  encryptionView,
55
35
  externalMetadataJoin,
36
+ fieldsForSql,
56
37
  heldManifest,
57
38
  isAtOrUnder,
58
39
  isIgnoredByGit,
@@ -62,8 +43,12 @@ import {
62
43
  lineSpec,
63
44
  loadExternalMetadata,
64
45
  loadSqlite,
46
+ machinesOf,
47
+ mapConcurrent,
65
48
  marksValidator,
66
49
  memberOf,
50
+ mentionsDerived,
51
+ mentionsResolved,
67
52
  mergeExternalMetadata,
68
53
  mergeWithMarks,
69
54
  offerPrompt,
@@ -76,16 +61,22 @@ import {
76
61
  planRelocation,
77
62
  pointerOf,
78
63
  provenanceEntries,
64
+ provenanceFenced,
79
65
  provenanceFindings,
66
+ provenanceManifests,
67
+ provenancePlace,
80
68
  rangeResults,
81
69
  readManifestValue,
82
70
  readProvenancePage,
71
+ readerManifests,
72
+ readerPlace,
83
73
  rebaseable,
84
74
  rebaseline,
85
75
  redactForModel,
86
76
  redactedDerived,
87
77
  registerLineFor,
88
78
  relocationContext,
79
+ relocationOffers,
89
80
  removeManifestKey,
90
81
  renameManifestEntry,
91
82
  renderProvenanceValue,
@@ -96,6 +87,7 @@ import {
96
87
  skipComment,
97
88
  skipStringOrIdent,
98
89
  spliceManifestValue,
90
+ stampManifests,
99
91
  startsComment,
100
92
  startsStringOrIdent,
101
93
  stringFormatNames,
@@ -106,11 +98,11 @@ import {
106
98
  valueAt,
107
99
  withValueAt,
108
100
  writeEncryptionKey
109
- } from "./chunk-HVFR66GQ.js";
101
+ } from "./chunk-TUAAR3MM.js";
110
102
  import {
111
103
  formatList,
112
104
  render
113
- } from "./chunk-TCC737IS.js";
105
+ } from "./chunk-5G53XATW.js";
114
106
  import {
115
107
  DERIVABLE_FIELDS,
116
108
  DERIVE_SOURCES,
@@ -164,7 +156,7 @@ import {
164
156
  urlManifestMessage,
165
157
  urlManifestOwning,
166
158
  writeFileAtomic
167
- } from "./chunk-527HHQPS.js";
159
+ } from "./chunk-KCOFEWV5.js";
168
160
  import {
169
161
  palette
170
162
  } from "./chunk-RNVYGWIC.js";
@@ -173,20 +165,24 @@ import {
173
165
  escapeWorkflowCommandProperty
174
166
  } from "./chunk-MNH7QO4Z.js";
175
167
  import {
176
- assertKnownProvider,
177
- assertLocalFlag,
178
- assertModelHasProvider,
179
168
  decryptValue,
180
169
  encryptValue,
181
170
  generateEncryptionKey,
182
171
  isEncryptedValue,
183
- isMember,
172
+ isMember
173
+ } from "./chunk-XKBEHKWO.js";
174
+ import {
175
+ warn
176
+ } from "./chunk-HX44GB4Z.js";
177
+ import {
178
+ assertKnownProvider,
179
+ assertLocalFlag,
180
+ assertModelHasProvider,
184
181
  localNotice,
185
182
  providerSpecFor,
186
183
  resolveIdentity,
187
- selectProvider,
188
- warn
189
- } from "./chunk-Q35YIDBV.js";
184
+ selectProvider
185
+ } from "./chunk-QCHVR4ZM.js";
190
186
  import {
191
187
  errorMessage
192
188
  } from "./chunk-G3T47CFV.js";
@@ -964,7 +960,110 @@ import { randomBytes } from "node:crypto";
964
960
  import { existsSync as existsSync2 } from "node:fs";
965
961
  import { mkdir as mkdir2, open, readFile as readFile3, rename, rm } from "node:fs/promises";
966
962
  import { dirname as dirname2, isAbsolute as isAbsolute2, resolve as resolve3, extname as extname3, sep as sep2 } from "node:path";
967
- import { parseDocument as parseDocument2, isMap, isSeq, isScalar } from "yaml";
963
+ import { parseDocument as parseDocument3, isMap as isMap2, isSeq, isScalar as isScalar2 } from "yaml";
964
+
965
+ // src/meta/core/location-writes.ts
966
+ import { LineCounter, isMap, isNode, isScalar, parseDocument as parseDocument2 } from "yaml";
967
+ var dedupe = (xs) => [...new Set(xs)];
968
+ var pages = (n) => `${String(n)} page${n === 1 ? "" : "s"}`;
969
+ async function offerExternalHomes(ctx, writes, hooks) {
970
+ const applied = /* @__PURE__ */ new Set();
971
+ const groups = /* @__PURE__ */ new Map();
972
+ for (const w of writes) {
973
+ if (w.home.kind !== "collection") continue;
974
+ const group = groups.get(w.home.collection) ?? [];
975
+ group.push(w);
976
+ groups.set(w.home.collection, group);
977
+ }
978
+ for (const [collection, group] of groups) {
979
+ const require2 = /* @__PURE__ */ new Map();
980
+ for (const w of group) {
981
+ const keys = require2.get(w.label) ?? [];
982
+ if (!keys.includes(w.key)) keys.push(w.key);
983
+ require2.set(w.label, keys);
984
+ }
985
+ const plan = await planRelocation(ctx, {
986
+ files: [...require2.keys()],
987
+ fields: dedupe(group.map((w) => w.key)),
988
+ require: require2
989
+ });
990
+ const offers = relocationOffers(plan);
991
+ if (offers.length === 0) continue;
992
+ let yes = true;
993
+ for (const offer of offers) {
994
+ const { notice, question } = offerPrompt(offer, "write");
995
+ hooks.onNotice?.(notice);
996
+ if (!await hooks.confirm(question)) {
997
+ yes = false;
998
+ break;
999
+ }
1000
+ }
1001
+ if (!yes) continue;
1002
+ const result = await applyRelocation(ctx, plan);
1003
+ hooks.onRelocated?.(result);
1004
+ applied.add(collection);
1005
+ }
1006
+ return applied;
1007
+ }
1008
+ function externalWriteWarnings(writes, dryRun) {
1009
+ const verb = dryRun ? "would write" : "wrote";
1010
+ const groups = /* @__PURE__ */ new Map();
1011
+ const groupOf = (w) => w.home.kind === "collection" ? `c:${w.home.collection}` : `n:${w.home.reason}`;
1012
+ for (const w of writes) {
1013
+ const id = groupOf(w);
1014
+ groups.set(id, [...groups.get(id) ?? [], w]);
1015
+ }
1016
+ const out = [];
1017
+ for (const group of groups.values()) {
1018
+ const [first] = group;
1019
+ if (first === void 0) continue;
1020
+ out.push(
1021
+ externalWriteWarning({
1022
+ verb,
1023
+ keys: dedupe(group.map((w) => w.key)),
1024
+ pages: new Set(group.map((w) => w.label)).size,
1025
+ home: first.home,
1026
+ createsHome: group.some(
1027
+ (w) => w.home.kind === "collection" && (w.home.createsCollection || w.home.addsPath !== void 0)
1028
+ )
1029
+ })
1030
+ );
1031
+ }
1032
+ return out;
1033
+ }
1034
+ function externalWriteWarning(line) {
1035
+ const { verb, keys, home } = line;
1036
+ const one = keys.length === 1;
1037
+ const head = `${verb} ${keys.join(", ")} to ${pages(line.pages)}`;
1038
+ const prefer = one ? "the schema prefers external metadata" : "their schemas prefer external metadata";
1039
+ const them = one ? "it" : "them";
1040
+ if (home.kind === "collection") {
1041
+ if (!line.createsHome) {
1042
+ return `${head} in collection ${home.collection}; ${prefer}, and no manifest owns ${them}. Run manni meta relocate to move ${them}.`;
1043
+ }
1044
+ return home.createsCollection || home.createsManifest ? `${head}; ${prefer}. Run manni meta relocate to give ${them} a manifest.` : `${head}; ${prefer}. Run manni meta relocate to add ${them} to collection ${home.collection}.`;
1045
+ }
1046
+ return home.reason === "no-config" ? `${head}; ${prefer}, and --no-config leaves ${them} no manifest.` : `${head} that ${line.pages === 1 ? "is" : "are"} in none of the ${String(home.collections)} collections; ${prefer}, and only a collection has a manifest.`;
1047
+ }
1048
+ function manifestKeyLine(text, entry, key, join3) {
1049
+ const norm = (e) => join3 === PATH_JOIN ? e.replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+/g, "/") : e;
1050
+ const lc = new LineCounter();
1051
+ const doc = parseDocument2(text, { lineCounter: lc, uniqueKeys: false });
1052
+ const root = doc.contents;
1053
+ if (!isMap(root)) return void 0;
1054
+ for (const pair of root.items) {
1055
+ const spelled = isScalar(pair.key) ? String(pair.key.value) : String(pair.key);
1056
+ if (norm(spelled) !== norm(entry) || !isMap(pair.value)) continue;
1057
+ for (const kv of pair.value.items) {
1058
+ const name = isScalar(kv.key) ? String(kv.key.value) : String(kv.key);
1059
+ const range = isNode(kv.key) ? kv.key.range : void 0;
1060
+ if (name === key && range) return lc.linePos(range[0]).line;
1061
+ }
1062
+ }
1063
+ return void 0;
1064
+ }
1065
+
1066
+ // src/meta/commands/query.ts
968
1067
  async function runQuery(opts) {
969
1068
  const cwd = opts.cwd ?? process.cwd();
970
1069
  const sql = opts.sql.trim();
@@ -2178,11 +2277,11 @@ async function planConfigEdit(ctx, edit, runRefs) {
2178
2277
  return { changes: [], repointed: false };
2179
2278
  }
2180
2279
  const text = await readFile3(configPath, "utf8");
2181
- const doc = parseDocument2(stripBom(text));
2280
+ const doc = parseDocument3(stripBom(text));
2182
2281
  const display = displayPath(ctx, configPath);
2183
2282
  const rawRefOf = (item) => {
2184
- if (isScalar(item) && typeof item.value === "string") return item.value;
2185
- if (isMap(item)) {
2283
+ if (isScalar2(item) && typeof item.value === "string") return item.value;
2284
+ if (isMap2(item)) {
2186
2285
  const ref = item.get("ref");
2187
2286
  if (typeof ref === "string") return ref;
2188
2287
  }
@@ -2204,10 +2303,10 @@ async function planConfigEdit(ctx, edit, runRefs) {
2204
2303
  for (const item of node.items) {
2205
2304
  const raw = rawRefOf(item);
2206
2305
  if (raw === void 0 || !wants(raw)) continue;
2207
- if (isScalar(item)) {
2306
+ if (isScalar2(item)) {
2208
2307
  item.value = spec.newRef;
2209
2308
  n += 1;
2210
- } else if (isMap(item)) {
2309
+ } else if (isMap2(item)) {
2211
2310
  item.set("ref", spec.newRef);
2212
2311
  n += 1;
2213
2312
  }
@@ -2215,13 +2314,13 @@ async function planConfigEdit(ctx, edit, runRefs) {
2215
2314
  return n;
2216
2315
  };
2217
2316
  const root = ctx.configSection === void 0 ? doc : doc.get(ctx.configSection, true);
2218
- const keyOf2 = (key) => root === doc ? doc.get(key, true) : isMap(root) ? root.get(key, true) : void 0;
2317
+ const keyOf2 = (key) => root === doc ? doc.get(key, true) : isMap2(root) ? root.get(key, true) : void 0;
2219
2318
  const topSeq = keyOf2("schemas");
2220
2319
  let repointCount = repoint(topSeq);
2221
2320
  const overrides = keyOf2("overrides");
2222
2321
  if (isSeq(overrides)) {
2223
2322
  for (const entry of overrides.items) {
2224
- if (isMap(entry)) repointCount += repoint(entry.get("schemas", true));
2323
+ if (isMap2(entry)) repointCount += repoint(entry.get("schemas", true));
2225
2324
  }
2226
2325
  }
2227
2326
  const repointed = repointCount > 0;
@@ -2230,7 +2329,7 @@ async function planConfigEdit(ctx, edit, runRefs) {
2230
2329
  if (edit.integrity && isSeq(topSeq)) {
2231
2330
  const wantPath = foldPath(edit.integrity.path);
2232
2331
  for (const item of topSeq.items) {
2233
- if (!isMap(item)) continue;
2332
+ if (!isMap2(item)) continue;
2234
2333
  const raw = rawRefOf(item);
2235
2334
  if (raw === void 0 || classifyRef(raw).kind !== "file") continue;
2236
2335
  const abs = isAbsolute2(raw) ? raw : resolve3(configDir, raw);
@@ -4041,6 +4140,51 @@ function buildUserPrompt(params, before = []) {
4041
4140
  ].join("\n");
4042
4141
  }
4043
4142
 
4143
+ // src/meta/core/meta-provenance.ts
4144
+ function isPlainRecord(value) {
4145
+ return typeof value === "object" && value !== null && !Array.isArray(value);
4146
+ }
4147
+ function mergeMetaProvenance(held, model, key, proposed) {
4148
+ if (held !== void 0 && !Array.isArray(held)) return void 0;
4149
+ const list = held === void 0 ? [] : [...held];
4150
+ const at = list.findIndex((e) => isPlainRecord(e) && e["generated-by"] === model);
4151
+ const prior = list[at];
4152
+ const kept = isPlainRecord(prior) ? prior : {};
4153
+ const priorNames = kept[key];
4154
+ const names = Array.isArray(priorNames) ? priorNames.filter((p) => typeof p === "string") : [];
4155
+ const confidence = {};
4156
+ if (isPlainRecord(kept.confidence)) {
4157
+ for (const [k, v] of Object.entries(kept.confidence)) {
4158
+ if (typeof v === "number") confidence[k] = v;
4159
+ }
4160
+ }
4161
+ for (const p of proposed) {
4162
+ if (!names.includes(p.name)) names.push(p.name);
4163
+ confidence[p.name] = p.confidence;
4164
+ }
4165
+ const entry = {
4166
+ ...kept,
4167
+ "generated-by": model,
4168
+ [key]: names,
4169
+ confidence
4170
+ };
4171
+ if (at === -1) list.push(entry);
4172
+ else list[at] = entry;
4173
+ return { list, entry, names };
4174
+ }
4175
+ function metaProvenanceEntries(value) {
4176
+ if (!Array.isArray(value)) return [];
4177
+ const strings = (list) => Array.isArray(list) ? list.filter((s) => typeof s === "string") : [];
4178
+ const out = [];
4179
+ for (const item of value) {
4180
+ if (!isPlainRecord(item)) continue;
4181
+ const machine = item["generated-by"];
4182
+ if (typeof machine !== "string" || machine === "") continue;
4183
+ out.push({ "generated-by": machine, fields: strings(item.fields), evals: strings(item.evals) });
4184
+ }
4185
+ return out;
4186
+ }
4187
+
4044
4188
  // src/meta/commands/fill.ts
4045
4189
  var META_PROVENANCE_KEY = "meta-provenance";
4046
4190
  var PROVENANCE_KEYS = /* @__PURE__ */ new Set(["provenance", META_PROVENANCE_KEY]);
@@ -4253,10 +4397,10 @@ async function runFill(opts) {
4253
4397
  const keys = new Set(candidates.map((c) => c.key));
4254
4398
  const wants = (fields) => fields.some(([key]) => key !== void 0 && keys.has(key));
4255
4399
  const termIndex = wants(TERM_FIELDS) ? await (termbase ??= readTermbase()) : void 0;
4256
- const pages = wants(PAGE_FIELDS) ? await pageIds(resolve5(base, label), mergeMembersFor(label)) : [];
4400
+ const pages2 = wants(PAGE_FIELDS) ? await pageIds(resolve5(base, label), mergeMembersFor(label)) : [];
4257
4401
  const hints = fieldHints(candidates, {
4258
4402
  terms: termIndex === void 0 ? void 0 : offered(termIndex.labels),
4259
- pages: offered(pages)
4403
+ pages: offered(pages2)
4260
4404
  });
4261
4405
  return { hints, termIndex };
4262
4406
  };
@@ -5550,7 +5694,7 @@ async function runDerive(opts) {
5550
5694
  runFields = union2;
5551
5695
  }
5552
5696
  const provenanceRoot = configDir ?? cwd;
5553
- const pages = files.map((label) => resolve6(base, label));
5697
+ const pages2 = files.map((label) => resolve6(base, label));
5554
5698
  const manifests = runFields.includes(PROVENANCE_FIELD) ? provenanceManifests(declaredCollections, provenanceRoot, base) : [];
5555
5699
  const provenanceCollections = declaredCollections.map((c) => ({
5556
5700
  ...c,
@@ -5558,7 +5702,7 @@ async function runDerive(opts) {
5558
5702
  (m) => m.keys === void 0 ? classifyRef(m.file).kind !== "url" : m.keys.includes(PROVENANCE_FIELD)
5559
5703
  )
5560
5704
  })).filter((c) => c.externalMetadata.length > 0);
5561
- const provenanceIndex = manifests.length === 0 ? null : await loadExternalMetadata(provenanceCollections, { configDir: provenanceRoot, base, pages });
5705
+ const provenanceIndex = manifests.length === 0 ? null : await loadExternalMetadata(provenanceCollections, { configDir: provenanceRoot, base, pages: pages2 });
5562
5706
  const places2 = /* @__PURE__ */ new Map();
5563
5707
  for (const doc of loaded2.values()) {
5564
5708
  const dated = fieldsOf(doc.label).filter((f) => f === "created" || f === "last-updated");
@@ -5600,7 +5744,7 @@ async function runDerive(opts) {
5600
5744
  (m.keys === void 0 || m.keys.some((k) => k !== PROVENANCE_FIELD && runFields.includes(k)))
5601
5745
  )
5602
5746
  })).filter((c) => c.externalMetadata.length > 0);
5603
- const ownedIndex = ownedCollections.length === 0 ? null : await loadExternalMetadata(ownedCollections, { configDir: provenanceRoot, base, pages });
5747
+ const ownedIndex = ownedCollections.length === 0 ? null : await loadExternalMetadata(ownedCollections, { configDir: provenanceRoot, base, pages: pages2 });
5604
5748
  const derived2 = await deriveMetadata([...loaded2.values()], {
5605
5749
  cwd,
5606
5750
  base,
@@ -6710,12 +6854,16 @@ export {
6710
6854
  vendorFileName,
6711
6855
  runVendorSchema,
6712
6856
  runInferSchema,
6857
+ offerExternalHomes,
6858
+ externalWriteWarnings,
6713
6859
  runQuery,
6714
6860
  CONCEPT_FIELDS,
6715
6861
  TERM_RELATION_FIELDS,
6716
6862
  fieldPointer,
6717
6863
  valueAt2 as valueAt,
6718
6864
  registerTermLabelSource,
6865
+ mergeMetaProvenance,
6866
+ metaProvenanceEntries,
6719
6867
  runFill,
6720
6868
  runDerive,
6721
6869
  deriveFailed,
@@ -6734,4 +6882,4 @@ export {
6734
6882
  renderQuery,
6735
6883
  renderQueryCsv
6736
6884
  };
6737
- //# sourceMappingURL=chunk-QCBICNKC.js.map
6885
+ //# sourceMappingURL=chunk-GREQKO6M.js.map