@refrakt-md/runes 0.35.0 → 0.37.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 (63) hide show
  1. package/dist/file-ref-resolve.d.ts.map +1 -1
  2. package/dist/file-ref-resolve.js +36 -1
  3. package/dist/file-ref-resolve.js.map +1 -1
  4. package/dist/index.d.ts +11 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +13 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/lang-map.d.ts.map +1 -1
  9. package/dist/lang-map.js +8 -0
  10. package/dist/lang-map.js.map +1 -1
  11. package/dist/lib/anchor.d.ts +73 -0
  12. package/dist/lib/anchor.d.ts.map +1 -0
  13. package/dist/lib/anchor.js +521 -0
  14. package/dist/lib/anchor.js.map +1 -0
  15. package/dist/lib/component.d.ts +1 -1
  16. package/dist/lib/component.d.ts.map +1 -1
  17. package/dist/lib/invocation.d.ts +22 -0
  18. package/dist/lib/invocation.d.ts.map +1 -0
  19. package/dist/lib/invocation.js +67 -0
  20. package/dist/lib/invocation.js.map +1 -0
  21. package/dist/lib/languages.d.ts +163 -0
  22. package/dist/lib/languages.d.ts.map +1 -0
  23. package/dist/lib/languages.js +383 -0
  24. package/dist/lib/languages.js.map +1 -0
  25. package/dist/lib/line-diff.d.ts +35 -0
  26. package/dist/lib/line-diff.d.ts.map +1 -0
  27. package/dist/lib/line-diff.js +77 -0
  28. package/dist/lib/line-diff.js.map +1 -0
  29. package/dist/lib/mask.d.ts +116 -0
  30. package/dist/lib/mask.d.ts.map +1 -0
  31. package/dist/lib/mask.js +378 -0
  32. package/dist/lib/mask.js.map +1 -0
  33. package/dist/lib/node.d.ts +1 -1
  34. package/dist/lib/node.d.ts.map +1 -1
  35. package/dist/lib/present.d.ts +73 -0
  36. package/dist/lib/present.d.ts.map +1 -0
  37. package/dist/lib/present.js +127 -0
  38. package/dist/lib/present.js.map +1 -0
  39. package/dist/lib/read-file.d.ts +21 -1
  40. package/dist/lib/read-file.d.ts.map +1 -1
  41. package/dist/lib/read-file.js +46 -0
  42. package/dist/lib/read-file.js.map +1 -1
  43. package/dist/lib/renderable.d.ts +7 -3
  44. package/dist/lib/renderable.d.ts.map +1 -1
  45. package/dist/lib/renderable.js +2 -2
  46. package/dist/lib/renderable.js.map +1 -1
  47. package/dist/lib/review-marker.d.ts +113 -0
  48. package/dist/lib/review-marker.d.ts.map +1 -0
  49. package/dist/lib/review-marker.js +173 -0
  50. package/dist/lib/review-marker.js.map +1 -0
  51. package/dist/snippet-pipeline.d.ts.map +1 -1
  52. package/dist/snippet-pipeline.js +70 -2
  53. package/dist/snippet-pipeline.js.map +1 -1
  54. package/dist/tags/diff.d.ts.map +1 -1
  55. package/dist/tags/diff.js +1 -38
  56. package/dist/tags/diff.js.map +1 -1
  57. package/dist/tags/file-ref.d.ts.map +1 -1
  58. package/dist/tags/file-ref.js +59 -1
  59. package/dist/tags/file-ref.js.map +1 -1
  60. package/dist/tags/snippet.d.ts.map +1 -1
  61. package/dist/tags/snippet.js +53 -2
  62. package/dist/tags/snippet.js.map +1 -1
  63. package/package.json +3 -3
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Anchor-native presentation (SPEC-131 D13 + D16; WORK-589).
3
+ *
4
+ * Anchoring makes nested targets easy for the first time — a class method, a
5
+ * key inside `"scripts"`, a rule inside `@media`, a step under `jobs:`. Two
6
+ * existing attributes were defined in terms of `lines=` and stop making sense
7
+ * under an anchor, and one new attribute is needed because the old form
8
+ * re-couples the invocation to the coordinates anchoring exists to decouple it
9
+ * from.
10
+ *
11
+ * **These are deliberately separate entry points, not folded into extraction.**
12
+ * Two later items need to call the pipeline at a chosen point and an inlined
13
+ * transform does not allow it:
14
+ *
15
+ * - WORK-590's codemod verifies a rewritten invocation produces a
16
+ * **byte-identical** slice, and that comparison runs **before** `reindent` —
17
+ * otherwise every nested target fails verification for a difference the
18
+ * codemod itself introduced.
19
+ * - WORK-591's review-marker hash applies `reindent` **first**, so that moving
20
+ * a function into a class — which shifts every line two columns without
21
+ * changing a character of content — does not fire the marker.
22
+ *
23
+ * The ordering is easy to get backwards and produces a confusing failure in
24
+ * each direction, which is why it is stated on both sides.
25
+ */
26
+ /**
27
+ * Strip the slice's common leading whitespace.
28
+ *
29
+ * Removing the *common* prefix preserves relative structure exactly, so the
30
+ * result stays valid in indentation-significant languages: a dedented Python
31
+ * method is a function, a dedented YAML subtree is that subtree rooted.
32
+ *
33
+ * Blank lines are ignored when measuring the prefix — a blank line inside a
34
+ * block is not evidence that the block is flush left — and are emitted as
35
+ * empty rather than as whatever whitespace they happened to carry.
36
+ *
37
+ * Tabs and spaces are compared as characters, not as widths: a slice mixing
38
+ * them has no common prefix to strip, and guessing a tab width in order to
39
+ * manufacture one would change bytes the author did not ask to change.
40
+ */
41
+ export declare function reindent(content: string): string;
42
+ /**
43
+ * Whether `reindent` applies, given the addressing mode and the attribute.
44
+ *
45
+ * **The default follows the addressing mode** (D16), for the same reason D9's
46
+ * does. An author writing `lines="10-40"` has seen the file and chosen those
47
+ * columns; changing how they render would be a silent visual change to every
48
+ * existing line-addressed invocation. An author writing `symbol="…"` never saw
49
+ * a column number — the resolver picked the region, so it owns presenting it
50
+ * legibly.
51
+ */
52
+ export declare function shouldReindent(anchored: boolean, attr: boolean | undefined): boolean;
53
+ /**
54
+ * Line numbers within a slice whose text matches any of the given regexes.
55
+ *
56
+ * The anchor-native form of `highlight` (D13). A *numeric* highlight under an
57
+ * anchor is no longer something an author can write from knowledge — the
58
+ * resolver chose the region — so this matches on content instead.
59
+ *
60
+ * Returns 1-based offsets **within the slice**, which is what the fence's
61
+ * `highlight` attribute expects once `linenumbers` has supplied the file
62
+ * offset.
63
+ *
64
+ * @param content The resolved slice.
65
+ * @param patterns One or more regex sources.
66
+ */
67
+ export declare function highlightMatchLines(content: string, patterns: string[]): number[];
68
+ /** Parse a `highlight-match` attribute into regex sources. Comma-separated,
69
+ * because an attribute is a string and authors reach for a list. */
70
+ export declare function parseHighlightMatch(raw: string | undefined): string[];
71
+ /** Render a list of 1-based slice offsets as the fence's `highlight` value. */
72
+ export declare function formatHighlight(lines: number[]): string;
73
+ //# sourceMappingURL=present.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"present.d.ts","sourceRoot":"","sources":["../../src/lib/present.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CA0BhD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,CAEpF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAajF;AAED;qEACqE;AACrE,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,EAAE,CAMrE;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAEvD"}
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Anchor-native presentation (SPEC-131 D13 + D16; WORK-589).
3
+ *
4
+ * Anchoring makes nested targets easy for the first time — a class method, a
5
+ * key inside `"scripts"`, a rule inside `@media`, a step under `jobs:`. Two
6
+ * existing attributes were defined in terms of `lines=` and stop making sense
7
+ * under an anchor, and one new attribute is needed because the old form
8
+ * re-couples the invocation to the coordinates anchoring exists to decouple it
9
+ * from.
10
+ *
11
+ * **These are deliberately separate entry points, not folded into extraction.**
12
+ * Two later items need to call the pipeline at a chosen point and an inlined
13
+ * transform does not allow it:
14
+ *
15
+ * - WORK-590's codemod verifies a rewritten invocation produces a
16
+ * **byte-identical** slice, and that comparison runs **before** `reindent` —
17
+ * otherwise every nested target fails verification for a difference the
18
+ * codemod itself introduced.
19
+ * - WORK-591's review-marker hash applies `reindent` **first**, so that moving
20
+ * a function into a class — which shifts every line two columns without
21
+ * changing a character of content — does not fire the marker.
22
+ *
23
+ * The ordering is easy to get backwards and produces a confusing failure in
24
+ * each direction, which is why it is stated on both sides.
25
+ */
26
+ /**
27
+ * Strip the slice's common leading whitespace.
28
+ *
29
+ * Removing the *common* prefix preserves relative structure exactly, so the
30
+ * result stays valid in indentation-significant languages: a dedented Python
31
+ * method is a function, a dedented YAML subtree is that subtree rooted.
32
+ *
33
+ * Blank lines are ignored when measuring the prefix — a blank line inside a
34
+ * block is not evidence that the block is flush left — and are emitted as
35
+ * empty rather than as whatever whitespace they happened to carry.
36
+ *
37
+ * Tabs and spaces are compared as characters, not as widths: a slice mixing
38
+ * them has no common prefix to strip, and guessing a tab width in order to
39
+ * manufacture one would change bytes the author did not ask to change.
40
+ */
41
+ export function reindent(content) {
42
+ const lines = content.split('\n');
43
+ let prefix;
44
+ for (const line of lines) {
45
+ if (line.trim().length === 0)
46
+ continue;
47
+ const indent = line.slice(0, line.length - line.trimStart().length);
48
+ if (prefix === undefined) {
49
+ prefix = indent;
50
+ continue;
51
+ }
52
+ // Shrink to the longest shared prefix.
53
+ let i = 0;
54
+ while (i < prefix.length && i < indent.length && prefix[i] === indent[i])
55
+ i++;
56
+ prefix = prefix.slice(0, i);
57
+ if (prefix.length === 0)
58
+ break;
59
+ }
60
+ if (prefix === undefined || prefix.length === 0)
61
+ return content;
62
+ return lines
63
+ .map((line) => {
64
+ if (line.trim().length === 0)
65
+ return '';
66
+ return line.startsWith(prefix) ? line.slice(prefix.length) : line.trimStart();
67
+ })
68
+ .join('\n');
69
+ }
70
+ /**
71
+ * Whether `reindent` applies, given the addressing mode and the attribute.
72
+ *
73
+ * **The default follows the addressing mode** (D16), for the same reason D9's
74
+ * does. An author writing `lines="10-40"` has seen the file and chosen those
75
+ * columns; changing how they render would be a silent visual change to every
76
+ * existing line-addressed invocation. An author writing `symbol="…"` never saw
77
+ * a column number — the resolver picked the region, so it owns presenting it
78
+ * legibly.
79
+ */
80
+ export function shouldReindent(anchored, attr) {
81
+ return attr ?? anchored;
82
+ }
83
+ /**
84
+ * Line numbers within a slice whose text matches any of the given regexes.
85
+ *
86
+ * The anchor-native form of `highlight` (D13). A *numeric* highlight under an
87
+ * anchor is no longer something an author can write from knowledge — the
88
+ * resolver chose the region — so this matches on content instead.
89
+ *
90
+ * Returns 1-based offsets **within the slice**, which is what the fence's
91
+ * `highlight` attribute expects once `linenumbers` has supplied the file
92
+ * offset.
93
+ *
94
+ * @param content The resolved slice.
95
+ * @param patterns One or more regex sources.
96
+ */
97
+ export function highlightMatchLines(content, patterns) {
98
+ const compiled = [];
99
+ for (const raw of patterns) {
100
+ if (raw.length === 0)
101
+ continue;
102
+ compiled.push(new RegExp(raw));
103
+ }
104
+ if (compiled.length === 0)
105
+ return [];
106
+ const hits = [];
107
+ content.split('\n').forEach((line, i) => {
108
+ if (compiled.some((re) => re.test(line)))
109
+ hits.push(i + 1);
110
+ });
111
+ return hits;
112
+ }
113
+ /** Parse a `highlight-match` attribute into regex sources. Comma-separated,
114
+ * because an attribute is a string and authors reach for a list. */
115
+ export function parseHighlightMatch(raw) {
116
+ if (typeof raw !== 'string' || raw.trim().length === 0)
117
+ return [];
118
+ return raw
119
+ .split(',')
120
+ .map((s) => s.trim())
121
+ .filter((s) => s.length > 0);
122
+ }
123
+ /** Render a list of 1-based slice offsets as the fence's `highlight` value. */
124
+ export function formatHighlight(lines) {
125
+ return lines.join(',');
126
+ }
127
+ //# sourceMappingURL=present.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"present.js","sourceRoot":"","sources":["../../src/lib/present.ts"],"names":[],"mappings":"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"}
@@ -14,14 +14,29 @@
14
14
  * runes package tree-shakable for browser bundles.
