@hawkeyexl/manni 4.3.1 → 4.4.1

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 (225) hide show
  1. package/README.md +9 -1
  2. package/dist/batch-GFNLTGOH.js +36 -0
  3. package/dist/build-COYIQ25L.js +31 -0
  4. package/dist/calibrate-MDBLJKEE.js +31 -0
  5. package/dist/capture-LRML2PKV.js +32 -0
  6. package/dist/check-ASPIHA6B.js +40 -0
  7. package/dist/check-ASPIHA6B.js.map +1 -0
  8. package/dist/check-EDLBYL5N.js +27 -0
  9. package/dist/check-EDLBYL5N.js.map +1 -0
  10. package/dist/check-HYNGXYJV.js +18 -0
  11. package/dist/check-HYNGXYJV.js.map +1 -0
  12. package/dist/chunk-2B7ZNTPV.js +230 -0
  13. package/dist/chunk-2B7ZNTPV.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-37LP5HMZ.js +1042 -0
  17. package/dist/chunk-37LP5HMZ.js.map +1 -0
  18. package/dist/chunk-3VK37OR2.js +2957 -0
  19. package/dist/chunk-3VK37OR2.js.map +1 -0
  20. package/dist/chunk-4IUC2MNL.js +2165 -0
  21. package/dist/chunk-4IUC2MNL.js.map +1 -0
  22. package/dist/{chunk-3R23C5DT.js → chunk-4TSWU2SU.js} +2 -14
  23. package/dist/chunk-4TSWU2SU.js.map +1 -0
  24. package/dist/chunk-57NEQRVO.js +10921 -0
  25. package/dist/chunk-57NEQRVO.js.map +1 -0
  26. package/dist/chunk-6JSSEWBG.js +6737 -0
  27. package/dist/chunk-6JSSEWBG.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-7UKO3ASZ.js +54 -0
  33. package/dist/chunk-7UKO3ASZ.js.map +1 -0
  34. package/dist/chunk-A5ULMVHQ.js +164 -0
  35. package/dist/chunk-A5ULMVHQ.js.map +1 -0
  36. package/dist/chunk-C4SQM22E.js +299 -0
  37. package/dist/chunk-C4SQM22E.js.map +1 -0
  38. package/dist/chunk-CK7SKVHR.js +1042 -0
  39. package/dist/chunk-CK7SKVHR.js.map +1 -0
  40. package/dist/{chunk-G5CM2VGQ.js → chunk-DXNZS72W.js} +8 -94
  41. package/dist/chunk-DXNZS72W.js.map +1 -0
  42. package/dist/chunk-EPH54CAY.js +374 -0
  43. package/dist/chunk-EPH54CAY.js.map +1 -0
  44. package/dist/{chunk-KJR7OVDX.js → chunk-FBEQCK47.js} +56 -137
  45. package/dist/chunk-FBEQCK47.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-GCQRPUSB.js +1287 -0
  49. package/dist/chunk-GCQRPUSB.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-I2AH3CJJ.js +1192 -0
  53. package/dist/chunk-I2AH3CJJ.js.map +1 -0
  54. package/dist/chunk-IDV6HJCB.js +388 -0
  55. package/dist/chunk-IDV6HJCB.js.map +1 -0
  56. package/dist/chunk-IKEWBMCN.js +98 -0
  57. package/dist/chunk-IKEWBMCN.js.map +1 -0
  58. package/dist/chunk-JCDXE76J.js +52 -0
  59. package/dist/chunk-JCDXE76J.js.map +1 -0
  60. package/dist/chunk-JXLTXMJ7.js +455 -0
  61. package/dist/chunk-JXLTXMJ7.js.map +1 -0
  62. package/dist/chunk-LJ2RDH3F.js +49 -0
  63. package/dist/chunk-LJ2RDH3F.js.map +1 -0
  64. package/dist/chunk-M2JCK5F6.js +805 -0
  65. package/dist/chunk-M2JCK5F6.js.map +1 -0
  66. package/dist/chunk-M3W7J6MU.js +4398 -0
  67. package/dist/chunk-M3W7J6MU.js.map +1 -0
  68. package/dist/chunk-MMTSSTG7.js +23 -0
  69. package/dist/chunk-MMTSSTG7.js.map +1 -0
  70. package/dist/chunk-MNH7QO4Z.js +15 -0
  71. package/dist/chunk-MNH7QO4Z.js.map +1 -0
  72. package/dist/chunk-MWJLZMBL.js +934 -0
  73. package/dist/chunk-MWJLZMBL.js.map +1 -0
  74. package/dist/chunk-MYMBCTDE.js +387 -0
  75. package/dist/chunk-MYMBCTDE.js.map +1 -0
  76. package/dist/chunk-NCPWXHDO.js +683 -0
  77. package/dist/chunk-NCPWXHDO.js.map +1 -0
  78. package/dist/chunk-NLXTXE5Y.js +1661 -0
  79. package/dist/chunk-NLXTXE5Y.js.map +1 -0
  80. package/dist/{chunk-CFDUZRM2.js → chunk-NXV7WE2D.js} +32 -240
  81. package/dist/chunk-NXV7WE2D.js.map +1 -0
  82. package/dist/chunk-OWBRDNRZ.js +16 -0
  83. package/dist/chunk-OWBRDNRZ.js.map +1 -0
  84. package/dist/{chunk-KTSJ2ZHA.js → chunk-PAU352SV.js} +5 -3
  85. package/dist/{chunk-KTSJ2ZHA.js.map → chunk-PAU352SV.js.map} +1 -1
  86. package/dist/chunk-PCE7QHXJ.js +68 -0
  87. package/dist/chunk-PCE7QHXJ.js.map +1 -0
  88. package/dist/chunk-PIKOVN6W.js +1651 -0
  89. package/dist/chunk-PIKOVN6W.js.map +1 -0
  90. package/dist/chunk-PNPQTHBT.js +17 -0
  91. package/dist/chunk-PNPQTHBT.js.map +1 -0
  92. package/dist/chunk-PU6DFJMY.js +1975 -0
  93. package/dist/chunk-PU6DFJMY.js.map +1 -0
  94. package/dist/chunk-Q35YIDBV.js +1202 -0
  95. package/dist/chunk-Q35YIDBV.js.map +1 -0
  96. package/dist/{chunk-5HNHEUD5.js → chunk-QQUKGCAJ.js} +3 -3
  97. package/dist/chunk-QRWGPQKO.js +198 -0
  98. package/dist/chunk-QRWGPQKO.js.map +1 -0
  99. package/dist/{chunk-UBMMXS2Y.js → chunk-QZ6LRSNV.js} +69 -48
  100. package/dist/{chunk-UBMMXS2Y.js.map → chunk-QZ6LRSNV.js.map} +1 -1
  101. package/dist/chunk-RL5XWQOL.js +3872 -0
  102. package/dist/chunk-RL5XWQOL.js.map +1 -0
  103. package/dist/chunk-RNVYGWIC.js +30 -0
  104. package/dist/chunk-RNVYGWIC.js.map +1 -0
  105. package/dist/chunk-SE4JN5XN.js +19 -0
  106. package/dist/chunk-SE4JN5XN.js.map +1 -0
  107. package/dist/chunk-SKSDRUUK.js +622 -0
  108. package/dist/chunk-SKSDRUUK.js.map +1 -0
  109. package/dist/chunk-TIUTIOFB.js +25 -0
  110. package/dist/chunk-TIUTIOFB.js.map +1 -0
  111. package/dist/chunk-TK3FC4RF.js +3090 -0
  112. package/dist/chunk-TK3FC4RF.js.map +1 -0
  113. package/dist/chunk-TU2WUBVZ.js +2 -0
  114. package/dist/chunk-TU2WUBVZ.js.map +1 -0
  115. package/dist/chunk-TZOYZK2E.js +98 -0
  116. package/dist/chunk-TZOYZK2E.js.map +1 -0
  117. package/dist/chunk-UJCVAWP7.js +178 -0
  118. package/dist/chunk-UJCVAWP7.js.map +1 -0
  119. package/dist/chunk-UKZNLVJW.js +17 -0
  120. package/dist/chunk-UKZNLVJW.js.map +1 -0
  121. package/dist/{chunk-HAPTXWU2.js → chunk-UQISLDAV.js} +4 -4
  122. package/dist/chunk-WB3QM6PP.js +5440 -0
  123. package/dist/chunk-WB3QM6PP.js.map +1 -0
  124. package/dist/chunk-YB4IBW3M.js +96 -0
  125. package/dist/chunk-YB4IBW3M.js.map +1 -0
  126. package/dist/chunk-YEUYKR62.js +72 -0
  127. package/dist/chunk-YEUYKR62.js.map +1 -0
  128. package/dist/chunk-YJOGUXGP.js +634 -0
  129. package/dist/chunk-YJOGUXGP.js.map +1 -0
  130. package/dist/chunk-YNHZHSSM.js +41 -0
  131. package/dist/chunk-YNHZHSSM.js.map +1 -0
  132. package/dist/chunk-YTURO7SI.js +979 -0
  133. package/dist/chunk-YTURO7SI.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-3BIBYHFK.js +473 -0
  137. package/dist/cli-3BIBYHFK.js.map +1 -0
  138. package/dist/cli-673OTRGE.js +28 -0
  139. package/dist/cli-673OTRGE.js.map +1 -0
  140. package/dist/cli-6HIDIFVT.js +1203 -0
  141. package/dist/cli-6HIDIFVT.js.map +1 -0
  142. package/dist/cli-6UB5N6CU.js +232 -0
  143. package/dist/cli-6UB5N6CU.js.map +1 -0
  144. package/dist/cli-LFP5ZGYS.js +346 -0
  145. package/dist/cli-LFP5ZGYS.js.map +1 -0
  146. package/dist/cli-MN7PYMBI.js +552 -0
  147. package/dist/cli-MN7PYMBI.js.map +1 -0
  148. package/dist/cli-PYPX6O6E.js +739 -0
  149. package/dist/cli-PYPX6O6E.js.map +1 -0
  150. package/dist/cli-RPM5PELX.js +626 -0
  151. package/dist/cli-RPM5PELX.js.map +1 -0
  152. package/dist/cli-VI7VHWNZ.js +423 -0
  153. package/dist/cli-VI7VHWNZ.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-6QMYOHC3.js +27 -0
  160. package/dist/github-6QMYOHC3.js.map +1 -0
  161. package/dist/github-SXPGP5DB.js +32 -0
  162. package/dist/github-SXPGP5DB.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-SY7KLNC7.js +35 -0
  169. package/dist/json-SY7KLNC7.js.map +1 -0
  170. package/dist/lint-ASMJLLPA.js +28 -0
  171. package/dist/lint-ASMJLLPA.js.map +1 -0
  172. package/dist/list-KZNVTNVC.js +31 -0
  173. package/dist/list-KZNVTNVC.js.map +1 -0
  174. package/dist/list-Q57YTFUQ.js +29 -0
  175. package/dist/list-Q57YTFUQ.js.map +1 -0
  176. package/dist/page-KSGV5RD4.js +41 -0
  177. package/dist/page-KSGV5RD4.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-A5EGTN35.js +37 -0
  181. package/dist/pretty-A5EGTN35.js.map +1 -0
  182. package/dist/pretty-CXSDXNAS.js +43 -0
  183. package/dist/pretty-CXSDXNAS.js.map +1 -0
  184. package/dist/reporters-HUY7UXFS.js +42 -0
  185. package/dist/reporters-HUY7UXFS.js.map +1 -0
  186. package/dist/reporters-K2VUKSAK.js +71 -0
  187. package/dist/reporters-K2VUKSAK.js.map +1 -0
  188. package/dist/reporters-M6LJ2IYU.js +21 -0
  189. package/dist/reporters-M6LJ2IYU.js.map +1 -0
  190. package/dist/run-3DYJNRIG.js +33 -0
  191. package/dist/run-3DYJNRIG.js.map +1 -0
  192. package/dist/term-BIQUPMOR.js +1592 -0
  193. package/dist/term-BIQUPMOR.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-53RKM2XG.js +16 -0
  197. package/dist/validate-53RKM2XG.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 +69 -0
  201. package/plugin/manni/hooks/manni.mjs +157 -0
  202. package/plugin/manni/skills/check/SKILL.md +20 -0
  203. package/plugin/manni/skills/evals/SKILL.md +27 -0
  204. package/plugin/manni/skills/fix/SKILL.md +56 -0
  205. package/plugin/manni/skills/setup/SKILL.md +41 -0
  206. package/dist/batch-A5HZKYIW.js +0 -18
  207. package/dist/calibrate-S5K6QHUY.js +0 -13
  208. package/dist/capture-OZEZDABQ.js +0 -15
  209. package/dist/chunk-3R23C5DT.js.map +0 -1
  210. package/dist/chunk-CFDUZRM2.js.map +0 -1
  211. package/dist/chunk-G5CM2VGQ.js.map +0 -1
  212. package/dist/chunk-KJR7OVDX.js.map +0 -1
  213. package/dist/chunk-V4KUVE47.js +0 -27170
  214. package/dist/chunk-V4KUVE47.js.map +0 -1
  215. package/dist/chunk-ZQBTK3DO.js +0 -26518
  216. package/dist/chunk-ZQBTK3DO.js.map +0 -1
  217. package/dist/picker-6HRMETE7.js +0 -12
  218. package/plugin/tracevals/.claude-plugin/plugin.json +0 -9
  219. package/plugin/tracevals/hooks/hooks.json +0 -17
  220. /package/dist/{batch-A5HZKYIW.js.map → batch-GFNLTGOH.js.map} +0 -0
  221. /package/dist/{calibrate-S5K6QHUY.js.map → build-COYIQ25L.js.map} +0 -0
  222. /package/dist/{capture-OZEZDABQ.js.map → calibrate-MDBLJKEE.js.map} +0 -0
  223. /package/dist/{picker-6HRMETE7.js.map → capture-LRML2PKV.js.map} +0 -0
  224. /package/dist/{chunk-5HNHEUD5.js.map → chunk-QQUKGCAJ.js.map} +0 -0
  225. /package/dist/{chunk-HAPTXWU2.js.map → chunk-UQISLDAV.js.map} +0 -0
