@ai-matrx/content-ir 0.12.0 → 0.14.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.
- package/CHANGELOG.md +119 -0
- package/dist/index.cjs +546 -98
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +539 -99
- package/dist/index.js.map +1 -1
- package/dist/source.cjs +546 -98
- package/dist/source.cjs.map +1 -1
- package/dist/source.d.cts +118 -14
- package/dist/source.d.ts +118 -14
- package/dist/source.js +539 -99
- package/dist/source.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,124 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.14.0 — 2026-09-25
|
|
4
|
+
|
|
5
|
+
**`/source` — RC-B3 polish: the re-verification residuals, and the verifier's
|
|
6
|
+
attacks made permanent** (common-docs
|
|
7
|
+
`projects/rich-content-unification/evidence/verify-RC-B3.md` § Re-verification).
|
|
8
|
+
Each residual had a failing test first (R1–R3 red on 0.13.0; the new
|
|
9
|
+
cross-language vectors fail 10 cases on the old Python twin):
|
|
10
|
+
|
|
11
|
+
- **R1** — an insertion carrying an exact copy of the next island at its
|
|
12
|
+
expected offset no longer causes a false `integrity` refusal: an island's
|
|
13
|
+
candidate positions are scored by how much of the original text still
|
|
14
|
+
surrounds them.
|
|
15
|
+
- **R2** — `tokenizeSource(text, { streaming: true })`: the last,
|
|
16
|
+
still-unterminated line closes no fence (a bare ```` ``` ```` there may grow
|
|
17
|
+
into ```` ```bash ````). Stored text omits the option.
|
|
18
|
+
- **R3** — `listIslands` loops instead of spreading, so a block with 150k
|
|
19
|
+
inline islands saves without a `RangeError`.
|
|
20
|
+
- **R4** — the fence rule defines its whitespace: `FENCE_WHITESPACE`
|
|
21
|
+
(CommonMark ASCII whitespace) and `trimFenceLine`, which every caller uses
|
|
22
|
+
in place of a language's `trim()`. The vectors carry U+FEFF, U+0085,
|
|
23
|
+
U+00A0, U+001C–U+001F and U+2028 lines; aidream matrx-ai's Python twin
|
|
24
|
+
gained `FENCE_WHITESPACE` / `trim_fence_line` and passes them.
|
|
25
|
+
- **R5** — tilde and odd-whitespace fences: matrx-frontend's
|
|
26
|
+
`source-covers-renderer` property test proves the tokenizer locks at least
|
|
27
|
+
every fenced block the renderer draws (both now share `trimFenceLine`).
|
|
28
|
+
- **Permanent attack suite** — `__tests__/source-attack.test.ts`: seeded fuzz
|
|
29
|
+
of rejoin identity, offsets (independently counted), surrogate safety,
|
|
30
|
+
no-edit/identity saves, splice verdicts, island refusals, misaligned spans,
|
|
31
|
+
streaming prefixes (settled islands never move) and pathological timing
|
|
32
|
+
(budget + linear scaling), bounded in CI; `SOURCE_ATTACK=long` runs the
|
|
33
|
+
verifier-scale version.
|
|
34
|
+
|
|
35
|
+
**Consumer action:** fence-line classification callers trim with
|
|
36
|
+
`trimFenceLine(line)` (matrx-frontend's splitters do as of this release).
|
|
37
|
+
|
|
38
|
+
**`/source` — islands for the extended markdown syntax** (RC-B8, common-docs
|
|
39
|
+
`projects/rich-content-unification/REGISTER.md`). The renderer now draws
|
|
40
|
+
callouts, directives, front matter, footnotes and wikilinks; an editor must
|
|
41
|
+
never re-serialize their grammar, so each is now an island:
|
|
42
|
+
|
|
43
|
+
- `directive` (block) — a generic-directive container `:::name[label]{attrs}`
|
|
44
|
+
… `:::` with nesting counted (tabs, columns, details, figures, callouts,
|
|
45
|
+
TOC), a leaf `::name` line (`meta.leaf`), or a MkDocs admonition
|
|
46
|
+
`!!! type "Title"` / `??? type` with its indented body (`meta.syntax: "mkdocs"`).
|
|
47
|
+
An unclosed container runs to the end with `complete: false` (streaming).
|
|
48
|
+
- `callout` (block) — a blockquote opening `> [!TYPE]` (GitHub alert /
|
|
49
|
+
Obsidian callout; `meta.name`, `meta.fold`).
|
|
50
|
+
- `footnote_def` (block) — `[^id]: …` with its continuation lines (`meta.id`).
|
|
51
|
+
- `front_matter` now also recognizes TOML (`+++`); `meta.format` is `yaml` | `toml`.
|
|
52
|
+
- `wikilink` (inline) — `[[Page]]`, `[[Page|alias]]`, `![[Page]]`
|
|
53
|
+
(`meta.target`, `meta.embed`); never across a line, never inside code.
|
|
54
|
+
|
|
55
|
+
CSV/TSV fences were already `fence` islands (`meta.lang`). Guard:
|
|
56
|
+
`__tests__/source-markdown-syntax-islands.test.ts` (7 of 10 red on 0.13.0).
|
|
57
|
+
|
|
58
|
+
**Consumer action:** an exhaustive `switch` over `IslandType` /
|
|
59
|
+
`BlockIslandType` gains the new members; nothing else changes (joinSource is
|
|
60
|
+
still byte-identical, the corpus check stays green).
|
|
61
|
+
|
|
62
|
+
**Single-dollar math: single-letter math shapes are math** (RC-B2 verification,
|
|
63
|
+
common-docs `projects/rich-content-unification/evidence/verify-RC-B2.md`).
|
|
64
|
+
`isSingleDollarMath` now also accepts a shape built only from single-letter
|
|
65
|
+
identifiers (primes, standard function names), digits, parentheses, commas and
|
|
66
|
+
`- * /` that applies, primes or juxtaposes them — `$f(g(x))$`, `$u v$`,
|
|
67
|
+
`$f'(x)$`, `$(x, y)$`, `$ln(x)$`. Words keep it text (`$Tipping (fee)$`), and
|
|
68
|
+
the pandoc spacing / digit rules still keep currency (`$5 and $10`, `$5-$10`)
|
|
69
|
+
as text. Guard: `__tests__/single-dollar-math.test.ts` (5 of 12 red before).
|
|
70
|
+
|
|
71
|
+
**Consumer action:** none — adopt the release; matrx-frontend's math
|
|
72
|
+
normalizer and `/source` tokenizer pick the rule up through the import.
|
|
73
|
+
|
|
74
|
+
## 0.13.0 — 2026-09-25
|
|
75
|
+
|
|
76
|
+
**`/source` — fixes from the RC-B3 independent verification**
|
|
77
|
+
(common-docs `projects/rich-content-unification/evidence/verify-RC-B3.md`).
|
|
78
|
+
Every finding got a failing test first (`__tests__/source-verify-findings.test.ts`,
|
|
79
|
+
14 of the 17 non-timing tests red on 0.12.0), then the fix:
|
|
80
|
+
|
|
81
|
+
- **THE nested-fence rule now lives here** (`source/fence-nesting.ts`, moved from
|
|
82
|
+
matrx-frontend `components/markdown-core/fence-nesting.ts`): inside a
|
|
83
|
+
```` ```markdown ```` / `md` / `mdx` fence, ```` ```lang ```` opens a nested
|
|
84
|
+
fence and a bare ```` ``` ```` closes the innermost one; a nested fence still
|
|
85
|
+
open at the end of the text retries strict CommonMark. The tokenizer uses it,
|
|
86
|
+
so it ends a nested markdown fence exactly where the renderer does (real row:
|
|
87
|
+
note `f9b7e9a2-…`). Generated cross-language vectors
|
|
88
|
+
`__tests__/fence-nesting-vectors.json`; aidream matrx-ai's Python twin runs a
|
|
89
|
+
byte-identical copy and fails on drift.
|
|
90
|
+
- **Islands change only through `islandEdit(island, text)`.** A plain edit must
|
|
91
|
+
carry every island inside its range back byte-identical and in order —
|
|
92
|
+
otherwise `SourceSpliceError("island_edit")` names the island. Edits are
|
|
93
|
+
diffed segment by segment between islands, so anchors inside an edited
|
|
94
|
+
paragraph map exactly.
|
|
95
|
+
- **Integrity is refused by default.** `requireIntegrity` defaults to `true`;
|
|
96
|
+
`false` is documented as tooling-only.
|
|
97
|
+
- **Linear time on pathological input.** Every closer search goes through an
|
|
98
|
+
occurrence index; code spans use a per-paragraph run table; the single-`$`
|
|
99
|
+
scan stops at the rule's 400-character limit; embedded `__kind` probing has a
|
|
100
|
+
per-paragraph budget; `readXmlTag` takes a finder. 2 MB of `{{`: 21 s → 41 ms.
|
|
101
|
+
- **A tree's root label belongs to the tree island** (the renderer splitter's
|
|
102
|
+
`findTreeBlockStart`).
|
|
103
|
+
- **`$$` follows the core's pairing rule** (`source/math-pairs.ts`, ported from
|
|
104
|
+
`@ai-matrx/kit/delimiter-guard`): tokens outside code pair in order, prose
|
|
105
|
+
pairs are not math, an unpaired `$$` is literal. `$$` at the end of a line
|
|
106
|
+
pairs with a later closer, and a lone `$$` never locks the rest of a document.
|
|
107
|
+
|
|
108
|
+
### Consumer action
|
|
109
|
+
|
|
110
|
+
- `spliceSave` now THROWS on an island change (`island_edit`) and on disturbed
|
|
111
|
+
integrity (`integrity`). Editors change islands with `islandEdit`; tooling
|
|
112
|
+
that wants the report passes `requireIntegrity: false`.
|
|
113
|
+
- matrx-frontend: import the fence rule from `@ai-matrx/content-ir/source`; the
|
|
114
|
+
local `components/markdown-core/fence-nesting.ts` is deleted.
|
|
115
|
+
|
|
116
|
+
## 0.12.1
|
|
117
|
+
|
|
118
|
+
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
119
|
+
`git diff npm/content-ir-core/v0.12.0..npm/content-ir-core/v0.12.1 -- apps/shared/content-ir-core`).
|
|
120
|
+
No source changes intended and no consumer action required.
|
|
121
|
+
|
|
3
122
|
## 0.12.0 — 2026-09-23
|
|
4
123
|
|
|
5
124
|
**`/source` — the stored text is the truth, block by block** (rich-content
|