15
15
  */
16
16
  import type { ProjectFiles } from '@refrakt-md/types';
17
+ import { type AnchorOptions } from './anchor.js';
17
18
  /** Diagnostics from a single read. */
18
19
  export interface ReadFileResult {
19
- /** Resolved file content (possibly sliced by `lines`). */
20
+ /** Resolved file content (possibly sliced by `lines` or by an anchor). */
20
21
  content: string;
21
22
  /** Project-root-relative POSIX path — what `data-snippet-source` carries. */
22
23
  relativePath: string;
23
24
  /** Warnings the preprocess hook should surface (e.g., end-clamp). */
24
25
  warnings: string[];
26
+ /**
27
+ * 1-indexed inclusive start line of the slice, in **file** coordinates.
28
+ *
29
+ * The coordinate frame survives anchoring on purpose (D13): `linenumbers`
30
+ * keeps starting at the real line and numeric `highlight` keeps meaning
31
+ * file lines, so the displayed numbers stay a usable pointer back into the
32
+ * file. Undefined only when the whole file was returned.
33
+ */
34
+ start?: number;
35
+ /** 1-indexed inclusive end line, in file coordinates. */
36
+ end?: number;
37
+ /** Whether the slice was located by anchor rather than by `lines=`. Drives
38
+ * the `reindent` and `doc` defaults, which follow the addressing mode. */
39
+ anchored: boolean;
25
40
  }