@@ -0,0 +1,934 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ ManifestSet,
4
+ appendFrontmatterCitation,
5
+ entryObject,
6
+ insertStatementBefore,
7
+ itemLine,
8
+ mintCitation,
9
+ removeFrontmatterCitations,
10
+ removeLine,
11
+ runAdd,
12
+ runRemove,
13
+ runUpdate,
14
+ shiftedEntries,
15
+ splice,
16
+ spliceEntryField,
17
+ unifiedDiff,
18
+ withClaimLines
19
+ } from "./chunk-4IUC2MNL.js";
20
+ import {
21
+ CITATIONS_KEY,
22
+ CITE_SECTION,
23
+ DEFAULT_CITE_BASELINE_PATH,
24
+ GIT_UNAVAILABLE_COMMIT,
25
+ GIT_UNAVAILABLE_HISTORY,
26
+ MAX_PAGE_COMMITS,
27
+ PAGE_HISTORY_UNAVAILABLE,
28
+ buildSourceIndex,
29
+ checkCitations,
30
+ claimDiff,
31
+ claimHistory,
32
+ claimWords,
33
+ classifyCitation,
34
+ decryptSourcePath,
35
+ duplicateJoinRefusal,
36
+ encryptSourcePath,
37
+ gitClient,
38
+ historyOf,
39
+ holdsWords,
40
+ loadCitationSidecars,
41
+ loadCiteConfig,
42
+ noGit,
43
+ orphanRefusal,
44
+ parseCiteConfig,
45
+ readCiteConfigFile,
46
+ readSource,
47
+ refineClaim,
48
+ resolveCiteRun,
49
+ runCheck,
50
+ runsHolding,
51
+ sentencesOf,
52
+ sharesSentence,
53
+ sidecarsFor,
54
+ stripMarkers,
55
+ twoManifestsRefusal,
56
+ urlManifestRefusal
57
+ } from "./chunk-PIKOVN6W.js";
58
+ import {
59
+ renderCheckGithub
60
+ } from "./chunk-7UKO3ASZ.js";
61
+ import {
62
+ refusalLine,
63
+ removalLine,
64
+ renderCheckPretty,
65
+ renderRemovePretty,
66
+ renderUpdatePretty,
67
+ rewriteLine
68
+ } from "./chunk-JXLTXMJ7.js";
69
+ import {
70
+ blockMatches,
71
+ claimEnd,
72
+ claimLine,
73
+ claimMessageFor,
74
+ errorSite,
75
+ findingsFor,
76
+ isUnitText,
77
+ markerClaimEnd,
78
+ markerRunAt,
79
+ markerUnit,
80
+ messageFor,
81
+ misplacedMarkerAt,
82
+ misplacedMarkers,
83
+ misplacedMessageFor,
84
+ movedUnit,
85
+ noUnitAt,
86
+ normalizeWhitespace,
87
+ pre43Span,
88
+ shortCommit,
89
+ shortLine,
90
+ shortPin,
91
+ shortSrc,
92
+ spellAt,
93
+ splitUnit,
94
+ toValidationResult,
95
+ unitAt,
96
+ unitText
97
+ } from "./chunk-SKSDRUUK.js";
98
+ import {
99
+ renderCheckJson,
100
+ renderRemoveJson,
101
+ renderUpdateJson
102
+ } from "./chunk-PCE7QHXJ.js";
103
+ import {
104
+ CITE_RULES,
105
+ CiteError,
106
+ DEFAULT_SEVERITY,
107
+ FILE_PATTERN,
108
+ MARKER_JSON,
109
+ MAX_MARKERS_PER_PAGE,
110
+ RULE_ID_PREFIX,
111
+ SRC_PATTERN,
112
+ anchoredLines,
113
+ bodyLineOf,
114
+ citationInputs,
115
+ detectEol,
116
+ fenceSpanAt,
117
+ fencedBlockAfter,
118
+ fencedBlockAt,
119
+ fencedBlocks,
120
+ formatSrc,
121
+ formatStatement,
122
+ hashRange,
123
+ insideFence,
124
+ isBoundLine,
125
+ isCiteRule,
126
+ isTableRow,
127
+ lineAt,
128
+ offsetOfLine,
129
+ ownedMessage,
130
+ paragraphAfter,
131
+ parseSrc,
132
+ parseStatements,
133
+ pickExtractor,
134
+ rangeLines,
135
+ readPage,
136
+ resolveSeverity,
137
+ ruleId,
138
+ sliceLines,
139
+ sourceRange,
140
+ spellSource,
141
+ statementForms,
142
+ validateEntry
143
+ } from "./chunk-YTURO7SI.js";
144
+ import {
145
+ reencryptData,
146
+ reencryptMetadata
147
+ } from "./chunk-QRWGPQKO.js";
148
+ import {
149
+ ENCRYPTION_KEY_ENV,
150
+ MAX_RANGE_LINES,
151
+ MOVE_BUDGET_BYTES,
152
+ MOVE_WINDOW_LINES,
153
+ PATH_JOIN,
154
+ committedKeyWarning,
155
+ configMarks,
156
+ externalMetadataJoin,
157
+ findWindows,
158
+ hashLines,
159
+ isIgnoredByGit,
160
+ isKeyedPin,
161
+ lineSpec,
162
+ loadExternalMetadata,
163
+ normalizeText,
164
+ parseLines,
165
+ pinOfLines,
166
+ resolveEncryptionKey,
167
+ spellLines,
168
+ spliceManifestValue,
169
+ splitLines,
170
+ toBodyLines,
171
+ toFileLines,
172
+ writeEncryptionKey
173
+ } from "./chunk-M3W7J6MU.js";
174
+ import {
175
+ LEGACY_CONFIG_NAMES,
176
+ STDIN_TOKEN,
177
+ assertNonEmpty,
178
+ classifyRef,
179
+ extractorByName,
180
+ gitignoreOptions,
181
+ resolveTargetSet,
182
+ supportedExtensions,
183
+ writeFileAtomic
184
+ } from "./chunk-57NEQRVO.js";
185
+ import {
186
+ findConfigFile,
187
+ findFamilyConfigFile,
188
+ findGitRoot,
189
+ findPageManifests,
190
+ generateEncryptionKey,
191
+ hasPagePlaceholder,
192
+ isMember,
193
+ isValidEncryptionKey,
194
+ pageManifestPath,
195
+ readConfigFile,
196
+ readFamilyConfigFile,
197
+ selectCollections
198
+ } from "./chunk-Q35YIDBV.js";
199
+ import {
200
+ ToolError
201
+ } from "./chunk-G3T47CFV.js";
202
+ import {
203
+ __export
204
+ } from "./chunk-2H7UOFLK.js";
205
+
206
+ // src/cite/index.ts
207
+ var cite_exports = {};
208
+ __export(cite_exports, {
209
+ CITATIONS_KEY: () => CITATIONS_KEY,
210
+ CITE_RULES: () => CITE_RULES,
211
+ CITE_SECTION: () => CITE_SECTION,
212
+ CiteError: () => CiteError,
213
+ DEFAULT_CITE_BASELINE_PATH: () => DEFAULT_CITE_BASELINE_PATH,
214
+ DEFAULT_SEVERITY: () => DEFAULT_SEVERITY,
215
+ FILE_PATTERN: () => FILE_PATTERN,
216
+ GIT_UNAVAILABLE_COMMIT: () => GIT_UNAVAILABLE_COMMIT,
217
+ GIT_UNAVAILABLE_HISTORY: () => GIT_UNAVAILABLE_HISTORY,
218
+ MARKER_JSON: () => MARKER_JSON,
219
+ MAX_MARKERS_PER_PAGE: () => MAX_MARKERS_PER_PAGE,
220
+ MAX_PAGE_COMMITS: () => MAX_PAGE_COMMITS,
221
+ MAX_RANGE_LINES: () => MAX_RANGE_LINES,
222
+ MOVE_BUDGET_BYTES: () => MOVE_BUDGET_BYTES,
223
+ MOVE_WINDOW_LINES: () => MOVE_WINDOW_LINES,
224
+ ManifestSet: () => ManifestSet,
225
+ PAGE_HISTORY_UNAVAILABLE: () => PAGE_HISTORY_UNAVAILABLE,
226
+ RULE_ID_PREFIX: () => RULE_ID_PREFIX,
227
+ SRC_PATTERN: () => SRC_PATTERN,
228
+ anchoredLines: () => anchoredLines,
229
+ appendFrontmatterCitation: () => appendFrontmatterCitation,
230
+ blockMatches: () => blockMatches,
231
+ bodyLineOf: () => bodyLineOf,
232
+ buildSourceIndex: () => buildSourceIndex,
233
+ checkCitations: () => checkCitations,
234
+ citationInputs: () => citationInputs,
235
+ claimDiff: () => claimDiff,
236
+ claimEnd: () => claimEnd,
237
+ claimHistory: () => claimHistory,
238
+ claimLine: () => claimLine,
239
+ claimMessageFor: () => claimMessageFor,
240
+ claimWords: () => claimWords,
241
+ classifyCitation: () => classifyCitation,
242
+ detectEol: () => detectEol,
243
+ duplicateJoinRefusal: () => duplicateJoinRefusal,
244
+ entryObject: () => entryObject,
245
+ errorSite: () => errorSite,
246
+ fenceSpanAt: () => fenceSpanAt,
247
+ fencedBlockAfter: () => fencedBlockAfter,
248
+ fencedBlockAt: () => fencedBlockAt,
249
+ fencedBlocks: () => fencedBlocks,
250
+ findWindows: () => findWindows,
251
+ findingsFor: () => findingsFor,
252
+ formatSrc: () => formatSrc,
253
+ formatStatement: () => formatStatement,
254
+ gitClient: () => gitClient,
255
+ hashLines: () => hashLines,
256
+ hashRange: () => hashRange,
257
+ historyOf: () => historyOf,
258
+ holdsWords: () => holdsWords,
259
+ insertStatementBefore: () => insertStatementBefore,
260
+ insideFence: () => insideFence,
261
+ isBoundLine: () => isBoundLine,
262
+ isCiteRule: () => isCiteRule,
263
+ isKeyedPin: () => isKeyedPin,
264
+ isTableRow: () => isTableRow,
265
+ isUnitText: () => isUnitText,
266
+ itemLine: () => itemLine,
267
+ lineAt: () => lineAt,
268
+ lineSpec: () => lineSpec,
269
+ loadCitationSidecars: () => loadCitationSidecars,
270
+ loadCiteConfig: () => loadCiteConfig,
271
+ markerClaimEnd: () => markerClaimEnd,
272
+ markerRunAt: () => markerRunAt,
273
+ markerUnit: () => markerUnit,
274
+ messageFor: () => messageFor,
275
+ mintCitation: () => mintCitation,
276
+ misplacedMarkerAt: () => misplacedMarkerAt,
277
+ misplacedMarkers: () => misplacedMarkers,
278
+ misplacedMessageFor: () => misplacedMessageFor,
279
+ movedUnit: () => movedUnit,
280
+ noGit: () => noGit,
281
+ noUnitAt: () => noUnitAt,
282
+ normalizeText: () => normalizeText,
283
+ normalizeWhitespace: () => normalizeWhitespace,
284
+ offsetOfLine: () => offsetOfLine,
285
+ orphanRefusal: () => orphanRefusal,
286
+ ownedMessage: () => ownedMessage,
287
+ paragraphAfter: () => paragraphAfter,
288
+ parseCiteConfig: () => parseCiteConfig,
289
+ parseLines: () => parseLines,
290
+ parseSrc: () => parseSrc,
291
+ parseStatements: () => parseStatements,
292
+ pickExtractor: () => pickExtractor,
293
+ pinOfLines: () => pinOfLines,
294
+ pre43Span: () => pre43Span,
295
+ rangeLines: () => rangeLines,
296
+ readCiteConfigFile: () => readCiteConfigFile,
297
+ readPage: () => readPage,
298
+ readSource: () => readSource,
299
+ reencryptCitationEntries: () => reencryptCitationEntries,
300
+ reencryptCitations: () => reencryptCitations,
301
+ refineClaim: () => refineClaim,
302
+ refusalLine: () => refusalLine,
303
+ removalLine: () => removalLine,
304
+ removeFrontmatterCitations: () => removeFrontmatterCitations,
305
+ removeLine: () => removeLine,
306
+ renderCheckGithub: () => renderCheckGithub,
307
+ renderCheckJson: () => renderCheckJson,
308
+ renderCheckPretty: () => renderCheckPretty,
309
+ renderRemoveJson: () => renderRemoveJson,
310
+ renderRemovePretty: () => renderRemovePretty,
311
+ renderUpdateJson: () => renderUpdateJson,
312
+ renderUpdatePretty: () => renderUpdatePretty,
313
+ resolveCiteRun: () => resolveCiteRun,
314
+ resolveSeverity: () => resolveSeverity,
315
+ rewriteLine: () => rewriteLine,
316
+ ruleId: () => ruleId,
317
+ runAdd: () => runAdd,
318
+ runCheck: () => runCheck,
319
+ runRemove: () => runRemove,
320
+ runUpdate: () => runUpdate,
321
+ runsHolding: () => runsHolding,
322
+ sentencesOf: () => sentencesOf,
323
+ sharesSentence: () => sharesSentence,
324
+ shiftedEntries: () => shiftedEntries,
325
+ shortCommit: () => shortCommit,
326
+ shortLine: () => shortLine,
327
+ shortPin: () => shortPin,
328
+ shortSrc: () => shortSrc,
329
+ sidecarsFor: () => sidecarsFor,
330
+ sliceLines: () => sliceLines,
331
+ sourceRange: () => sourceRange,
332
+ spellAt: () => spellAt,
333
+ spellLines: () => spellLines,
334
+ spellSource: () => spellSource,
335
+ splice: () => splice,
336
+ spliceEntryField: () => spliceEntryField,
337
+ splitLines: () => splitLines,
338
+ splitUnit: () => splitUnit,
339
+ statementForms: () => statementForms,
340
+ stripMarkers: () => stripMarkers,
341
+ toBodyLines: () => toBodyLines,
342
+ toFileLines: () => toFileLines,
343
+ toValidationResult: () => toValidationResult,
344
+ twoManifestsRefusal: () => twoManifestsRefusal,
345
+ unifiedDiff: () => unifiedDiff,
346
+ unitAt: () => unitAt,
347
+ unitText: () => unitText,
348
+ urlManifestRefusal: () => urlManifestRefusal,
349
+ validateEntry: () => validateEntry,
350
+ withClaimLines: () => withClaimLines
351
+ });
352
+
353
+ // src/cite/core/reencrypt.ts
354
+ var UNDECRYPTABLE = "does not decrypt under the current key";
355
+ var MISSING = "missing (no tracked file matches)";
356
+ var CHANGED = "changed; run `manni cite update --accept` before rotating";
357
+ function whereOf(citation, origin) {
358
+ const where = { index: origin.index };
359
+ if (citation.id !== void 0) where.id = citation.id;
360
+ if (origin.line !== void 0) where.line = origin.line;
361
+ return where;
362
+ }
363
+ async function pinnedLines(ctx, citation, range, path, key) {
364
+ const source = await readSource(ctx.root, ctx.index, { ...range, path, encrypted: false });
365
+ if (source.kind === "missing") return { skip: MISSING };
366
+ const pin = citation.source.integrity;
367
+ let joined;
368
+ try {
369
+ joined = sliceLines(splitLines(source.text), range);
370
+ } catch {
371
+ joined = void 0;
372
+ }
373
+ if (joined !== void 0 && hashLines(joined, key) === pin) return { joined };
374
+ const commit = citation.source["commit-sha"];
375
+ if (commit !== void 0 && await ctx.git.available()) {
376
+ const history = await historyOf(ctx.git, commit, path, range, pin, key, void 0);
377
+ if (history.kind === "original") return { joined: history.lines.join("\n") };
378
+ }
379
+ return { skip: CHANGED };
380
+ }
381
+ async function verdictFor(ctx, citation, opts) {
382
+ const range = sourceRange(citation.source);
383
+ const underNew = decryptSourcePath(range.path, opts.toKey);
384
+ if (underNew !== void 0) {
385
+ const held = await pinnedLines(ctx, citation, range, underNew, opts.toKey);
386
+ if ("joined" in held) return { kind: "done" };
387
+ }
388
+ const path = underNew ?? decryptSourcePath(range.path, opts.fromKey);
389
+ if (path === void 0) return { kind: "skip", message: UNDECRYPTABLE };
390
+ const lines = await pinnedLines(ctx, citation, range, path, opts.fromKey);
391
+ if ("skip" in lines) return { kind: "skip", message: lines.skip };
392
+ const file = underNew === void 0 ? encryptSourcePath(path, opts.toKey) : range.path;
393
+ return {
394
+ kind: "write",
395
+ file,
396
+ integrity: hashLines(lines.joined, opts.toKey),
397
+ to: formatSrc({ ...range, path: file })
398
+ };
399
+ }
400
+ async function contextFor(opts) {
401
+ const git = opts.gitClient ?? gitClient(opts.root);
402
+ const index = opts.sourceIndex ?? await buildSourceIndex(opts.root, { gitClient: git });
403
+ return { root: opts.root, index, git };
404
+ }
405
+ async function reencryptCitations(page, opts) {
406
+ const read = readPage(page.file, page.content, page.format === void 0 ? void 0 : { format: page.format });
407
+ const result = { content: page.content, rewritten: [], skipped: [] };
408
+ const encrypted = read.citations.filter(({ citation }) => sourceRange(citation.source).encrypted);
409
+ if (encrypted.length === 0) return result;
410
+ const ctx = await contextFor(opts);
411
+ let after = page.content;
412
+ for (const { citation, origin } of encrypted) {
413
+ const range = sourceRange(citation.source);
414
+ const where = whereOf(citation, origin);
415
+ const verdict = await verdictFor(ctx, citation, opts);
416
+ if (verdict.kind === "done") continue;
417
+ if (verdict.kind === "skip") {
418
+ result.skipped.push({ ...where, message: verdict.message });
419
+ continue;
420
+ }
421
+ if (verdict.file !== range.path) {
422
+ after = spliceEntryField(after, read.format, origin.index, ["source", "file"], verdict.file);
423
+ }
424
+ after = spliceEntryField(
425
+ after,
426
+ read.format,
427
+ origin.index,
428
+ ["source", "integrity"],
429
+ verdict.integrity
430
+ );
431
+ result.rewritten.push({ ...where, from: spellSource(citation.source), to: verdict.to });
432
+ }
433
+ result.content = after;
434
+ return result;
435
+ }
436
+ async function reencryptCitationEntries(page, opts) {
437
+ const entries = JSON.parse(
438
+ JSON.stringify(page.citations.map((input) => input.entry))
439
+ );
440
+ const out = { entries, changed: false, rewritten: [], skipped: [] };
441
+ const read = readPage(page.file, page.content, {
442
+ ...page.format === void 0 ? {} : { format: page.format },
443
+ citations: page.citations
444
+ });
445
+ const encrypted = read.citations.filter(({ citation }) => sourceRange(citation.source).encrypted);
446
+ if (encrypted.length === 0) return out;
447
+ const ctx = await contextFor(opts);
448
+ for (const { citation, origin } of encrypted) {
449
+ const where = whereOf(citation, origin);
450
+ const verdict = await verdictFor(ctx, citation, opts);
451
+ if (verdict.kind === "done") continue;
452
+ if (verdict.kind === "skip") {
453
+ out.skipped.push({ ...where, message: verdict.message });
454
+ continue;
455
+ }
456
+ const entry = entries[origin.index];
457
+ const source = typeof entry === "object" && entry !== null && !Array.isArray(entry) ? entry.source : void 0;
458
+ if (typeof source !== "object" || source === null || Array.isArray(source)) {
459
+ out.skipped.push({ ...where, message: UNDECRYPTABLE });
460
+ continue;
461
+ }
462
+ const fields = source;
463
+ fields.file = verdict.file;
464
+ fields.integrity = verdict.integrity;
465
+ out.changed = true;
466
+ out.rewritten.push({ ...where, from: spellSource(citation.source), to: verdict.to });
467
+ }
468
+ return out;
469
+ }
470
+
471
+ // src/key/errors.ts
472
+ var KeyError = class extends ToolError {
473
+ constructor(message) {
474
+ super(message);
475
+ this.name = "KeyError";
476
+ }
477
+ };
478
+
479
+ // src/key/commands/rotate.ts
480
+ import { existsSync } from "node:fs";
481
+ import { readFile } from "node:fs/promises";
482
+ import { isAbsolute, join, relative, resolve, sep } from "node:path";
483
+ import { parse as parseYaml } from "yaml";
484
+
485
+ // src/key/core/config.ts
486
+ var toKeyError = (message) => new KeyError(message);
487
+ var KEY_CONFIG = {
488
+ section: "key",
489
+ // The key never had a file of its own.
490
+ legacyNames: [],
491
+ toError: toKeyError
492
+ };
493
+ function readRotateConfig(configPath, cwd) {
494
+ return configPath === void 0 ? findConfigFile(cwd, KEY_CONFIG) : readConfigFile(configPath, cwd, KEY_CONFIG);
495
+ }
496
+ function readSetConfig(configPath, cwd) {
497
+ return configPath === void 0 ? findFamilyConfigFile(cwd, toKeyError) : readFamilyConfigFile(configPath, cwd, toKeyError);
498
+ }
499
+ var unfinishedRotation = (source) => `A rotation is unfinished in ${source}. Run \`manni key rotate\` with no --to to finish it.`;
500
+
501
+ // src/key/commands/rotate.ts
502
+ var BAD_TO = "--to must be at least 32 hex or base64url characters.";
503
+ var NO_STDIN = "key rotate reads and writes files, so it takes no stdin (`-`). Name the files instead.";
504
+ var WITH_PATHS = "--collection selects a configured collection; it cannot be combined with paths.";
505
+ var NEEDS_CONFIG = "--collection needs a config file to select from.";
506
+ var NO_KEY = "No encryption key is available, so nothing can be re-encrypted. Run `manni key set` first.";
507
+ var ENV_NEEDS_TO = "The key comes from MANNI_ENCRYPTION_KEY; pass --to <value>, re-encrypt with it, then update the secret. Nothing is written to config.";
508
+ var NARROWED_NEEDS_TO = "A run over part of the family needs --to, and never writes the key.";
509
+ var NO_FILES = "No files to re-encrypt. Pass paths/globs, or declare a collection under `collections:` in manni.config.yaml.";
510
+ var ANY_CIPHERTEXT = /~[A-Za-z0-9_-]{82,}/;
511
+ function citeSection(file) {
512
+ if (file === null) return {};
513
+ const doc = parseYaml(file.text);
514
+ if (typeof doc !== "object" || doc === null || !("cite" in doc)) return {};
515
+ return parseCiteConfig(doc.cite, file.source);
516
+ }
517
+ function rootFor(flag, cite, file, cwd) {
518
+ if (flag !== void 0) return { root: resolve(cwd, flag), fellBack: false };
519
+ if (file !== null && cite.root !== void 0) {
520
+ return { root: resolve(file.dir, cite.root), fellBack: false };
521
+ }
522
+ const gitRoot = findGitRoot(cwd);
523
+ return gitRoot === null ? { root: cwd, fellBack: true } : { root: gitRoot, fellBack: false };
524
+ }
525
+ function isEnoent(error) {
526
+ return typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT";
527
+ }
528
+ async function indexFor(root, client) {
529
+ try {
530
+ return await buildSourceIndex(root, { gitClient: client });
531
+ } catch (error) {
532
+ if (isEnoent(error)) throw new KeyError(`Root directory not found: ${root}.`);
533
+ throw error;
534
+ }
535
+ }
536
+ function encryptedCitations(file, content, format) {
537
+ const read = readPage(file, content, format === void 0 ? void 0 : { format });
538
+ const encrypted = read.citations.filter(({ citation }) => sourceRange(citation.source).encrypted);
539
+ return {
540
+ any: encrypted.length > 0,
541
+ withCommit: encrypted.some(({ citation }) => citation.source["commit-sha"] !== void 0)
542
+ };
543
+ }
544
+ async function rotateManifestCitations(sidecars, manifests, page, opts) {
545
+ const none = { rewritten: [], skipped: [], wantsHistory: false };
546
+ if (sidecars === null) return none;
547
+ const sidecar = await sidecars.forPage(page.file, page.content, page.format);
548
+ const owner = sidecar.owner;
549
+ if (owner === void 0 || sidecar.citations === void 0) return none;
550
+ if (!sidecar.citations.some((input) => ANY_CIPHERTEXT.test(JSON.stringify(input.entry)))) {
551
+ return none;
552
+ }
553
+ const result = await reencryptCitationEntries(
554
+ { ...page, citations: sidecar.citations },
555
+ {
556
+ root: opts.root,
557
+ fromKey: opts.fromKey,
558
+ toKey: opts.toKey,
559
+ gitClient: opts.gitClient,
560
+ sourceIndex: await opts.sourceIndex()
561
+ }
562
+ );
563
+ if (result.changed && sidecar.entry !== void 0) {
564
+ await manifests.write(owner, sidecar.entry, result.entries, 0);
565
+ }
566
+ return {
567
+ rewritten: result.rewritten.map((r) => ({ kind: "citation", ...r })),
568
+ skipped: result.skipped.map((s) => ({ kind: "citation", ...s })),
569
+ // A pin that no longer holds is re-keyed from the lines at its commit.
570
+ wantsHistory: sidecar.citations.some(
571
+ (input) => /"commit-sha"\s*:/.test(JSON.stringify(input.entry))
572
+ )
573
+ };
574
+ }
575
+ function reportedPath(abs, base) {
576
+ const rel = relative(base, abs);
577
+ return rel === "" ? "." : rel.split(sep).join("/");
578
+ }
579
+ function manifestCollections(collections, opts) {
580
+ if (opts.fromCollections) return [...collections];
581
+ const rels = opts.files.map(
582
+ (rel) => reportedPath(resolve(opts.base, rel), opts.configDir)
583
+ );
584
+ return collections.filter((c) => rels.some((rel) => isMember(c, rel)));
585
+ }
586
+ function valuesOf(index, entry) {
587
+ const empty = /* @__PURE__ */ new Map();
588
+ if (entry.join === PATH_JOIN) {
589
+ return entry.abs === void 0 ? empty : index.byPath.get(entry.abs) ?? empty;
590
+ }
591
+ return index.byField.get(entry.join)?.get(entry.spelled) ?? empty;
592
+ }
593
+ async function planManifests(opts) {
594
+ const local = opts.collections.map((c) => ({
595
+ ...c,
596
+ externalMetadata: c.externalMetadata.filter(
597
+ (m) => classifyRef(m.file).kind !== "url"
598
+ )
599
+ })).filter((c) => c.externalMetadata.length > 0);
600
+ if (local.length === 0) return [];
601
+ const pages = new Set(opts.pages);
602
+ if (opts.whole) {
603
+ for (const c of local) {
604
+ for (const m of c.externalMetadata) {
605
+ if (!hasPagePlaceholder(m.file)) continue;
606
+ for (const found of findPageManifests(m.file, opts.configDir, (rel) => isMember(c, rel))) {
607
+ for (const entry of found.entries) pages.add(entry.pageAbs);
608
+ }
609
+ }
610
+ }
611
+ }
612
+ const index = await loadExternalMetadata(local, {
613
+ configDir: opts.configDir,
614
+ base: opts.base,
615
+ pages: [...pages]
616
+ });
617
+ if (index === null) return [];
618
+ const plans = /* @__PURE__ */ new Map();
619
+ const located = /* @__PURE__ */ new Map();
620
+ const locate = (collection, abs, join3) => {
621
+ located.set(`${collection}\0${reportedPath(abs, opts.base)}\0${join3}`, { abs, collection });
622
+ };
623
+ for (const c of local) {
624
+ for (const m of c.externalMetadata) {
625
+ const join3 = externalMetadataJoin(m);
626
+ if (!hasPagePlaceholder(m.file)) {
627
+ locate(c.name, isAbsolute(m.file) ? m.file : resolve(opts.configDir, m.file), join3);
628
+ continue;
629
+ }
630
+ for (const page of pages) {
631
+ const resolved = pageManifestPath(m.file, opts.configDir, page);
632
+ if (!("outside" in resolved)) locate(c.name, resolved.abs, join3);
633
+ }
634
+ }
635
+ }
636
+ const planFor = async (key) => {
637
+ const where = located.get(key);
638
+ if (where === void 0) return void 0;
639
+ const known = plans.get(where.abs);
640
+ if (known !== void 0) return known;
641
+ const plan = {
642
+ manifest: {
643
+ file: reportedPath(where.abs, opts.base),
644
+ collection: where.collection,
645
+ rewritten: [],
646
+ skipped: [],
647
+ written: false
648
+ },
649
+ path: where.abs,
650
+ text: await readFile(where.abs, "utf8"),
651
+ changed: false
652
+ };
653
+ plans.set(where.abs, plan);
654
+ return plan;
655
+ };
656
+ for (const entry of index.entries) {
657
+ const plan = await planFor(`${entry.collection}\0${entry.file}\0${entry.join}`);
658
+ if (plan === void 0) continue;
659
+ const data = {};
660
+ for (const [key, supplied] of valuesOf(index, entry)) {
661
+ if (supplied.file === entry.file && supplied.collection === entry.collection) {
662
+ data[key] = supplied.value;
663
+ }
664
+ }
665
+ const done = reencryptData(data, { fromKey: opts.fromKey, toKey: opts.toKey });
666
+ for (const r of done.rewritten) {
667
+ plan.manifest.rewritten.push({ entry: entry.spelled, ...r });
668
+ }
669
+ for (const s of done.skipped) {
670
+ plan.manifest.skipped.push({ entry: entry.spelled, ...s });
671
+ }
672
+ for (const key of done.keys) {
673
+ plan.text = spliceManifestValue(plan.text, {
674
+ entry: entry.spelled,
675
+ key,
676
+ value: done.data[key],
677
+ join: entry.join,
678
+ file: plan.manifest.file
679
+ }).text;
680
+ plan.changed = true;
681
+ }
682
+ }
683
+ return [...plans.values()].filter(
684
+ (p) => p.manifest.rewritten.length > 0 || p.manifest.skipped.length > 0
685
+ );
686
+ }
687
+ async function runKeyRotate(opts) {
688
+ const cwd = resolve(opts.cwd ?? process.cwd());
689
+ const env = opts.env ?? process.env;
690
+ if (opts.to !== void 0 && !isValidEncryptionKey(opts.to)) throw new KeyError(BAD_TO);
691
+ if (opts.inputs.includes(STDIN_TOKEN)) throw new KeyError(NO_STDIN);
692
+ const wanted = opts.collection ?? [];
693
+ if (wanted.length > 0 && opts.inputs.length > 0) throw new KeyError(WITH_PATHS);
694
+ const file = await readRotateConfig(opts.configPath, cwd);
695
+ if (wanted.length > 0 && file === null) throw new KeyError(NEEDS_CONFIG);
696
+ const { key: current, source: keySource } = resolveEncryptionKey({
697
+ env,
698
+ file,
699
+ toError: toKeyError
700
+ });
701
+ if (current === void 0) throw new KeyError(NO_KEY);
702
+ const narrowed = opts.inputs.length > 0 || wanted.length > 0;
703
+ const keyFile = keySource === "config" ? file : null;
704
+ const previous = keyFile?.encryptionKeyPrevious;
705
+ if (keyFile !== null && previous !== void 0 && (narrowed || opts.to !== void 0 && opts.to !== current)) {
706
+ throw new KeyError(unfinishedRotation(keyFile.source));
707
+ }
708
+ if (keySource === "env" && opts.to === void 0) throw new KeyError(ENV_NEEDS_TO);
709
+ if (narrowed && opts.to === void 0) throw new KeyError(NARROWED_NEEDS_TO);
710
+ const fromKey = previous ?? current;
711
+ const toKey = previous === void 0 ? opts.to ?? generateEncryptionKey() : current;
712
+ const collections = file === null ? [] : selectCollections(file.collections, wanted, file.source, toKeyError);
713
+ const fromCollections = opts.inputs.length === 0;
714
+ const inputs = fromCollections ? collections.flatMap((c) => c.paths) : opts.inputs;
715
+ if (inputs.length === 0) throw new KeyError(NO_FILES);
716
+ const base = fromCollections && file !== null ? file.dir : cwd;
717
+ const forced = opts.as === void 0 ? void 0 : extractorByName(opts.as);
718
+ if (opts.as !== void 0 && forced === void 0) {
719
+ throw new KeyError(
720
+ `Unknown format "${opts.as}". Supported extensions: ${supportedExtensions().join(", ")}.`
721
+ );
722
+ }
723
+ const format = forced?.name;
724
+ const exts = opts.exts ?? forced?.extensions;
725
+ const exclude = [
726
+ .../* @__PURE__ */ new Set([
727
+ ...opts.exclude ?? [],
728
+ ...fromCollections ? collections.flatMap((c) => c.exclude) : []
729
+ ])
730
+ ];
731
+ const { files, gitignoreSkipped } = await resolveTargetSet({
732
+ inputs,
733
+ exts,
734
+ exclude,
735
+ cwd: base,
736
+ allowEmpty: opts.allowEmpty,
737
+ ...gitignoreOptions({ flag: opts.respectGitignore, onNotice: opts.onNotice })
738
+ });
739
+ assertNonEmpty({
740
+ files,
741
+ inputs,
742
+ usingStdin: false,
743
+ allowEmpty: opts.allowEmpty,
744
+ exclude,
745
+ exts,
746
+ gitignoreSkipped,
747
+ action: "re-encrypted"
748
+ });
749
+ const cite = citeSection(file);
750
+ const { root, fellBack } = rootFor(opts.root, cite, file, cwd);
751
+ const client = opts.gitClient ?? gitClient(root);
752
+ let index;
753
+ const sourceIndex = () => {
754
+ if (index === void 0) {
755
+ if (fellBack) opts.onNotice?.(`No git root found; resolving src: paths from ${cwd}`);
756
+ index = indexFor(root, client);
757
+ }
758
+ return index;
759
+ };
760
+ const sidecars = file === null ? null : await loadCitationSidecars({
761
+ collections: file.collections,
762
+ configDir: file.dir,
763
+ base,
764
+ configSource: file.source,
765
+ key: current,
766
+ toError: toKeyError,
767
+ // A keyless manifest (proposal 0068) keeps what a page's schemas mark.
768
+ marks: () => configMarks(file.path, file.dir),
769
+ // A `{page}` manifest (0058) is read for exactly the pages rotated.
770
+ pages: files.map((rel) => resolve(base, rel))
771
+ });
772
+ const manifests = new ManifestSet();
773
+ const planned = [];
774
+ let wantsHistory = false;
775
+ for (const rel of files) {
776
+ const path = resolve(base, rel);
777
+ const before = await readFile(path, "utf8");
778
+ const page = { file: rel, content: before, ...format === void 0 ? {} : { format } };
779
+ const sidecarWork = await rotateManifestCitations(sidecars, manifests, page, {
780
+ root,
781
+ fromKey,
782
+ toKey,
783
+ gitClient: client,
784
+ sourceIndex
785
+ });
786
+ if (sidecarWork.wantsHistory) wantsHistory = true;
787
+ if (!ANY_CIPHERTEXT.test(before)) {
788
+ if (sidecarWork.rewritten.length === 0 && sidecarWork.skipped.length === 0) continue;
789
+ planned.push({
790
+ page: { file: rel, rewritten: sidecarWork.rewritten, skipped: sidecarWork.skipped, written: false },
791
+ path,
792
+ content: before,
793
+ changed: false
794
+ });
795
+ continue;
796
+ }
797
+ const meta = reencryptMetadata(page, { fromKey, toKey });
798
+ const encrypted = encryptedCitations(rel, meta.content, format);
799
+ if (encrypted.withCommit) wantsHistory = true;
800
+ const cited = encrypted.any ? await reencryptCitations(
801
+ { ...page, content: meta.content },
802
+ { root, fromKey, toKey, gitClient: client, sourceIndex: await sourceIndex() }
803
+ ) : { content: meta.content, rewritten: [], skipped: [] };
804
+ const rewritten = [
805
+ ...meta.rewritten.map((r) => ({ kind: "metadata", ...r })),
806
+ ...cited.rewritten.map((r) => ({ kind: "citation", ...r })),
807
+ ...sidecarWork.rewritten
808
+ ];
809
+ const skipped2 = [
810
+ ...meta.skipped.map((s) => ({ kind: "metadata", ...s })),
811
+ ...cited.skipped.map((s) => ({ kind: "citation", ...s })),
812
+ ...sidecarWork.skipped
813
+ ];
814
+ if (rewritten.length === 0 && skipped2.length === 0) continue;
815
+ planned.push({
816
+ page: { file: rel, rewritten, skipped: skipped2, written: false },
817
+ path,
818
+ content: cited.content,
819
+ changed: cited.content !== before
820
+ });
821
+ }
822
+ if (wantsHistory && !await client.available()) opts.onNotice?.(GIT_UNAVAILABLE_HISTORY);
823
+ const valueManifests = file === null ? [] : await planManifests({
824
+ collections: manifestCollections(collections, {
825
+ fromCollections,
826
+ files,
827
+ base,
828
+ configDir: file.dir
829
+ }),
830
+ configDir: file.dir,
831
+ base,
832
+ fromKey,
833
+ toKey,
834
+ pages: files.map((rel) => resolve(base, rel)),
835
+ whole: !narrowed
836
+ });
837
+ const reencrypted = planned.reduce((n, p) => n + p.page.rewritten.length, 0) + valueManifests.reduce((n, m) => n + m.manifest.rewritten.length, 0);
838
+ const skipped = planned.reduce((n, p) => n + p.page.skipped.length, 0) + valueManifests.reduce((n, m) => n + m.manifest.skipped.length, 0);
839
+ const writePage = opts.writePage ?? ((path, content) => writeFileAtomic(path, content));
840
+ let outcome;
841
+ if (skipped > 0) {
842
+ outcome = "skipped";
843
+ } else if (opts.dryRun === true) {
844
+ outcome = "dry-run";
845
+ } else {
846
+ const writesKey = !narrowed && keyFile !== null;
847
+ if (!narrowed && keyFile !== null && previous === void 0) {
848
+ await writeEncryptionKey({ file: keyFile, key: toKey, previous: fromKey, cwd, toError: toKeyError });
849
+ }
850
+ for (const p of planned) {
851
+ if (!p.changed) continue;
852
+ await writePage(p.path, p.content);
853
+ p.page.written = true;
854
+ }
855
+ for (const changed of manifests.changed()) await writePage(changed.path, changed.text);
856
+ for (const m of valueManifests) {
857
+ if (!m.changed) continue;
858
+ await writePage(m.path, m.text);
859
+ m.manifest.written = true;
860
+ }
861
+ if (!narrowed && keyFile !== null) {
862
+ await writeEncryptionKey({ file: keyFile, key: toKey, previous: null, cwd, toError: toKeyError });
863
+ }
864
+ if (narrowed) outcome = "narrowed";
865
+ else if (!writesKey) outcome = "env";
866
+ else outcome = previous === void 0 ? "written" : "finished";
867
+ }
868
+ const wrote = outcome !== "skipped" && outcome !== "dry-run";
869
+ const baseline = file !== null && cite.baseline !== void 0 ? resolve(file.dir, cite.baseline) : join(file?.dir ?? cwd, DEFAULT_CITE_BASELINE_PATH);
870
+ return {
871
+ pages: planned.map((p) => p.page),
872
+ manifests: valueManifests.map((m) => m.manifest),
873
+ reencrypted,
874
+ skipped,
875
+ keyWritten: outcome === "written" || outcome === "finished",
876
+ outcome,
877
+ ...keyFile === null ? {} : { configSource: keyFile.source },
878
+ baselineStale: wrote && existsSync(baseline),
879
+ exitCode: skipped > 0 ? 1 : 0
880
+ };
881
+ }
882
+
883
+ // src/key/commands/set.ts
884
+ import { existsSync as existsSync2 } from "node:fs";
885
+ import { basename, dirname, join as join2, relative as relative2, resolve as resolve2 } from "node:path";
886
+ var BAD_VALUE = "The key must be at least 32 hex or base64url characters. Run `manni key set` with no value to generate one.";
887
+ var ENV_SET = `${ENCRYPTION_KEY_ENV} is set, so a key written to config would never be read. Unset it, or keep the key in the secret.`;
888
+ var alreadyConfigured = (source) => `An encryption key is already configured in ${source}. Run \`manni key rotate\` to replace it and re-encrypt every value.`;
889
+ function refuseBesideLegacy(path, cwd) {
890
+ const dir = dirname(path);
891
+ const name = basename(path);
892
+ for (const legacy of LEGACY_CONFIG_NAMES) {
893
+ const found = join2(dir, legacy);
894
+ if (!existsSync2(found)) continue;
895
+ const source = relative2(cwd, found).replace(/\\/g, "/");
896
+ throw new KeyError(
897
+ `${source} is a single-tool config; a ${name} beside it would hide it. Move its keys under meta: in ${name} first.`
898
+ );
899
+ }
900
+ }
901
+ async function runKeySet(opts) {
902
+ const cwd = resolve2(opts.cwd ?? process.cwd());
903
+ const env = opts.env ?? process.env;
904
+ if (opts.value !== void 0 && !isValidEncryptionKey(opts.value)) {
905
+ throw new KeyError(BAD_VALUE);
906
+ }
907
+ const fromEnv = env[ENCRYPTION_KEY_ENV];
908
+ if (fromEnv !== void 0 && fromEnv !== "") throw new KeyError(ENV_SET);
909
+ const file = await readSetConfig(opts.configPath, cwd);
910
+ if (file?.encryptionKeyPrevious !== void 0) {
911
+ throw new KeyError(unfinishedRotation(file.source));
912
+ }
913
+ if (file?.encryptionKey !== void 0) {
914
+ throw new KeyError(alreadyConfigured(file.source));
915
+ }
916
+ const generated = opts.value === void 0;
917
+ const key = opts.value ?? generateEncryptionKey();
918
+ const dryRun = opts.dryRun === true;
919
+ const target = await writeEncryptionKey({ file, key, cwd, toError: toKeyError, dryRun: true });
920
+ if (target.created) refuseBesideLegacy(target.path, cwd);
921
+ if (isIgnoredByGit(target.path) === false) {
922
+ opts.onNotice?.(committedKeyWarning(target.source));
923
+ }
924
+ if (!dryRun) await writeEncryptionKey({ file, key, cwd, toError: toKeyError });
925
+ return { path: target.path, source: target.source, created: target.created, generated, dryRun };
926
+ }
927
+
928
+ export {
929
+ cite_exports,
930
+ KeyError,
931
+ runKeyRotate,
932
+ runKeySet
933
+ };
934
+ //# sourceMappingURL=chunk-MWJLZMBL.js.map