@hawkeyexl/manni 2.3.8 → 2.3.10

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.
package/README.md CHANGED
@@ -98,7 +98,7 @@ actually reads rather than hand-written:
98
98
  ```yaml
99
99
  repos:
100
100
  - repo: https://github.com/hawkeyexl/manni
101
- rev: v2.3.8
101
+ rev: v2.3.10
102
102
  hooks:
103
103
  - id: manni-meta
104
104
  ```
@@ -70,7 +70,7 @@ import {
70
70
  withValueAt,
71
71
  writeEncryptionKey,
72
72
  writeFileAtomic
73
- } from "./chunk-EYD2RYKV.js";
73
+ } from "./chunk-TNT3ZROC.js";
74
74
 
75
75
  // src/meta/core/reencrypt.ts
76
76
  import { extname } from "node:path";
@@ -260,6 +260,7 @@ __export(cite_exports, {
260
260
  runCheck: () => runCheck,
261
261
  runUpdate: () => runUpdate,
262
262
  shortCommit: () => shortCommit,
263
+ shortLine: () => shortLine,
263
264
  shortPin: () => shortPin,
264
265
  shortSrc: () => shortSrc,
265
266
  sidecarsFor: () => sidecarsFor,
@@ -420,6 +421,11 @@ function shortSrc(src) {
420
421
  const lines = colon === -1 ? "" : src.slice(colon);
421
422
  return token.length <= 5 ? src : `${token.slice(0, 5)}\u2026${lines}`;
422
423
  }
424
+ var LINE_WIDTH = 60;
425
+ function shortLine(text) {
426
+ const one = text.replace(/\s+/g, " ").trim();
427
+ return one.length <= LINE_WIDTH ? one : `${one.slice(0, LINE_WIDTH)}\u2026`;
428
+ }
423
429
 
424
430
  // src/cite/core/sources.ts
425
431
  import fg from "fast-glob";
@@ -2594,7 +2600,8 @@ async function resolveCiteRun(opts) {
2594
2600
  const cwd = resolve2(opts.cwd);
2595
2601
  const env = opts.env ?? process.env;
2596
2602
  const wanted = opts.collection ?? [];
2597
- if (wanted.length > 0 && opts.inputs.some((input) => input !== STDIN)) {
2603
+ const typedInputs = opts.inputs.filter((input) => input !== STDIN);
2604
+ if (wanted.length > 0 && typedInputs.length > 0) {
2598
2605
  throw new CiteError(
2599
2606
  "--collection selects a configured collection; it cannot be combined with paths."
2600
2607
  );
@@ -2607,9 +2614,10 @@ async function resolveCiteRun(opts) {
2607
2614
  if (loaded) opts.onConfigLoaded?.({ path: loaded.path, dir: loaded.dir });
2608
2615
  const config = loaded ? loaded.config : null;
2609
2616
  const collections = loaded ? selectCollections(loaded.collections, wanted, loaded.source, (message) => new CiteError(message)) : [];
2610
- const fromCollections = opts.inputs.length === 0;
2611
- const inputs = fromCollections ? collections.flatMap((c) => c.paths) : opts.inputs;
2612
- const base = fromCollections && inputs.length > 0 && loaded ? loaded.dir : cwd;
2617
+ const fromCollections = wanted.length > 0 || opts.inputs.length === 0;
2618
+ const collectionPaths = fromCollections ? collections.flatMap((c) => c.paths) : [];
2619
+ const inputs = fromCollections ? [...opts.inputs, ...collectionPaths] : opts.inputs;
2620
+ const base = collectionPaths.length > 0 && loaded ? loaded.dir : cwd;
2613
2621
  let root;
2614
2622
  if (opts.root !== void 0) {
2615
2623
  root = resolve2(cwd, opts.root);
@@ -2864,6 +2872,50 @@ async function citedText(root, index, src, key) {
2864
2872
  function spellAt(lines) {
2865
2873
  return lines.start === lines.end ? `line ${String(lines.start)}` : `lines ${String(lines.start)}-${String(lines.end)}`;
2866
2874
  }
2875
+ function entryName(entry) {
2876
+ return entry.citation.id ?? `/citations/${String(entry.origin.index)}`;
2877
+ }
2878
+ function duplicateOf(page, src, pageLines) {
2879
+ const wanted = formatSrc(parseSrc(src));
2880
+ return page.citations.find((entry) => {
2881
+ const { citation } = entry;
2882
+ if (spellSource(citation.source) !== wanted) return false;
2883
+ if (pageLines === void 0) return citation.claim === void 0;
2884
+ const spec = citation.claim?.lines;
2885
+ if (spec === void 0) return false;
2886
+ const recorded = parseLines(spec);
2887
+ if (recorded === void 0) return false;
2888
+ const file = toFileLines(recorded, page.bodyLine);
2889
+ return file.start === pageLines.start && file.end === pageLines.end;
2890
+ });
2891
+ }
2892
+ function holdsNoText(text) {
2893
+ return text.trim() === "" || ANY_FENCE.test(text);
2894
+ }
2895
+ function emptyClaimRefusal(lines, pageLines, at2) {
2896
+ const span = lines.slice(pageLines.start - 1, pageLines.end);
2897
+ if (span.some((text) => !holdsNoText(text))) return void 0;
2898
+ if (pageLines.start !== pageLines.end) return `${at2} holds no claim text.`;
2899
+ const only = span[0] ?? "";
2900
+ return only.trim() === "" ? `${at2} is blank.` : `${at2} is a fence line, not claim text.`;
2901
+ }
2902
+ function otherClaimSpans(lines, pageLines, pin, bodyLine) {
2903
+ const width = pageLines.end - pageLines.start + 1;
2904
+ const found = findWindows(lines.slice(bodyLine - 1), width, pin, void 0, {
2905
+ around: toBodyLines(pageLines, bodyLine).start
2906
+ });
2907
+ return found.starts.map((start) => toFileLines({ start, end: start + width - 1 }, bodyLine)).filter((span) => span.start !== pageLines.start);
2908
+ }
2909
+ var NAMED_SPANS = 3;
2910
+ function spellElsewhere(spans) {
2911
+ const first = spans[0];
2912
+ const noun = spans.length === 1 && first !== void 0 && first.start === first.end ? "line" : "lines";
2913
+ const named3 = spans.slice(0, NAMED_SPANS).map((span) => spellLines(span));
2914
+ const rest = spans.length - named3.length;
2915
+ if (rest > 0) return `${noun} ${named3.join(", ")} and ${String(rest)} more`;
2916
+ const last = named3.pop() ?? "";
2917
+ return named3.length === 0 ? `${noun} ${last}` : `${noun} ${named3.join(", ")} and ${last}`;
2918
+ }
2867
2919
  function shiftedEntries(citations, insertLine, bodyLine, label) {
2868
2920
  const out = { frontmatter: [], manifest: /* @__PURE__ */ new Map() };
2869
2921
  for (const { citation, origin } of citations) {
@@ -2962,6 +3014,12 @@ async function runAdd(opts) {
2962
3014
  );
2963
3015
  }
2964
3016
  }
3017
+ const duplicate = marker ? void 0 : duplicateOf(page, opts.src, pageLines);
3018
+ if (duplicate !== void 0) {
3019
+ const src = shortSrc(spellSource(duplicate.citation.source));
3020
+ const what = pageLines === void 0 ? `a bare pin for ${src}` : `an entry for ${spellAt(pageLines)} and ${src}`;
3021
+ throw new CiteError(`${label} already has ${what} (${entryName(duplicate)}).`);
3022
+ }
2965
3023
  const lines = splitLines(content);
2966
3024
  if (pageLines !== void 0) {
2967
3025
  if (pageLines.end > lines.length) {
@@ -2975,6 +3033,9 @@ async function runAdd(opts) {
2975
3033
  if (span === void 0 || span.end !== pageLines.end) {
2976
3034
  throw new CiteError(`${at2} is not a fenced block, so it cannot be a quote.`);
2977
3035
  }
3036
+ } else if (!marker) {
3037
+ const empty = emptyClaimRefusal(lines, pageLines, at2);
3038
+ if (empty !== void 0) throw new CiteError(empty);
2978
3039
  }
2979
3040
  }
2980
3041
  const client = opts.gitClient ?? gitClient(root);
@@ -2983,6 +3044,7 @@ async function runAdd(opts) {
2983
3044
  let markerAt;
2984
3045
  let claimSpan;
2985
3046
  let claim;
3047
+ let elsewhere = [];
2986
3048
  let shifted = { frontmatter: [], manifest: /* @__PURE__ */ new Map() };
2987
3049
  if (marker && pageLines !== void 0) {
2988
3050
  const holding = unitHolding(content, pageLines.start, format, {
@@ -3025,6 +3087,7 @@ async function runAdd(opts) {
3025
3087
  }
3026
3088
  claimSpan = pageLines;
3027
3089
  claim = { lines: lineSpec(toBodyLines(pageLines, page.bodyLine)), integrity: pin };
3090
+ elsewhere = otherClaimSpans(lines, pageLines, pin, page.bodyLine);
3028
3091
  }
3029
3092
  const mint = (key, encrypt) => mintCitation({
3030
3093
  root,
@@ -3061,6 +3124,12 @@ async function runAdd(opts) {
3061
3124
  });
3062
3125
  citation = await mint(key, true);
3063
3126
  }
3127
+ const srcRange = parseSrc(opts.src);
3128
+ let sourceLine;
3129
+ if (srcRange.start !== void 0 && !isEncryptedValue(citation.source.file)) {
3130
+ const read = await readSource(root, sourceIndex, srcRange, void 0);
3131
+ if (read.kind === "ok") sourceLine = splitLines(read.text)[srcRange.start - 1];
3132
+ }
3064
3133
  const manifests = new ManifestSet();
3065
3134
  let placed;
3066
3135
  if (owner !== void 0) {
@@ -3093,6 +3162,7 @@ async function runAdd(opts) {
3093
3162
  content: after,
3094
3163
  diff: unifiedDiff(label, content, after),
3095
3164
  written: false,
3165
+ ...sourceLine === void 0 ? {} : { sourceLine },
3096
3166
  ...placed === void 0 ? {} : { manifest: placed }
3097
3167
  };
3098
3168
  if (markerAt !== void 0) result.markerLine = markerAt + shift;
@@ -3105,6 +3175,13 @@ async function runAdd(opts) {
3105
3175
  for (const changed of manifests.changed()) await writeFileAtomic(changed.path, changed.text);
3106
3176
  result.manifest.written = true;
3107
3177
  }
3178
+ if (elsewhere.length > 0) {
3179
+ const named3 = elsewhere.map((span) => ({ start: span.start + shift, end: span.end + shift }));
3180
+ const who = citation.id === void 0 ? "" : `${citation.id}: `;
3181
+ opts.onNotice?.(
3182
+ `${who}the claim's text also appears at ${spellElsewhere(named3)}, so a move would be ambiguous. Use --marker, or pin more lines.`
3183
+ );
3184
+ }
3108
3185
  if (opts.commitSha !== false && !await client.available()) {
3109
3186
  opts.onNotice?.(GIT_UNAVAILABLE_COMMIT);
3110
3187
  }
@@ -3831,7 +3908,7 @@ var NAMES_ITS_SUBJECT = /* @__PURE__ */ new Set([
3831
3908
  "marker-repeated",
3832
3909
  "anchor-invalid"
3833
3910
  ]);
3834
- function annotationMessage(finding2) {
3911
+ function findingMessage(finding2) {
3835
3912
  const subject = finding2.id ?? finding2.src;
3836
3913
  if (subject === void 0) return finding2.message;
3837
3914
  if (NAMES_ITS_SUBJECT.has(finding2.rule)) return finding2.message;
@@ -3849,7 +3926,7 @@ function renderCheckGithub(run3) {
3849
3926
  if (site.line !== void 0) params.push(`line=${String(site.line)}`);
3850
3927
  params.push(`title=${escapeWorkflowCommandProperty(finding2.ruleId)}`);
3851
3928
  lines.push(
3852
- `::${finding2.severity} ${params.join(",")}::${escapeWorkflowCommandMessage(annotationMessage(finding2))}`
3929
+ `::${finding2.severity} ${params.join(",")}::${escapeWorkflowCommandMessage(findingMessage(finding2))}`
3853
3930
  );
3854
3931
  }
3855
3932
  });
@@ -4285,15 +4362,20 @@ export {
4285
4362
  codeEndAt,
4286
4363
  CiteError,
4287
4364
  asCiteError,
4365
+ RULE_ID_PREFIX,
4366
+ isCiteRule,
4288
4367
  spellSource,
4289
- runAdd,
4290
- runCheck,
4291
- runUpdate,
4292
4368
  shortPin,
4293
4369
  shortCommit,
4294
4370
  shortSrc,
4371
+ shortLine,
4372
+ runAdd,
4373
+ errorSite,
4374
+ runCheck,
4375
+ runUpdate,
4295
4376
  renderCheckPretty,
4296
4377
  renderUpdatePretty,
4378
+ findingMessage,
4297
4379
  renderCheckGithub,
4298
4380
  renderCheckJson,
4299
4381
  renderUpdateJson,
@@ -4302,4 +4384,4 @@ export {
4302
4384
  runKeyRotate,
4303
4385
  runKeySet
4304
4386
  };
4305
- //# sourceMappingURL=chunk-TIZE6GXU.js.map
4387
+ //# sourceMappingURL=chunk-LORLZO3J.js.map