@ai-matrx/content-ir 0.18.0 → 0.18.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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,39 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.18.1 — 2026-09-25
4
+
5
+ **Carries: RC-B10 only** (the one code-range rule). No RC-B3 work is pending
6
+ after the 0.18.0 tag; 0.18.0 itself (RC-B3's single-dollar release) ALSO
7
+ carried RC-B10 stages a and b, swept onto main before that tag — recorded
8
+ here because its entry does not mention them.
9
+
10
+ **`/source`: THE one code-range rule is the renderer's rule** (RC-B10 ruling,
11
+ REGISTER rulings ledger). `source/code-ranges.ts` owns it: a backtick fence
12
+ opens where a line's trimmed text starts with ``` at ANY indent (list items at
13
+ any depth), after stripping blockquote `>` prefixes; a tilde fence opens at
14
+ ≤ 3 spaces relative to its container (list content column); a backtick fence
15
+ closes by the nested-fence rule (with the strict retry) or the renderer's
16
+ line-end closer (`code````), and inside ```json a backtick run in a JSON
17
+ string is text; a blockquoted fence ends with its quote. Strict CommonMark's
18
+ "4+ spaces is not a fence" is rejected on purpose — users see what the
19
+ renderer's splitter draws. Phases follow the renderer: the splitter's
20
+ any-indent backtick fences first, then remark inside each prose segment
21
+ (blockquote, list-marker-line and tilde fences, code spans).
22
+ - New exports: `fenceOpenerOf`, `closeFence`, `FenceReader` (the streaming
23
+ closer), `BacktickRuns` (the code-span pairing table), `fenceLineKinds`
24
+ (per-line prose/open/body/close), types `FenceOpener`, `FenceLines`,
25
+ `FenceEnd`, `FenceLineKind`.
26
+ - The tokenizer (0.18.0) and `XmlContainerTracker` (this release) read fences
27
+ only through these; their private copies are deleted.
28
+ - Corpus: 136,662/136,662 byte-identical; every tokenizer backtick-fence
29
+ island (17,518) is exactly one `findCodeRanges` fence (the 0.17 rule missed
30
+ 92); display-math pairing unchanged on every row. Renderer blocks ⊆
31
+ tokenizer islands (matrx-frontend `source-covers-renderer`, container
32
+ fences added). Vectors: `__tests__/fixtures/code-range-vectors.json` (25,
33
+ incl. stored-row shapes with every word replaced) and the Python twin's
34
+ `fence-nesting-vectors.json` (container + stored-row documents).
35
+ - Consumer action: none — refresh to latest.
36
+
3
37
  ## 0.18.0 — 2026-09-25
4
38
 
5
39
  **`/source` `isSingleDollarMath`: `$FC$` is math.** (RC-B9 verifier, RC-B3.)
package/dist/index.cjs CHANGED
@@ -5367,7 +5367,7 @@ function scan(text) {
5367
5367
  }
5368
5368
  const count = starts.length;
5369
5369
  const raw = (k) => text.slice(starts[k], ends[k]);
5370
- const out = { ranges: [], paragraphs: [], endsInFence: false, pendingPara: -1 };
5370
+ const out = { ranges: [], fences: [], paragraphs: [], endsInFence: false, pendingPara: -1 };
5371
5371
  const rawLines = { count, line: raw };
5372
5372
  let segment = 0;
5373
5373
  for (let k = 0; k < count; k++) {
@@ -5376,6 +5376,7 @@ function scan(text) {
5376
5376
  prose(text, starts, ends, raw, segment, k, out);
5377
5377
  const end = closeFence(rawLines, k, opener);
5378
5378
  out.ranges.push({ start: starts[k], end: ends[end.line], kind: "fence" });
5379
+ out.fences.push([k, end.line, end.closed]);
5379
5380
  out.pendingPara = -1;
5380
5381
  if (!end.closed && end.line === count - 1) out.endsInFence = true;
5381
5382
  k = end.line;
@@ -5441,6 +5442,7 @@ function prose(text, starts, ends, raw, from, to, out) {
5441
5442
  };
5442
5443
  const end = closeFence(src, k, opener);
5443
5444
  out.ranges.push({ start: starts[k], end: ends[end.line], kind: "fence" });
5445
+ out.fences.push([k, end.line, end.closed]);
5444
5446
  if (!end.closed && end.line === starts.length - 1) out.endsInFence = true;
5445
5447
  k = end.line;
5446
5448
  }
@@ -5504,6 +5506,18 @@ function findCodeRanges(text) {
5504
5506
  for (const [from, to] of s.paragraphs) codeSpans(text, from, to, ranges);
5505
5507
  return ranges.sort((a, b) => a.start - b.start);
5506
5508
  }
5509
+ function fenceLineKinds(text) {
5510
+ const s = scan(text);
5511
+ let count = 1;
5512
+ for (let i = text.indexOf("\n"); i !== -1; i = text.indexOf("\n", i + 1)) count++;
5513
+ const kinds = new Array(count).fill("prose");
5514
+ for (const [open, last, closed] of s.fences) {
5515
+ kinds[open] = "open";
5516
+ for (let k = open + 1; k <= last; k++) kinds[k] = "body";
5517
+ if (closed && last > open) kinds[last] = "close";
5518
+ }
5519
+ return kinds;
5520
+ }
5507
5521
  function pendingCodeSpanStart(text) {
5508
5522
  const n = text.length;
5509
5523
  if (n === 0 || /\n[ \t]*\n[ \t]*$/.test(text)) return -1;
@@ -5802,25 +5816,20 @@ var XmlContainerTracker = class {
5802
5816
  inComment = false;
5803
5817
  inCdata = false;
5804
5818
  inlineTicks = 0;
5805
- fenceMarker = null;
5819
+ /** The open fence, read by THE one closer (source/code-ranges.ts). */
5820
+ fence = null;
5806
5821
  consumeLine(line, startOffset = 0) {
5807
- const fence = /^[ \t]*(`{3,}|~{3,})(.*)$/.exec(line);
5808
- if (!this.inComment && !this.inCdata && this.inlineTicks === 0 && fence) {
5809
- const marker = fence[1];
5810
- const char = marker[0];
5811
- const suffix = fence[2];
5812
- if (marker.length >= 3) {
5813
- if (!this.fenceMarker) {
5814
- this.fenceMarker = { char, ticks: marker.length };
5815
- return null;
5816
- }
5817
- if (char === this.fenceMarker.char && marker.length >= this.fenceMarker.ticks && suffix.trim() === "") {
5818
- this.fenceMarker = null;
5819
- }
5822
+ if (this.fence) {
5823
+ if (this.fence.feed(line)) this.fence = null;
5824
+ return null;
5825
+ }
5826
+ if (!this.inComment && !this.inCdata && this.inlineTicks === 0) {
5827
+ const opener = fenceOpenerOf(line);
5828
+ if (opener) {
5829
+ this.fence = new FenceReader(opener);
5820
5830
  return null;
5821
5831
  }
5822
5832
  }
5823
- if (this.fenceMarker) return null;
5824
5833
  for (let i = startOffset; i < line.length; i++) {
5825
5834
  if (this.inlineTicks > 0) {
5826
5835
  if (line[i] === "`") {
@@ -7311,6 +7320,7 @@ function mapRange(changes, start, end, unit = "utf16") {
7311
7320
  }
7312
7321
 
7313
7322
  exports.ACTION_BY_CLASS = ACTION_BY_CLASS;
7323
+ exports.BacktickRuns = BacktickRuns;
7314
7324
  exports.CALLOUT_NAMES = CALLOUT_NAMES;
7315
7325
  exports.CAPABILITY_BY_CLASS = CAPABILITY_BY_CLASS;
7316
7326
  exports.CLASSES = CLASSES;
@@ -7318,6 +7328,7 @@ exports.DIRECTIVE_VERSION = DIRECTIVE_VERSION;
7318
7328
  exports.DirectiveDecodeError = DirectiveDecodeError;
7319
7329
  exports.FENCE_OPENER_WHITESPACE = FENCE_OPENER_WHITESPACE;
7320
7330
  exports.FENCE_WHITESPACE = FENCE_WHITESPACE;
7331
+ exports.FenceReader = FenceReader;
7321
7332
  exports.IN_CONTENT_CLASSES = IN_CONTENT_CLASSES;
7322
7333
  exports.IR_ENVELOPE_CACHE_VERSION = IR_ENVELOPE_CACHE_VERSION;
7323
7334
  exports.IR_ENVELOPE_KEY = IR_ENVELOPE_KEY;
@@ -7352,6 +7363,7 @@ exports.buildKindDirective = buildKindDirective;
7352
7363
  exports.capabilityOf = capabilityOf;
7353
7364
  exports.classifyInboundEnvelopeMetadata = classifyInboundEnvelopeMetadata;
7354
7365
  exports.classifyInnerFenceLine = classifyInnerFenceLine;
7366
+ exports.closeFence = closeFence;
7355
7367
  exports.collectReferencedKinds = collectReferencedKinds;
7356
7368
  exports.collectSchemaReferencedKinds = collectSchemaReferencedKinds;
7357
7369
  exports.compareWithExistingKindSchema = compareWithExistingKindSchema;
@@ -7371,7 +7383,9 @@ exports.envelopeCacheFromEnvelopes = envelopeCacheFromEnvelopes;
7371
7383
  exports.envelopeFromCompleteValue = envelopeFromCompleteValue;
7372
7384
  exports.executesAtOutputRoot = executesAtOutputRoot;
7373
7385
  exports.fenceDiscriminator = fenceDiscriminator;
7386
+ exports.fenceLineKinds = fenceLineKinds;
7374
7387
  exports.fenceNestsInnerFences = fenceNestsInnerFences;
7388
+ exports.fenceOpenerOf = fenceOpenerOf;
7375
7389
  exports.fieldsToDbPayload = fieldsToDbPayload;
7376
7390
  exports.findCodeRanges = findCodeRanges;
7377
7391
  exports.fingerprintText = fingerprintText;