26
41
  export interface ReadFileOptions {
27
42
  /** The project's files, rooted at the project root. Reads go through this. */
@@ -33,6 +48,11 @@ export interface ReadFileOptions {
33
48
  /** Optional source-page context used in error messages
34
49
  * ("Referenced from: docs/getting-started.md:42"). */
35
50
  referencingPage?: string;
51
+ /** Optional anchor attributes — `symbol`, `match`, `extent` and friends.
52
+ * Mutually exclusive with `lines`. */
53
+ anchor?: AnchorOptions;
54
+ /** Optional explicit language id, overriding extension inference. */
55
+ lang?: string;
36
56
  }
37
57
  /** Range parsed from the `lines=` attribute. */
38
58
  interface LineRange {
@@ -1 +1 @@
1
- {"version":3,"file":"read-file.d.ts","sourceRoot":"","sources":["../../src/lib/read-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC9B,0DAA0D;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,eAAe;IAC/B,8EAA8E;IAC9E,KAAK,EAAE,YAAY,CAAC;IACpB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;2DACuD;IACvD,eAAe,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,gDAAgD;AAChD,UAAU,SAAS;IAClB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED;uDACuD;AACvD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,CA2CxE;AAED;;gBAEgB;AAChB,wBAAgB,YAAY,CAC3B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,GAAG,IAAI,GACrB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAuBxC;AAED;;iFAEiF;AACjF,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,cAAc,CAiBrE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC5C,KAAK,EAAE,YAAY,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAQT;AAED;oDACoD;AACpD,qBAAa,mBAAoB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI3B"}
1
+ {"version":3,"file":"read-file.d.ts","sourceRoot":"","sources":["../../src/lib/read-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,KAAK,aAAa,EAAwC,MAAM,aAAa,CAAC;AAGvF,sCAAsC;AACtC,MAAM,WAAW,cAAc;IAC9B,0EAA0E;IAC1E,OAAO,EAAE,MAAM,CAAC;IAChB,6EAA6E;IAC7E,YAAY,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,yDAAyD;IACzD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;+EAC2E;IAC3E,QAAQ,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC/B,8EAA8E;IAC9E,KAAK,EAAE,YAAY,CAAC;IACpB,2EAA2E;IAC3E,QAAQ,EAAE,MAAM,CAAC;IACjB,+EAA+E;IAC/E,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;2DACuD;IACvD,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;2CACuC;IACvC,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB,qEAAqE;IACrE,IAAI,CAAC,EAAE,MAAM,CAAC;CACd;AAED,gDAAgD;AAChD,UAAU,SAAS;IAClB,yEAAyE;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,mEAAmE;IACnE,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED;uDACuD;AACvD,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,IAAI,CA2CxE;AAED;;gBAEgB;AAChB,wBAAgB,YAAY,CAC3B,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,GAAG,IAAI,GACrB;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,EAAE,CAAA;CAAE,CAuBxC;AAED;;iFAEiF;AACjF,wBAAgB,eAAe,CAAC,IAAI,EAAE,eAAe,GAAG,cAAc,CAoErE;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE;IAC5C,KAAK,EAAE,YAAY,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;CACrB,GAAG,MAAM,CAQT;AAED;oDACoD;AACpD,qBAAa,mBAAoB,SAAQ,KAAK;gBACjC,OAAO,EAAE,MAAM;CAI3B"}
@@ -13,6 +13,8 @@
13
13
  * No `node:fs` import — all I/O goes through the provider, which keeps the
14
14
  * runes package tree-shakable for browser bundles.
15
15
  */
16
+ import { AnchorResolutionError, resolveAnchor } from './anchor.js';
17
+ import { resolveLanguage } from './languages.js';
16
18
  /** Parse a `lines=` attribute. Returns null when the attribute is empty/absent;
17
19
  * throws `SnippetSandboxError` on malformed input. */
18
20
  export function parseLineRange(raw) {
@@ -83,12 +85,56 @@ export function readSnippetFile(opts) {
83
85
  const referenced = opts.referencingPage ? `\n\nReferenced from: ${opts.referencingPage}` : '';
84
86
  throw new SnippetSandboxError(`snippet path "${opts.pathAttr}" cannot be resolved — the file is missing, not a regular file, or outside the project root.${referenced}`);
85
87
  }
88
+ const anchor = opts.anchor;
89
+ const hasAnchor = anchor !== undefined &&
90
+ ((typeof anchor.symbol === 'string' && anchor.symbol.length > 0) ||
91
+ (typeof anchor.match === 'string' && anchor.match.length > 0));
92
+ const hasLines = typeof opts.lines === 'string' && opts.lines.length > 0;
93
+ if (hasAnchor && hasLines) {
94
+ throw new SnippetSandboxError(`snippet "${opts.pathAttr}" sets both \`lines\` and an anchor (\`symbol\`/\`match\`), ` +
95
+ 'which are mutually exclusive — an anchor names a region and `lines` addresses one by ' +
96
+ 'coordinate. Remove one.');
97
+ }
98
+ if (hasAnchor) {
99
+ const lang = resolveLanguage(opts.lang ?? opts.pathAttr);
100
+ let resolved;
101
+ try {
102
+ resolved = resolveAnchor(rawContent, lang, anchor, opts.pathAttr);
103
+ }
104
+ catch (err) {
105
+ // One failure channel. D6: resolution failures raise
106
+ // `SnippetSandboxError`, which the existing path turns into an error
107
+ // fence plus a `ctx.error` diagnostic. No new channel.
108
+ if (err instanceof AnchorResolutionError) {
109
+ const referenced = opts.referencingPage
110
+ ? `\n\nReferenced from: ${opts.referencingPage}`
111
+ : '';
112
+ throw new SnippetSandboxError(`snippet ${err.message}${referenced}`);
113
+ }
114
+ throw err;
115
+ }
116
+ const allLines = rawContent.split('\n');
117
+ return {
118
+ content: allLines.slice(resolved.start - 1, resolved.end).join('\n'),
119
+ relativePath: opts.pathAttr,
120
+ warnings: resolved.warnings,
121
+ start: resolved.start,
122
+ end: resolved.end,
123
+ anchored: true,
124
+ };
125
+ }
86
126
  const range = parseLineRange(opts.lines);
87
127
  const { sliced, warnings } = sliceContent(rawContent, range);
128
+ const total = rawContent.split('\n').length;
129
+ const start = range ? (range.start ?? 1) : undefined;
130
+ const end = range ? Math.min(range.end ?? total, total) : undefined;
88
131
  return {
89
132
  content: sliced,
90
133
  relativePath: opts.pathAttr,
91
134
  warnings,
135
+ start,
136
+ end,
137
+ anchored: false,
92
138
  };
93
139
  }
94
140
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"read-file.js","sourceRoot":"","sources":["../../src/lib/read-file.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"read-file.js","sourceRoot":"","sources":["../../src/lib/read-file.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAGH,OAAO,EAAsB,qBAAqB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACvF,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAmDjD;uDACuD;AACvD,MAAM,UAAU,cAAc,CAAC,GAAuB;IACrD,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,EAAE;QAAE,OAAO,IAAI,CAAC;IACjE,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;QAC7B,MAAM,IAAI,mBAAmB,CAC5B,qDAAqD,OAAO,GAAG,EAAE,CACjE,CAAC;IACH,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC;IAC3B,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEtC,+BAA+B;IAC/B,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;QAC1B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;YAC/B,MAAM,IAAI,mBAAmB,CAAC,4BAA4B,GAAG,6BAA6B,CAAC,CAAC;QAC7F,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC;IAC7B,CAAC;IAED,0BAA0B;IAC1B,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxC,IAAI,CAAC,CAAC,EAAE,CAAC;QACR,MAAM,IAAI,mBAAmB,CAC5B,4BAA4B,GAAG,oDAAoD,CACnF,CAAC;IACH,CAAC;IACD,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACpB,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACjE,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAC3D,IAAI,KAAK,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,CAAC,EAAE,CAAC;QACnE,MAAM,IAAI,mBAAmB,CAC5B,4BAA4B,QAAQ,6BAA6B,CACjE,CAAC;IACH,CAAC;IACD,IAAI,GAAG,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC;QAC7D,MAAM,IAAI,mBAAmB,CAAC,0BAA0B,MAAM,6BAA6B,CAAC,CAAC;IAC9F,CAAC;IACD,IAAI,KAAK,KAAK,SAAS,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,KAAK,EAAE,CAAC;QAC7D,MAAM,IAAI,mBAAmB,CAC5B,4BAA4B,GAAG,kCAAkC,CACjE,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;AACvB,CAAC;AAED;;gBAEgB;AAChB,MAAM,UAAU,YAAY,CAC3B,OAAe,EACf,KAAuB;IAEvB,IAAI,KAAK,KAAK,IAAI;QAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;IAE7D,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAClC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC;IAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;IACnC,IAAI,OAAO,GAAG,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC;IACjC,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,IAAI,SAAS,GAAG,KAAK,EAAE,CAAC;QACvB,MAAM,IAAI,mBAAmB,CAC5B,2BAA2B,SAAS,yBAAyB,KAAK,SAAS,CAC3E,CAAC;IACH,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,EAAE,CAAC;QACrB,QAAQ,CAAC,IAAI,CAAC,yBAAyB,OAAO,oCAAoC,KAAK,EAAE,CAAC,CAAC;QAC3F,OAAO,GAAG,KAAK,CAAC;IACjB,CAAC;IAED,2EAA2E;IAC3E,gFAAgF;IAChF,MAAM,MAAM,GAAG,KAAK,CAAC,KAAK,CAAC,SAAS,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC9D,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;AAC7B,CAAC;AAED;;iFAEiF;AACjF,MAAM,UAAU,eAAe,CAAC,IAAqB;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAClD,IAAI,UAAU,KAAK,IAAI,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,wBAAwB,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9F,MAAM,IAAI,mBAAmB,CAC5B,iBAAiB,IAAI,CAAC,QAAQ,+FAA+F,UAAU,EAAE,CACzI,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;IAC3B,MAAM,SAAS,GACd,MAAM,KAAK,SAAS;QACpB,CAAC,CAAC,OAAO,MAAM,CAAC,MAAM,KAAK,QAAQ,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;YAC/D,CAAC,OAAO,MAAM,CAAC,KAAK,KAAK,QAAQ,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC;IACjE,MAAM,QAAQ,GAAG,OAAO,IAAI,CAAC,KAAK,KAAK,QAAQ,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAEzE,IAAI,SAAS,IAAI,QAAQ,EAAE,CAAC;QAC3B,MAAM,IAAI,mBAAmB,CAC5B,YAAY,IAAI,CAAC,QAAQ,8DAA8D;YACtF,uFAAuF;YACvF,yBAAyB,CAC1B,CAAC;IACH,CAAC;IAED,IAAI,SAAS,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,QAAQ,CAAC,CAAC;QACzD,IAAI,QAA0C,CAAC;QAC/C,IAAI,CAAC;YACJ,QAAQ,GAAG,aAAa,CAAC,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;QACnE,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,qDAAqD;YACrD,qEAAqE;YACrE,uDAAuD;YACvD,IAAI,GAAG,YAAY,qBAAqB,EAAE,CAAC;gBAC1C,MAAM,UAAU,GAAG,IAAI,CAAC,eAAe;oBACtC,CAAC,CAAC,wBAAwB,IAAI,CAAC,eAAe,EAAE;oBAChD,CAAC,CAAC,EAAE,CAAC;gBACN,MAAM,IAAI,mBAAmB,CAAC,WAAW,GAAG,CAAC,OAAO,GAAG,UAAU,EAAE,CAAC,CAAC;YACtE,CAAC;YACD,MAAM,GAAG,CAAC;QACX,CAAC;QAED,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACxC,OAAO;YACN,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,GAAG,CAAC,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;YACpE,YAAY,EAAE,IAAI,CAAC,QAAQ;YAC3B,QAAQ,EAAE,QAAQ,CAAC,QAAQ;YAC3B,KAAK,EAAE,QAAQ,CAAC,KAAK;YACrB,GAAG,EAAE,QAAQ,CAAC,GAAG;YACjB,QAAQ,EAAE,IAAI;SACd,CAAC;IACH,CAAC;IAED,MAAM,KAAK,GAAG,cAAc,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACzC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,YAAY,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAE7D,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IAC5C,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACrD,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAEpE,OAAO;QACN,OAAO,EAAE,MAAM;QACf,YAAY,EAAE,IAAI,CAAC,QAAQ;QAC3B,QAAQ;QACR,KAAK;QACL,GAAG;QACH,QAAQ,EAAE,KAAK;KACf,CAAC;AACH,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAGtC;IACA,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAC/C,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;QAClB,MAAM,IAAI,mBAAmB,CAC5B,gBAAgB,IAAI,CAAC,YAAY,uFAAuF,CACxH,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED;oDACoD;AACpD,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC7C,YAAY,OAAe;QAC1B,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAC;IACnC,CAAC;CACD"}
@@ -1,6 +1,6 @@
1
1
  import Markdoc from '@markdoc/markdoc';
2
2
  import type { Tag, RenderableTreeNode } from '@markdoc/markdoc';
3
- import { NodeType } from '@refrakt-md/types';
3
+ import type { NodeType } from '@refrakt-md/types';
4
4
  export declare class RenderableNodeCursor<T extends RenderableTreeNode = RenderableTreeNode> {
5
5
  readonly nodes: T[];
6
6
  private offset;
@@ -11,8 +11,12 @@ export declare class RenderableNodeCursor<T extends RenderableTreeNode = Rendera
11
11
  tags<TagNames extends NodeType[]>(...tags: TagNames): RenderableNodeCursor<Tag<TagNames[number]>>;
12
12
  headings(): RenderableNodeCursor<Markdoc.Tag<"h1" | "h2" | "h3" | "h4" | "h5" | "h6", Record<string, any>>>;
13
13
  typeof(type: string): RenderableNodeCursor<T>;
14
- concat(...other: (RenderableTreeNode | RenderableNodeCursor)[]): RenderableNodeCursor<Markdoc.RenderableTreeNode>;
15
- flatten(): RenderableNodeCursor<Markdoc.RenderableTreeNode | (T extends readonly (infer InnerArr)[] ? InnerArr : T)>;
14
+ concat(...other: (RenderableTreeNode | RenderableNodeCursor)[]): RenderableNodeCursor<string | number | boolean | Markdoc.Scalar[] | {
15
+ [key: string]: Markdoc.Scalar;
16
+ } | Markdoc.Tag<string, Record<string, any>> | null>;
17
+ flatten(): RenderableNodeCursor<string | number | boolean | Markdoc.Scalar[] | {
18
+ [key: string]: Markdoc.Scalar;
19
+ } | Markdoc.Tag<string, Record<string, any>> | null>;
16
20
  limit(count: number): RenderableNodeCursor<T>;
17
21
  slice(start: number, end?: number): RenderableNodeCursor<T>;
18
22
  toArray(): T[];
@@ -1 +1 @@
1
- {"version":3,"file":"renderable.d.ts","sourceRoot":"","sources":["../../src/lib/renderable.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAI7C,qBAAa,oBAAoB,CAAC,CAAC,SAAS,kBAAkB,GAAG,kBAAkB;aAGtD,KAAK,EAAE,CAAC,EAAE;IAFtC,OAAO,CAAC,MAAM,CAAK;gBAES,KAAK,EAAE,CAAC,EAAE;IAEtC,MAAM,CAAC,QAAQ,CAAC,OAAO,SAAS,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO;IAIjE,IAAI,CAAC,OAAO,SAAS,MAAM,EAC1B,GAAG,EAAE,OAAO,EACZ,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAClC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAIrC,GAAG,CAAC,OAAO,SAAS,QAAQ,EAAE,GAAG,EAAE,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAO/E,IAAI,CAAC,QAAQ,SAAS,QAAQ,EAAE,EAC/B,GAAG,IAAI,EAAE,QAAQ,GACf,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAO9C,QAAQ;IAIR,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CAAC,CAAC,CAAC;IAQ7C,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC,kBAAkB,GAAG,oBAAoB,CAAC,EAAE;IAK9D,OAAO;IAKP,KAAK,CAAC,KAAK,EAAE,MAAM;IAInB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM;IAIjC,OAAO,IAAI,CAAC,EAAE;IAId,KAAK,IAAI,MAAM;IAIf,IAAI,IAAI,CAAC;CAGT"}
1
+ {"version":3,"file":"renderable.d.ts","sourceRoot":"","sources":["../../src/lib/renderable.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,kBAAkB,CAAC;AACvC,OAAO,KAAK,EAAE,GAAG,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAIlD,qBAAa,oBAAoB,CAAC,CAAC,SAAS,kBAAkB,GAAG,kBAAkB;aAGtD,KAAK,EAAE,CAAC,EAAE;IAFtC,OAAO,CAAC,MAAM,CAAK;gBAES,KAAK,EAAE,CAAC,EAAE;IAEtC,MAAM,CAAC,QAAQ,CAAC,OAAO,SAAS,QAAQ,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO;IAIjE,IAAI,CAAC,OAAO,SAAS,MAAM,EAC1B,GAAG,EAAE,OAAO,EACZ,UAAU,GAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAM,GAClC,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAIrC,GAAG,CAAC,OAAO,SAAS,QAAQ,EAAE,GAAG,EAAE,OAAO,GAAG,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAO/E,IAAI,CAAC,QAAQ,SAAS,QAAQ,EAAE,EAC/B,GAAG,IAAI,EAAE,QAAQ,GACf,oBAAoB,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;IAO9C,QAAQ;IAIR,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,oBAAoB,CAAC,CAAC,CAAC;IAQ7C,MAAM,CAAC,GAAG,KAAK,EAAE,CAAC,kBAAkB,GAAG,oBAAoB,CAAC,EAAE;;;IAK9D,OAAO;;;IAKP,KAAK,CAAC,KAAK,EAAE,MAAM;IAInB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM;IAIjC,OAAO,IAAI,CAAC,EAAE;IAId,KAAK,IAAI,MAAM;IAIf,IAAI,IAAI,CAAC;CAGT"}
@@ -27,11 +27,11 @@ export class RenderableNodeCursor {
27
27
  return new RenderableNodeCursor(this.nodes.filter((n) => Markdoc.Tag.isTag(n) && n.attributes['data-rune'] === toKebabCase(type)));
28
28
  }
29
29
  concat(...other) {
30
- const nodes = other.map((o) => (o instanceof RenderableNodeCursor ? o.nodes : o)).flat();
30
+ const nodes = other.flatMap((o) => (o instanceof RenderableNodeCursor ? o.nodes : o));
31
31
  return new RenderableNodeCursor([...this.nodes, ...nodes]);
32
32
  }
33
33
  flatten() {
34
- const nodes = this.nodes.map((t) => (Markdoc.Tag.isTag(t) ? Array.from(walkTag(t)) : t)).flat();
34
+ const nodes = this.nodes.flatMap((t) => (Markdoc.Tag.isTag(t) ? Array.from(walkTag(t)) : t));
35
35
  return new RenderableNodeCursor(nodes);
36
36
  }
37
37
  limit(count) {
@@ -1 +1 @@
1
- {"version":3,"file":"renderable.js","sourceRoot":"","sources":["../../src/lib/renderable.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"renderable.js","sourceRoot":"","sources":["../../src/lib/renderable.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Review markers for embedded source (SPEC-134, WORK-591).
3
+ *
4
+ * SPEC-131 answers *am I quoting the right region*. This answers the next
5
+ * question up: **the region is right, and the prose around it no longer
6
+ * describes what is in it.**
7
+ *
8
+ * A field is removed, a default flips, a parameter is reordered — the anchor
9
+ * resolves perfectly, the code block renders real current code, and the
10
+ * paragraph above it quietly becomes false. That is the *ordinary* case,
11
+ * because editing a declaration is far more common than renaming or moving one.
12
+ *
13
+ * ```markdoc
14
+ * {% snippet path="packages/types/src/config.ts" symbol="SiteConfig" reviewed="a3f91c4e" /%}
15
+ * ```
16
+ *
17
+ * Resolution is unchanged. After the slice resolves it is normalized, hashed
18
+ * and compared. A mismatch produces a diagnostic; the page still renders the
19
+ * current code.
20
+ *
21
+ * **`reviewed`, not `pin` (D1).** This freezes nothing — the snippet still
22
+ * tracks HEAD and re-resolves every build. What the attribute records is that a
23
+ * human read this version and the surrounding prose matched. The name is
24
+ * load-bearing: `pin=` would steer an author toward "this is frozen, nothing to
25
+ * do here", which is the opposite of the intended response.
26
+ */
27
+ export interface HashPair {
28
+ /** The stored hash — reindent, line endings, trailing whitespace. */
29
+ strict: string;
30
+ /** Additionally collapsing whitespace runs and dropping blank lines. */
31
+ loose: string;
32
+ }
33
+ /**
34
+ * The normalized form that gets hashed.
35
+ *
36
+ * **Normalization is the whole design.** Hash raw bytes and the marker fires on
37
+ * every trailing space and every reformat — and a marker that cries wolf gets
38
+ * deleted. Budget the normalization, not the hash: hashing is a line, and
39
+ * getting normalization wrong produces a feature that is worse than not having
40
+ * it.
41
+ *
42
+ * In order:
43
+ *
44
+ * 1. **Apply `reindent` first.** Moving a function into a class shifts every
45
+ * line two columns without changing a character of content.
46
+ * 2. Normalize line endings, strip per-line trailing whitespace, normalize the
47
+ * trailing newline.
48
+ * 3. **Stop. Comments stay in — D2.**
49
+ *
50
+ * Excluding comments would make markers quieter, and SPEC-131's masker could do
51
+ * it for free. It is still wrong: a doc comment is very often the exact text
52
+ * the surrounding prose paraphrases. If `@param timeout`'s description changes
53
+ * meaning and the marker stays green, the feature has failed at the only job it
54
+ * has.
55
+ */
56
+ export declare function normalizeStrict(content: string): string;
57
+ /**
58
+ * The loose form — strict, plus collapsing whitespace runs and dropping blank
59
+ * lines.
60
+ *
61
+ * This exists so that "it was just the formatter" is a **fact the tool
62
+ * establishes** rather than a judgement an author makes under time pressure
63
+ * (D3). A repo-wide formatter run would otherwise invalidate every marker at
64
+ * once, and an author re-stamping fifty of them learns nothing — the feature's
65
+ * worst failure mode, and the strongest objection to it.
66
+ */
67
+ export declare function normalizeLoose(content: string): string;
68
+ /** Both hash levels for a resolved slice. */
69
+ export declare function hashSlice(content: string): HashPair;
70
+ /** What a comparison against a stored marker concluded. */
71
+ export type MarkerVerdict =
72
+ /** The stored hash still matches. Nothing to do. */
73
+ 'current'
74
+ /** Strict differs, loose matches — the change is *provably* formatting
75
+ * only, so it can be re-stamped silently (D3). */
76
+ | 'formatting-only'
77
+ /** Both differ. The content carries meaning; hold for review. */
78
+ | 'stale';
79
+ export interface MarkerComparison {
80
+ verdict: MarkerVerdict;
81
+ stored: string;
82
+ current: HashPair;
83
+ }
84
+ /**
85
+ * Compare a stored marker against the slice as it is now.
86
+ *
87
+ * The stored value is compared against the **strict** hash. A stored marker
88
+ * that matches neither level, but whose loose form matches the current loose
89
+ * form, is formatting-only: the author reviewed content that still says the
90
+ * same thing with different whitespace.
91
+ */
92
+ export declare function compareMarker(stored: string, content: string, storedLoose?: string): MarkerComparison;
93
+ /** Render a marker attribute value. Both levels are stored, separated by a
94
+ * colon, so the formatting-only case can be *proven* rather than assumed. */
95
+ export declare function formatMarker(pair: HashPair): string;
96
+ /** Parse a stored marker value into its levels. A marker written before the
97
+ * loose level existed — or by hand — carries only the strict half. */
98
+ export declare function parseMarker(raw: string): {
99
+ strict: string;
100
+ loose?: string;
101
+ };
102
+ /**
103
+ * Whether an invocation can meaningfully carry a marker.
104
+ *
105
+ * D10: a slice that cannot change can never fire, so stamping one means
106
+ * nothing and the tool should say so rather than doing it. Today the only such
107
+ * case is an invocation with no resolvable slice at all.
108
+ */
109
+ export declare function canCarryMarker(opts: {
110
+ hasPath: boolean;
111
+ rune: string;
112
+ }): boolean;
113
+ //# sourceMappingURL=review-marker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-marker.d.ts","sourceRoot":"","sources":["../../src/lib/review-marker.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAYH,MAAM,WAAW,QAAQ;IACxB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC;IACf,wEAAwE;IACxE,KAAK,EAAE,MAAM,CAAC;CACd;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAOvD;AAED;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAMtD;AAwCD,6CAA6C;AAC7C,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,QAAQ,CAKnD;AAED,2DAA2D;AAC3D,MAAM,MAAM,aAAa;AACxB,oDAAoD;AAClD,SAAS;AACX;mDACmD;GACjD,iBAAiB;AACnB,iEAAiE;GAC/D,OAAO,CAAC;AAEX,MAAM,WAAW,gBAAgB;IAChC,OAAO,EAAE,aAAa,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,QAAQ,CAAC;CAClB;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,WAAW,CAAC,EAAE,MAAM,GAClB,gBAAgB,CAiBlB;AAED;8EAC8E;AAC9E,wBAAgB,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,MAAM,CAEnD;AAED;uEACuE;AACvE,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAG3E;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE;IAAE,OAAO,EAAE,OAAO,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAMhF"}