@ai-matrx/content-ir 0.19.1 → 0.19.3

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,10 +1,59 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.19.3
4
+
5
+ Automatic republish — despite the generated note, this version carries source
6
+ changes: **RC-B3 round 4 close-out** (verify-RC-B3 § round 4, RC-B3 lane; swept
7
+ into aidream 57b7a956da by the local-work sweeper).
8
+
9
+ - `/source` streaming (D1): a footnote's lazy connector lines that a tree may
10
+ still claim hold the note open; an inline island read out of a paragraph
11
+ that reaches into provisional text is held; a note that took in provisional
12
+ text (a `$$` that may still pair across a blank line) is held. Each pinned by
13
+ a reproducer that fails when its hold alone is removed.
14
+ - D2: the provisional mark in the JSON-head branch (braces balancing on the
15
+ open last line, unrecognized head) is deleted as redundant — planted
16
+ mutation: 1,120 differing streamed prefixes, 0 settled-island changes over
17
+ 12,000 documents.
18
+ - `isSingleDollarMath` (D5): shell arithmetic `$((1+2))$` and PowerShell's
19
+ `$_.Name$` / `$_[0]` are not math (vectors). Read-only measurement over 87,527
20
+ assistant messages + 4,351 notes: 0 such spans in stored content.
21
+ - No consumer action required.
22
+
23
+ ## 0.19.2
24
+ ### Unreleased
25
+
26
+ - `/source`: **THE GFM table rule** (`source/gfm-table.ts`, verify-RC-B4) —
27
+ `splitRowSegments` / `rowCells` (a `|` is a boundary unless an odd backslash
28
+ run precedes it), `unescapeCellPipes`, `isGfmDelimiterRow`, `isPipeLedRow`,
29
+ `startsPipelessTable`, `continuesTable`, `opensTable`, `tableStartsAt`,
30
+ `findTableStart`, `findTableEnd`. Held to the shared vectors
31
+ (`__tests__/gfm-table-vectors.json`, byte copy of matrx-frontend's and of the
32
+ Python block detector's fixture). Consumers: `@ai-matrx/print` now; the
33
+ matrx-frontend readers move onto it once this version is on npm.
34
+
3
35
  ## 0.19.1
4
36
 
5
- Automatic changed-only republish (docs/metadata drift since the last tag — see
6
- `git diff npm/content-ir-core/v0.19.0..npm/content-ir-core/v0.19.1 -- apps/shared/content-ir-core`).
7
- No source changes intended and no consumer action required.
37
+ Automatic republish — despite the generated note, this version carries source
38
+ changes: **the RC-B3 round 3 fix round** (verify-RC-B3 § round 3, RC-B3 lane;
39
+ aidream a8506eeeca, 4b92192527, aaef42333d).
40
+
41
+ - `/source` streaming: a trailing single `$` may be half of a `$$` (B3); a lone
42
+ CR is half of a line break still arriving (B4); a block that opens in
43
+ provisional text may still dissolve (a footnote or paragraph does not end
44
+ there); front matter still waiting for its closing fence is undecided.
45
+ Lone CR, tab, list-item and quote atoms joined the LLM-fragment generator.
46
+ - Holdbacks R4 (`$$` block may dissolve), R8 (spilled region), R10 (`\(`/`\[`
47
+ opener) each pinned by a reproducer that fails when it alone is removed; the
48
+ JSON open-tail holdback (R12) and a provisional-tree-root holdback were
49
+ deleted as redundant — planted-mutation differentials over 12,000 documents
50
+ showed 64 and 972 differing prefixes but 0 settled-island changes.
51
+ - Front matter behind a leading byte-order mark (`\uFEFF---`) is front matter.
52
+ - `isSingleDollarMath`: PHP/Perl member access is not math (`$this->$prop`,
53
+ `$obj->$method`, `$class::$instance`). Measured read-only over 86,136
54
+ assistant messages + 4,329 notes: 0 gained, 8 lost (6 shell-variable-chain,
55
+ 2 php-perl-member), every one intended.
56
+ - No consumer action required.
8
57
 
9
58
  ## 0.19.0 — kind validation behind a schema-source port (Matrx Alchemy ALC-13)
10
59
 
package/dist/index.cjs CHANGED
@@ -5807,6 +5807,7 @@ var IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
5807
5807
  var MATH_SUFFIX = /^(?:s|es|th|st|nd|rd)$/i;
5808
5808
  function isVariableChain(content, after) {
5809
5809
  if (/^\{[A-Za-z_][\w.]*\}$/.test(content)) return true;
5810
+ if (/^\(\(.*\)\)$/.test(content) || /^_[.[]/.test(content)) return true;
5810
5811
  if (!after) return false;
5811
5812
  if (after[0] === "{") return IDENTIFIER.test(content);
5812
5813
  const run = /^[A-Za-z0-9_]+/.exec(after)?.[0];
@@ -6378,6 +6379,16 @@ var Tokenizer = class {
6378
6379
  holdUndecidedTail() {
6379
6380
  const last = this.lineStarts.length - 1;
6380
6381
  if (last < 0) return;
6382
+ if (this.provisionalFrom < this.n) {
6383
+ for (let b = 0; b < this.blocks.length; b++) {
6384
+ const block = this.blocks[b];
6385
+ if (block.end <= this.provisionalFrom) continue;
6386
+ if (block.kind === "prose") block.inlines = block.inlines.filter((inline) => inline.end <= this.provisionalFrom);
6387
+ else if (block.island?.fromParagraph && block.start < this.provisionalFrom) {
6388
+ this.blocks[b] = { kind: "prose", start: block.start, end: block.end, island: null, inlines: [] };
6389
+ }
6390
+ }
6391
+ }
6381
6392
  if (this.isOpenTail(last)) {
6382
6393
  let b = this.blocks.length - 1;
6383
6394
  while (b >= 0 && this.blocks[b].kind === "gap") b--;
@@ -6675,6 +6686,9 @@ var Tokenizer = class {
6675
6686
  }
6676
6687
  if (this.isOpenTail(k)) return this.heldFootnote(p, open[1]);
6677
6688
  if (FOOTNOTE_DEF.test(line.trimStart())) break;
6689
+ if (this.streaming && TREE_GLYPHS.test(line) && this.connectorRunReachesEnd(k)) {
6690
+ return this.heldFootnote(p, open[1]);
6691
+ }
6678
6692
  const block = this.detectBlock(this.lineStarts[k], k, false);
6679
6693
  if (block && this.mayDissolve(block)) return this.heldFootnote(p, open[1]);
6680
6694
  if (block) break;
@@ -6682,8 +6696,22 @@ var Tokenizer = class {
6682
6696
  }
6683
6697
  const end = this.contentEnds[last];
6684
6698
  if (this.paragraphMayGrow(end)) return this.heldFootnote(p, open[1]);
6699
+ if (this.streaming && end > this.provisionalFrom) return this.heldFootnote(p, open[1]);
6685
6700
  return this.island("footnote_def", p, end, true, { id: open[1] });
6686
6701
  }
6702
+ /** Every line from `k` to the end is a connector line or blank (a tree may still form there). */
6703
+ connectorRunReachesEnd(k) {
6704
+ if (this.lastNonConnectorLine === void 0) {
6705
+ let j = this.lineCount - 1;
6706
+ for (; j >= 0; j--) {
6707
+ this.tick(1);
6708
+ if (!this.lineIsBlank(j) && !TREE_GLYPHS.test(this.lineText(j))) break;
6709
+ }
6710
+ this.lastNonConnectorLine = j;
6711
+ }
6712
+ return k > this.lastNonConnectorLine;
6713
+ }
6714
+ lastNonConnectorLine = void 0;
6687
6715
  /** A footnote whose continuation is still arriving: open to the end of the text. */
6688
6716
  heldFootnote(p, id) {
6689
6717
  return this.island("footnote_def", p, this.n, false, { id });
@@ -6948,7 +6976,6 @@ var Tokenizer = class {
6948
6976
  if (isRecognizedJsonHead(this.text.slice(tp, tp + 512))) {
6949
6977
  return this.island("json", p, this.n, false, jsonMeta(this.text.slice(tp)));
6950
6978
  }
6951
- this.provisionalFrom = Math.min(this.provisionalFrom, p);
6952
6979
  return null;
6953
6980
  }
6954
6981
  if (net !== 0) return null;
@@ -7619,6 +7646,76 @@ function mapRange(changes, start, end, unit = "utf16") {
7619
7646
  return { start: newStart, end: newEnd, touched, collapsed: newEnd === newStart && end > start };
7620
7647
  }
7621
7648
 
7649
+ // source/gfm-table.ts
7650
+ function splitRowSegments(line) {
7651
+ const segments = [];
7652
+ let start = 0;
7653
+ for (let i = 0; i < line.length; i += 1) {
7654
+ const ch = line[i];
7655
+ if (ch === "\\") {
7656
+ i += 1;
7657
+ continue;
7658
+ }
7659
+ if (ch === "|") {
7660
+ segments.push(line.slice(start, i));
7661
+ start = i + 1;
7662
+ }
7663
+ }
7664
+ segments.push(line.slice(start));
7665
+ return segments;
7666
+ }
7667
+ function rowCells(line) {
7668
+ const cells = splitRowSegments(line).map((cell) => cell.trim());
7669
+ if (cells.length > 1 && cells[0] === "") cells.shift();
7670
+ if (cells.length > 1 && cells[cells.length - 1] === "") cells.pop();
7671
+ else if (cells.length === 1 && cells[0] === "") cells.pop();
7672
+ return cells;
7673
+ }
7674
+ function unescapeCellPipes(cell) {
7675
+ return cell.replace(/\\\|/g, "|");
7676
+ }
7677
+ var BLOCK_START = /^(?:[-+*](?:\s|$)|\d{1,9}[.)](?:\s|$)|>|#{1,6}(?:\s|$)|```|~~~|(?:-\s*){3,}$|(?:\*\s*){3,}$|(?:_\s*){3,}$)/;
7678
+ var DELIMITER_CELL = /^:?-+:?$/;
7679
+ function isGfmDelimiterRow(line) {
7680
+ const trimmed = line.trim();
7681
+ if (!trimmed.includes("|")) return false;
7682
+ const cells = rowCells(trimmed);
7683
+ return cells.length > 0 && cells.every((cell) => DELIMITER_CELL.test(cell));
7684
+ }
7685
+ function isPipeLedRow(line) {
7686
+ const trimmed = line.trim();
7687
+ return trimmed.startsWith("|") && trimmed.includes("|", 1);
7688
+ }
7689
+ function startsPipelessTable(header, delimiter) {
7690
+ const head = header.trim();
7691
+ if (!head || head.startsWith("|") || BLOCK_START.test(head)) return false;
7692
+ if (splitRowSegments(head).length < 2) return false;
7693
+ if (delimiter === void 0 || !isGfmDelimiterRow(delimiter)) return false;
7694
+ return rowCells(head).length === rowCells(delimiter.trim()).length;
7695
+ }
7696
+ function continuesTable(line) {
7697
+ const trimmed = line.trim();
7698
+ if (!trimmed) return false;
7699
+ if (trimmed.startsWith("|")) return trimmed.includes("|", 1);
7700
+ return splitRowSegments(trimmed).length > 1 && !BLOCK_START.test(trimmed);
7701
+ }
7702
+ function opensTable(lines, index) {
7703
+ const line = lines[index] ?? "";
7704
+ return isPipeLedRow(line) || startsPipelessTable(line, lines[index + 1]);
7705
+ }
7706
+ function tableStartsAt(lines, index) {
7707
+ return opensTable(lines, index) && isGfmDelimiterRow(lines[index + 1] ?? "");
7708
+ }
7709
+ function findTableStart(lines, from = 0) {
7710
+ for (let i = Math.max(0, from); i < lines.length; i += 1) if (opensTable(lines, i)) return i;
7711
+ return -1;
7712
+ }
7713
+ function findTableEnd(lines, start) {
7714
+ let end = Math.min(lines.length, start + 2);
7715
+ while (end < lines.length && continuesTable(lines[end] ?? "")) end += 1;
7716
+ return end;
7717
+ }
7718
+
7622
7719
  exports.ACTION_BY_CLASS = ACTION_BY_CLASS;
7623
7720
  exports.AFTER_WINDOW = AFTER_WINDOW;
7624
7721
  exports.BacktickRuns = BacktickRuns;
@@ -7669,6 +7766,7 @@ exports.codeSpanText = codeSpanText;
7669
7766
  exports.collectReferencedKinds = collectReferencedKinds;
7670
7767
  exports.collectSchemaReferencedKinds = collectSchemaReferencedKinds;
7671
7768
  exports.compareWithExistingKindSchema = compareWithExistingKindSchema;
7769
+ exports.continuesTable = continuesTable;
7672
7770
  exports.convertAiSchemaToBlockFields = convertAiSchemaToBlockFields;
7673
7771
  exports.createFingerprinter = createFingerprinter;
7674
7772
  exports.createKindStreamParser = createKindStreamParser;
@@ -7692,6 +7790,8 @@ exports.fenceOpenerOf = fenceOpenerOf;
7692
7790
  exports.fenceParts = fenceParts;
7693
7791
  exports.fieldsToDbPayload = fieldsToDbPayload;
7694
7792
  exports.findCodeRanges = findCodeRanges;
7793
+ exports.findTableEnd = findTableEnd;
7794
+ exports.findTableStart = findTableStart;
7695
7795
  exports.fingerprintText = fingerprintText;
7696
7796
  exports.formatBlockLabel = formatBlockLabel;
7697
7797
  exports.getParseSession = getParseSession;
@@ -7705,11 +7805,13 @@ exports.isDirectiveClass = isDirectiveClass;
7705
7805
  exports.isDuplicateBlockSlug = isDuplicateBlockSlug;
7706
7806
  exports.isEmptyResidue = isEmptyResidue;
7707
7807
  exports.isEscapedBracketMath = isEscapedBracketMath;
7808
+ exports.isGfmDelimiterRow = isGfmDelimiterRow;
7708
7809
  exports.isIrEnvelopeCache = isIrEnvelopeCache;
7709
7810
  exports.isJsonAnyField = isJsonAnyField;
7710
7811
  exports.isKindDirective = isKindDirective;
7711
7812
  exports.isLegacyShell = isLegacyShell;
7712
7813
  exports.isMathPlaceholder = isMathPlaceholder;
7814
+ exports.isPipeLedRow = isPipeLedRow;
7713
7815
  exports.isProvisionalKind = isProvisionalKind;
7714
7816
  exports.isReservedDirectiveSlug = isReservedDirectiveSlug;
7715
7817
  exports.isScalarArrayType = isScalarArrayType;
@@ -7740,6 +7842,7 @@ exports.nounFamily = nounFamily;
7740
7842
  exports.nounLabel = nounLabel;
7741
7843
  exports.nounTitleColumn = nounTitleColumn;
7742
7844
  exports.openParseSession = openParseSession;
7845
+ exports.opensTable = opensTable;
7743
7846
  exports.pairDisplayMath = pairDisplayMath;
7744
7847
  exports.parseDirectiveSlug = parseDirectiveSlug;
7745
7848
  exports.parseFenceOpener = parseFenceOpener;
@@ -7757,6 +7860,7 @@ exports.rehydrateRunResult = rehydrateRunResult;
7757
7860
  exports.resetLegacyShellUses = resetLegacyShellUses;
7758
7861
  exports.resolvesInContent = resolvesInContent;
7759
7862
  exports.reuseEnvelopeIfCurrent = reuseEnvelopeIfCurrent;
7863
+ exports.rowCells = rowCells;
7760
7864
  exports.runKindDualGate = runKindDualGate;
7761
7865
  exports.runSchemaConversion = runSchemaConversion;
7762
7866
  exports.sanitizeInboundEnvelopeMetadata = sanitizeInboundEnvelopeMetadata;
@@ -7768,9 +7872,12 @@ exports.setJsonRootKeyLookup = setJsonRootKeyLookup;
7768
7872
  exports.singleDollarAfter = singleDollarAfter;
7769
7873
  exports.singleDollarMathEnd = singleDollarMathEnd;
7770
7874
  exports.spliceSave = spliceSave;
7875
+ exports.splitRowSegments = splitRowSegments;
7771
7876
  exports.splitsSurrogatePair = splitsSurrogatePair;
7877
+ exports.startsPipelessTable = startsPipelessTable;
7772
7878
  exports.storageToKindSchema = storageToKindSchema;
7773
7879
  exports.stripKindDeep = stripKindDeep;
7880
+ exports.tableStartsAt = tableStartsAt;
7774
7881
  exports.titleCaseToken = titleCaseToken;
7775
7882
  exports.toCodePointOffset = toCodePointOffset;
7776
7883
  exports.toUtf16Offset = toUtf16Offset;
@@ -7778,6 +7885,7 @@ exports.tokenizeSource = tokenizeSource;
7778
7885
  exports.trimFenceLine = trimFenceLine;
7779
7886
  exports.tryDecodeDirective = tryDecodeDirective;
7780
7887
  exports.tryDecodeDirectiveContent = tryDecodeDirectiveContent;
7888
+ exports.unescapeCellPipes = unescapeCellPipes;
7781
7889
  exports.validateBlockSchemaSavePlan = validateBlockSchemaSavePlan;
7782
7890
  exports.validateStructuralLeg = validateStructuralLeg;
7783
7891
  exports.withRootKind = withRootKind;