@ai-matrx/content-ir 0.18.6 → 0.19.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 +37 -6
- package/README.md +1 -1
- package/dist/index.cjs +131 -55
- 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 +131 -56
- package/dist/index.js.map +1 -1
- package/dist/registry.cjs +88 -0
- package/dist/registry.cjs.map +1 -1
- package/dist/registry.d.cts +104 -1
- package/dist/registry.d.ts +104 -1
- package/dist/registry.js +88 -1
- package/dist/registry.js.map +1 -1
- package/dist/source.cjs +43 -55
- package/dist/source.cjs.map +1 -1
- package/dist/source.js +43 -55
- package/dist/source.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,12 +1,34 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.
|
|
3
|
+
## 0.19.1
|
|
4
4
|
|
|
5
5
|
Automatic changed-only republish (docs/metadata drift since the last tag — see
|
|
6
|
-
`git diff npm/content-ir-core/v0.
|
|
6
|
+
`git diff npm/content-ir-core/v0.19.0..npm/content-ir-core/v0.19.1 -- apps/shared/content-ir-core`).
|
|
7
7
|
No source changes intended and no consumer action required.
|
|
8
8
|
|
|
9
|
-
## 0.19.0
|
|
9
|
+
## 0.19.0 — kind validation behind a schema-source port (Matrx Alchemy ALC-13)
|
|
10
|
+
|
|
11
|
+
`/registry` (and the root) now export `createKindValidator(source, options?)`,
|
|
12
|
+
`SchemaSourcePort`, `SchemaUnavailableReason`, `KindValidationResult`,
|
|
13
|
+
`KindValidator` and `Json`. This is matrx-frontend's `validateAgainstKind`,
|
|
14
|
+
moved into the package with its database read inverted: the host implements
|
|
15
|
+
`SchemaSourcePort.kindSchema(kind, signal)` once and answers `{ schema,
|
|
16
|
+
version }` or `{ unavailable: "kind_not_registered" | "schema_unavailable" |
|
|
17
|
+
"schema_invalid" | "catalog_unreachable" }`. The verdict (`checked`, `ok`,
|
|
18
|
+
`errors`, `degradedReason`) and its messages are unchanged; a source that
|
|
19
|
+
throws reads as `catalog_unreachable`; an uncompilable schema reads as
|
|
20
|
+
`schema_invalid`. The schema cache (30 s default, `invalidate`,
|
|
21
|
+
`cachedSchema`) belongs to each validator instance, never to the module.
|
|
22
|
+
|
|
23
|
+
### Consumer action
|
|
24
|
+
|
|
25
|
+
matrx-frontend: implement `SchemaSourcePort` once over
|
|
26
|
+
`content_ir.kind_definition`, build one validator with `createKindValidator`,
|
|
27
|
+
repoint `features/surfaces/runtime/surface-writeback.ts` and
|
|
28
|
+
`build-tool-injection.ts` to it, and delete
|
|
29
|
+
`features/content-ir/registry/validate-against-kind.ts`.
|
|
30
|
+
|
|
31
|
+
### Also in 0.19.0 — the RC-B3 fix round (RC-B3 lane)
|
|
10
32
|
|
|
11
33
|
**Carries: RC-B3 fix round (verify-RC-B3 § 0.18.3) and RC-B3r R3 — builder:
|
|
12
34
|
the RC-B3 standard lane.** (aidream 1174edb640 — RC-B10, the print lane —
|
|
@@ -16,7 +38,7 @@ below — shipped in 0.18.4; both under generic "no source changes" notes.)
|
|
|
16
38
|
**`/source` streaming: settled means settled** (F3/F4). Found with the
|
|
17
39
|
verifier's generator (realistic model fragments, every prefix, with and
|
|
18
40
|
without a final newline), now permanent in `__tests__/source-attack.test.ts`
|
|
19
|
-
(`LLM-fragment documents…`; 12,000 documents in `SOURCE_ATTACK=long`) plus
|
|
41
|
+
(`LLM-fragment documents…`; 12,000 documents in `SOURCE_ATTACK=long`) plus 30
|
|
20
42
|
pinned reproducers. `tokenizeSource(prefix, { streaming: true })` now also
|
|
21
43
|
holds back, as prose or as an open island:
|
|
22
44
|
- lines a box-drawing tree still forming at the end may claim as its root
|
|
@@ -24,12 +46,14 @@ holds back, as prose or as an open island:
|
|
|
24
46
|
- a paragraph cut short by a block that may still dissolve (a `$$` pair
|
|
25
47
|
closing on the open line, an unbalanced JSON head, any opener still
|
|
26
48
|
arriving on the open line) — and a footnote before one;
|
|
27
|
-
-
|
|
49
|
+
- a block island ending on the open last line (inlines there are covered by
|
|
50
|
+
the tree-root hold);
|
|
28
51
|
- a nested-fence closer found only by the strict-CommonMark retry, a tilde
|
|
29
52
|
fence whose inner block may still grow past it, braces that balance on
|
|
30
53
|
the open last line;
|
|
31
54
|
- a code span that a blank-so-far or `>`-only open line may still close
|
|
32
|
-
(`pendingCodeSpanStart`, `source/code-ranges.ts`)
|
|
55
|
+
(`pendingCodeSpanStart`, `source/code-ranges.ts`);
|
|
56
|
+
- a block whose opener is provisional text, and a paragraph break there.
|
|
33
57
|
The two lone-HTML-tag holdbacks (M-N6/N7) collapsed into the open-tail block
|
|
34
58
|
rule. Each holdback turns the attack suite red on its own when removed
|
|
35
59
|
(planted mutations on a scratch copy). The H2 exception is unchanged.
|
|
@@ -53,6 +77,12 @@ guard case `echo $HOME $PATH`).
|
|
|
53
77
|
`singleDollarAfter(text, close)` instead of `text[close + 1]` (a one-character
|
|
54
78
|
`after` still works; it just cannot see a variable chain).
|
|
55
79
|
|
|
80
|
+
## 0.18.6
|
|
81
|
+
|
|
82
|
+
Automatic republish. Despite the generated note, this version DID carry source
|
|
83
|
+
changes: most of the 0.19.0 work above (through aidream cd35751bea). 0.19.0
|
|
84
|
+
completes it (aidream d6241c5496, f1e9156e82).
|
|
85
|
+
|
|
56
86
|
## 0.18.5
|
|
57
87
|
|
|
58
88
|
Automatic republish. Despite the generated note, this version DID carry source
|
|
@@ -952,3 +982,4 @@ unchanged. Two things are worth doing at your next working session:
|
|
|
952
982
|
- Added ESM and declaration builds, package linting, packed-artifact analysis, and an isolated consumer canary.
|
|
953
983
|
- Preserved all parser, session, normalization, schema conversion, and structural-validation behavior with the existing shared fixtures and fingerprint vectors.
|
|
954
984
|
|
|
985
|
+
|
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ The root export is the full surface and always will be. Since 0.10.0 each intern
|
|
|
15
15
|
| `@ai-matrx/content-ir` | everything below |
|
|
16
16
|
| `@ai-matrx/content-ir/core` | IR types + tree, JSON tokenizer, kind parser, snapshots, normalize, fingerprint, discriminator, envelope read/value/cache, region, schema structure |
|
|
17
17
|
| `@ai-matrx/content-ir/session` | `ParseSession` and the one-writer-per-identity registry |
|
|
18
|
-
| `@ai-matrx/content-ir/registry` | kind registry types, storage transform, the dual gate |
|
|
18
|
+
| `@ai-matrx/content-ir/registry` | kind registry types, storage transform, the dual gate, `createKindValidator` over a host `SchemaSourcePort` |
|
|
19
19
|
| `@ai-matrx/content-ir/convert` | kind ⇄ JSON Schema, the OpenAI structured-output converter |
|
|
20
20
|
| `@ai-matrx/content-ir/wire` | partial-kind events, runtime wrapper readers, emit payload |
|
|
21
21
|
| `@ai-matrx/content-ir/directives` | Kind Directives: slug grammar, the ONE decoder |
|
package/dist/index.cjs
CHANGED
|
@@ -2968,6 +2968,93 @@ function describeDualGateFailure(kind, result) {
|
|
|
2968
2968
|
return `kind "${kind}" failed the dual gate \u2014 ${parts.join(" | ")}`;
|
|
2969
2969
|
}
|
|
2970
2970
|
|
|
2971
|
+
// registry/kind-validator.ts
|
|
2972
|
+
var SCHEMA_COMPILE_FAILURE_PREFIX = "emitted_json_schema failed to compile:";
|
|
2973
|
+
var DEFAULT_CACHE_TTL_MS = 3e4;
|
|
2974
|
+
function unavailableMessage(kind, reason, detail) {
|
|
2975
|
+
switch (reason) {
|
|
2976
|
+
case "kind_not_registered":
|
|
2977
|
+
return `kind "${kind}" is not registered in content_ir.kind_definition`;
|
|
2978
|
+
case "schema_unavailable":
|
|
2979
|
+
return `kind "${kind}" has no emitted_json_schema \u2014 nothing to validate against`;
|
|
2980
|
+
case "schema_invalid":
|
|
2981
|
+
return `kind "${kind}" has an uncompilable emitted_json_schema${detail ? `: ${detail}` : ""}`;
|
|
2982
|
+
case "catalog_unreachable":
|
|
2983
|
+
return `could not read the contract for kind "${kind}"${detail ? `: ${detail}` : ""}`;
|
|
2984
|
+
}
|
|
2985
|
+
}
|
|
2986
|
+
function degraded(kind, reason, detail) {
|
|
2987
|
+
return {
|
|
2988
|
+
kind,
|
|
2989
|
+
checked: false,
|
|
2990
|
+
ok: false,
|
|
2991
|
+
errors: [unavailableMessage(kind, reason, detail)],
|
|
2992
|
+
degradedReason: reason
|
|
2993
|
+
};
|
|
2994
|
+
}
|
|
2995
|
+
function createKindValidator(source, options = {}) {
|
|
2996
|
+
const ttl = options.cacheTtlMs ?? DEFAULT_CACHE_TTL_MS;
|
|
2997
|
+
const now = options.now ?? Date.now;
|
|
2998
|
+
const cache = /* @__PURE__ */ new Map();
|
|
2999
|
+
async function fetchSchema(kind, signal) {
|
|
3000
|
+
const cached = cache.get(kind);
|
|
3001
|
+
if (cached && now() - cached.fetchedAt <= ttl) {
|
|
3002
|
+
return { schema: cached.schema, version: cached.version };
|
|
3003
|
+
}
|
|
3004
|
+
let answer;
|
|
3005
|
+
try {
|
|
3006
|
+
answer = await source.kindSchema(kind, signal);
|
|
3007
|
+
} catch (err) {
|
|
3008
|
+
return {
|
|
3009
|
+
unavailable: "catalog_unreachable",
|
|
3010
|
+
detail: err instanceof Error ? err.message : String(err)
|
|
3011
|
+
};
|
|
3012
|
+
}
|
|
3013
|
+
if ("unavailable" in answer) return { unavailable: answer.unavailable };
|
|
3014
|
+
if (answer.schema == null) {
|
|
3015
|
+
return { unavailable: "schema_unavailable" };
|
|
3016
|
+
}
|
|
3017
|
+
cache.set(kind, {
|
|
3018
|
+
schema: answer.schema,
|
|
3019
|
+
version: answer.version,
|
|
3020
|
+
fetchedAt: now()
|
|
3021
|
+
});
|
|
3022
|
+
return answer;
|
|
3023
|
+
}
|
|
3024
|
+
return {
|
|
3025
|
+
async validate(value, kind, signal = new AbortController().signal) {
|
|
3026
|
+
if (!kind || typeof kind !== "string") {
|
|
3027
|
+
throw new TypeError(
|
|
3028
|
+
`validateAgainstKind: "kind" must be a non-empty slug (received ${typeof kind})`
|
|
3029
|
+
);
|
|
3030
|
+
}
|
|
3031
|
+
const fetched = await fetchSchema(kind, signal);
|
|
3032
|
+
if ("unavailable" in fetched) {
|
|
3033
|
+
return degraded(kind, fetched.unavailable, fetched.detail);
|
|
3034
|
+
}
|
|
3035
|
+
const leg = validateStructuralLeg(value, fetched.schema);
|
|
3036
|
+
if (!leg.ok && leg.detail?.startsWith(SCHEMA_COMPILE_FAILURE_PREFIX)) {
|
|
3037
|
+
return degraded(kind, "schema_invalid", leg.detail);
|
|
3038
|
+
}
|
|
3039
|
+
return {
|
|
3040
|
+
kind,
|
|
3041
|
+
checked: true,
|
|
3042
|
+
ok: leg.ok,
|
|
3043
|
+
errors: leg.ok ? [] : [leg.detail ?? "validation failed"],
|
|
3044
|
+
degradedReason: null
|
|
3045
|
+
};
|
|
3046
|
+
},
|
|
3047
|
+
async cachedSchema(kind, signal = new AbortController().signal) {
|
|
3048
|
+
const fetched = await fetchSchema(kind, signal);
|
|
3049
|
+
return "unavailable" in fetched ? null : fetched.schema;
|
|
3050
|
+
},
|
|
3051
|
+
invalidate(kind) {
|
|
3052
|
+
if (kind) cache.delete(kind);
|
|
3053
|
+
else cache.clear();
|
|
3054
|
+
}
|
|
3055
|
+
};
|
|
3056
|
+
}
|
|
3057
|
+
|
|
2971
3058
|
// convert/openai-schema-converter.ts
|
|
2972
3059
|
function requiredNullableFlags(required, nullable) {
|
|
2973
3060
|
return {
|
|
@@ -5243,12 +5330,6 @@ function fenceOpenerOf(content) {
|
|
|
5243
5330
|
return null;
|
|
5244
5331
|
}
|
|
5245
5332
|
var FenceReader = class {
|
|
5246
|
-
constructor(opener, options = {}) {
|
|
5247
|
-
this.opener = opener;
|
|
5248
|
-
this.isJson = opener.char === "`" && opener.lang === "json";
|
|
5249
|
-
this.nesting = opener.char === "`" && (options.nesting ?? fenceNestsInnerFences(opener.lang));
|
|
5250
|
-
this.tildeCloser = opener.char === "~" ? new RegExp(`^ {0,3}~{${opener.ticks},}[ \\t]*$`) : null;
|
|
5251
|
-
}
|
|
5252
5333
|
opener;
|
|
5253
5334
|
state = { inString: false, escaped: false };
|
|
5254
5335
|
depth = 0;
|
|
@@ -5257,6 +5338,12 @@ var FenceReader = class {
|
|
|
5257
5338
|
isJson;
|
|
5258
5339
|
nesting;
|
|
5259
5340
|
tildeCloser;
|
|
5341
|
+
constructor(opener, options = {}) {
|
|
5342
|
+
this.opener = opener;
|
|
5343
|
+
this.isJson = opener.char === "`" && opener.lang === "json";
|
|
5344
|
+
this.nesting = opener.char === "`" && (options.nesting ?? fenceNestsInnerFences(opener.lang));
|
|
5345
|
+
this.tildeCloser = opener.char === "~" ? new RegExp(`^ {0,3}~{${opener.ticks},}[ \\t]*$`) : null;
|
|
5346
|
+
}
|
|
5260
5347
|
/** How many nested fences are open right now. */
|
|
5261
5348
|
get nestedDepth() {
|
|
5262
5349
|
return this.depth;
|
|
@@ -5561,7 +5648,7 @@ function pendingCodeSpanStart(text) {
|
|
|
5561
5648
|
const n = text.length;
|
|
5562
5649
|
if (n === 0 || /\n[ \t]*\n[ \t]*$/.test(text)) return -1;
|
|
5563
5650
|
const lastLine = text.slice(text.lastIndexOf("\n") + 1);
|
|
5564
|
-
if (lastLine && /^(?: {0,3}>[ \t]?)*[ \t]*$/.test(lastLine)) return pendingCodeSpanStart(`${text}x`);
|
|
5651
|
+
if (lastLine && /^(?: {0,3}>[ \t]?)*[ \t\r]*$/.test(lastLine)) return pendingCodeSpanStart(`${text}x`);
|
|
5565
5652
|
const s = scan(text);
|
|
5566
5653
|
const para = s.pendingPara;
|
|
5567
5654
|
if (s.endsInFence || para === -1) return -1;
|
|
@@ -5725,7 +5812,7 @@ function isVariableChain(content, after) {
|
|
|
5725
5812
|
const run = /^[A-Za-z0-9_]+/.exec(after)?.[0];
|
|
5726
5813
|
if (!run) return false;
|
|
5727
5814
|
if (after.length === 1) return false;
|
|
5728
|
-
if (/^[A-Za-z_][A-Za-z0-9_]*[.@-]$/.test(content)) return true;
|
|
5815
|
+
if (/^[A-Za-z_][A-Za-z0-9_]*(?:[.@-]|->|::)$/.test(content)) return true;
|
|
5729
5816
|
return IDENTIFIER.test(content) && !MATH_SUFFIX.test(run);
|
|
5730
5817
|
}
|
|
5731
5818
|
var FUNCTION_NAMES = /* @__PURE__ */ new Set([
|
|
@@ -5874,9 +5961,6 @@ function isEscapedBacktick(line, offset) {
|
|
|
5874
5961
|
return slashes % 2 === 1;
|
|
5875
5962
|
}
|
|
5876
5963
|
var XmlContainerTracker = class {
|
|
5877
|
-
constructor(rootTag) {
|
|
5878
|
-
this.rootTag = rootTag;
|
|
5879
|
-
}
|
|
5880
5964
|
rootTag;
|
|
5881
5965
|
depth = 0;
|
|
5882
5966
|
inComment = false;
|
|
@@ -5884,6 +5968,9 @@ var XmlContainerTracker = class {
|
|
|
5884
5968
|
inlineTicks = 0;
|
|
5885
5969
|
/** The open fence, read by THE one closer (source/code-ranges.ts). */
|
|
5886
5970
|
fence = null;
|
|
5971
|
+
constructor(rootTag) {
|
|
5972
|
+
this.rootTag = rootTag;
|
|
5973
|
+
}
|
|
5887
5974
|
consumeLine(line, startOffset = 0) {
|
|
5888
5975
|
if (this.fence) {
|
|
5889
5976
|
if (this.fence.feed(line)) this.fence = null;
|
|
@@ -6095,6 +6182,23 @@ function isSplitterTreeLine(line) {
|
|
|
6095
6182
|
}
|
|
6096
6183
|
var MEDIA_REF_PREFIXES = ["[Image URL:", "[Video URL:", "[Audio URL:"];
|
|
6097
6184
|
var Tokenizer = class {
|
|
6185
|
+
text;
|
|
6186
|
+
streaming;
|
|
6187
|
+
meter;
|
|
6188
|
+
n;
|
|
6189
|
+
lineStarts = [];
|
|
6190
|
+
contentEnds = [];
|
|
6191
|
+
lineEnds = [];
|
|
6192
|
+
blocks = [];
|
|
6193
|
+
blockCache = /* @__PURE__ */ new Map();
|
|
6194
|
+
/** Lazily built: for line i, first line j >= i where brace net from i drops to <= 0. */
|
|
6195
|
+
braceStop = null;
|
|
6196
|
+
braceNet = null;
|
|
6197
|
+
/** Every occurrence offset of each needle searched so far (overlapping, like indexOf). */
|
|
6198
|
+
occurrences = /* @__PURE__ */ new Map();
|
|
6199
|
+
/** `$$` opener → closer for the pairs the core renders as math. */
|
|
6200
|
+
mathPairs;
|
|
6201
|
+
finder = (needle, from) => this.next(needle, from);
|
|
6098
6202
|
constructor(text, streaming = false, meter = void 0) {
|
|
6099
6203
|
this.text = text;
|
|
6100
6204
|
this.streaming = streaming;
|
|
@@ -6113,7 +6217,7 @@ var Tokenizer = class {
|
|
|
6113
6217
|
if (close >= span) this.provisionalFrom = Math.min(this.provisionalFrom, open);
|
|
6114
6218
|
}
|
|
6115
6219
|
}
|
|
6116
|
-
for (const pad of ["`", "``", "```", "~~~"]) {
|
|
6220
|
+
for (const pad of ["`", "``", "```", "~~~", "$"]) {
|
|
6117
6221
|
const alt = pairDisplayMath(text + pad);
|
|
6118
6222
|
for (const [open, close] of this.mathPairs) {
|
|
6119
6223
|
if (alt.get(open) !== close) this.provisionalFrom = Math.min(this.provisionalFrom, open);
|
|
@@ -6141,40 +6245,10 @@ var Tokenizer = class {
|
|
|
6141
6245
|
this.lineEnds.push(text.length);
|
|
6142
6246
|
}
|
|
6143
6247
|
}
|
|
6144
|
-
text;
|
|
6145
|
-
streaming;
|
|
6146
|
-
meter;
|
|
6147
|
-
n;
|
|
6148
|
-
lineStarts = [];
|
|
6149
|
-
contentEnds = [];
|
|
6150
|
-
lineEnds = [];
|
|
6151
|
-
blocks = [];
|
|
6152
|
-
blockCache = /* @__PURE__ */ new Map();
|
|
6153
|
-
/** Lazily built: for line i, first line j >= i where brace net from i drops to <= 0. */
|
|
6154
|
-
braceStop = null;
|
|
6155
|
-
braceNet = null;
|
|
6156
|
-
/** Every occurrence offset of each needle searched so far (overlapping, like indexOf). */
|
|
6157
|
-
occurrences = /* @__PURE__ */ new Map();
|
|
6158
|
-
/** `$$` opener → closer for the pairs the core renders as math. */
|
|
6159
|
-
mathPairs;
|
|
6160
|
-
finder = (needle, from) => this.next(needle, from);
|
|
6161
6248
|
/** Streaming: where provisional text starts (a pending `$$`), or +∞. */
|
|
6162
6249
|
provisionalFrom = Number.POSITIVE_INFINITY;
|
|
6163
6250
|
/** Streaming: the text ends in a lone CR whose LF has not arrived yet. */
|
|
6164
6251
|
pendingCR = false;
|
|
6165
|
-
/**
|
|
6166
|
-
* Streaming: an open last line that begins with `{` is undecided — each new
|
|
6167
|
-
* byte can balance or unbalance its braces and flip the whole line between
|
|
6168
|
-
* prose and a JSON island — so it is provisional until it ends (G5).
|
|
6169
|
-
* (A lone HTML tag on that line is held by {@link holdUndecidedTail}.)
|
|
6170
|
-
*/
|
|
6171
|
-
markOpenJsonTail() {
|
|
6172
|
-
const last = this.lineStarts.length - 1;
|
|
6173
|
-
if (!this.isOpenTail(last)) return;
|
|
6174
|
-
if (this.lineText(last).trim().startsWith("{")) {
|
|
6175
|
-
this.provisionalFrom = Math.min(this.provisionalFrom, this.lineStarts[last]);
|
|
6176
|
-
}
|
|
6177
|
-
}
|
|
6178
6252
|
/**
|
|
6179
6253
|
* `text.indexOf(needle, from)` in O(log k): the first query for a needle
|
|
6180
6254
|
* indexes all of its occurrences once, so repeated searches for a closer
|
|
@@ -6209,7 +6283,7 @@ var Tokenizer = class {
|
|
|
6209
6283
|
const rest = this.n - pe;
|
|
6210
6284
|
if (rest === 0) return true;
|
|
6211
6285
|
const tail = this.text.slice(pe);
|
|
6212
|
-
return /^(?:\r\n|\r|\n)[ \t]*$/.test(tail);
|
|
6286
|
+
return /^(?:\r\n|\r|\n)[ \t\r]*$/.test(tail);
|
|
6213
6287
|
}
|
|
6214
6288
|
/**
|
|
6215
6289
|
* Streaming: an open block that may still turn back into prose — a `$$`
|
|
@@ -6218,7 +6292,9 @@ var Tokenizer = class {
|
|
|
6218
6292
|
* or any opener that is itself still arriving on the open last line.
|
|
6219
6293
|
*/
|
|
6220
6294
|
mayDissolve(block) {
|
|
6221
|
-
if (!this.streaming
|
|
6295
|
+
if (!this.streaming) return false;
|
|
6296
|
+
if (block.start >= this.provisionalFrom) return true;
|
|
6297
|
+
if (block.complete) return false;
|
|
6222
6298
|
if (block.type === "math_block" || block.type === "json") return true;
|
|
6223
6299
|
return this.isOpenTail(this.lineOf(block.start));
|
|
6224
6300
|
}
|
|
@@ -6257,7 +6333,6 @@ var Tokenizer = class {
|
|
|
6257
6333
|
return this.text.slice(this.lineStarts[li], this.contentEnds[li]);
|
|
6258
6334
|
}
|
|
6259
6335
|
run() {
|
|
6260
|
-
if (this.streaming) this.markOpenJsonTail();
|
|
6261
6336
|
let pos = 0;
|
|
6262
6337
|
while (pos < this.n) {
|
|
6263
6338
|
const li = this.lineOf(pos);
|
|
@@ -6304,12 +6379,6 @@ var Tokenizer = class {
|
|
|
6304
6379
|
const last = this.lineStarts.length - 1;
|
|
6305
6380
|
if (last < 0) return;
|
|
6306
6381
|
if (this.isOpenTail(last)) {
|
|
6307
|
-
const lineStart = this.lineStarts[last];
|
|
6308
|
-
for (const block2 of this.blocks) {
|
|
6309
|
-
if (block2.kind === "prose" && block2.end > lineStart) {
|
|
6310
|
-
block2.inlines = block2.inlines.filter((inline) => inline.end <= lineStart);
|
|
6311
|
-
}
|
|
6312
|
-
}
|
|
6313
6382
|
let b = this.blocks.length - 1;
|
|
6314
6383
|
while (b >= 0 && this.blocks[b].kind === "gap") b--;
|
|
6315
6384
|
const block = this.blocks[b];
|
|
@@ -6501,7 +6570,7 @@ var Tokenizer = class {
|
|
|
6501
6570
|
return { type, start, end, complete, meta };
|
|
6502
6571
|
}
|
|
6503
6572
|
frontMatter(li, t) {
|
|
6504
|
-
const fence = this.lineText(li);
|
|
6573
|
+
const fence = this.lineText(li).replace(/^\uFEFF/, "");
|
|
6505
6574
|
if (fence !== "---" && fence !== "+++" || t !== fence) return null;
|
|
6506
6575
|
const toml = fence === "+++";
|
|
6507
6576
|
let sawContent = false;
|
|
@@ -6512,9 +6581,13 @@ var Tokenizer = class {
|
|
|
6512
6581
|
}
|
|
6513
6582
|
if (!NOT_WHITESPACE.test(line)) continue;
|
|
6514
6583
|
const shaped = toml ? /^\s*(?:[A-Za-z0-9_."-]+\s*=|\[|#)/.test(line) : /^(?:[A-Za-z0-9_"'-][^:]*:(?:\s|$)|\s+\S|-\s|#)/.test(line);
|
|
6515
|
-
if (!shaped)
|
|
6584
|
+
if (!shaped) {
|
|
6585
|
+
if (this.isOpenTail(k)) break;
|
|
6586
|
+
return null;
|
|
6587
|
+
}
|
|
6516
6588
|
sawContent = true;
|
|
6517
6589
|
}
|
|
6590
|
+
if (this.streaming) return this.island("front_matter", 0, this.n, false, { format: toml ? "toml" : "yaml" });
|
|
6518
6591
|
return null;
|
|
6519
6592
|
}
|
|
6520
6593
|
/**
|
|
@@ -6915,7 +6988,9 @@ var Tokenizer = class {
|
|
|
6915
6988
|
const block = this.detectBlock(this.lineStarts[k], k, false);
|
|
6916
6989
|
if (block) {
|
|
6917
6990
|
breakLine = k;
|
|
6918
|
-
if (this.mayDissolve(block))
|
|
6991
|
+
if (this.mayDissolve(block)) {
|
|
6992
|
+
this.undecidedBreaks.add(end);
|
|
6993
|
+
}
|
|
6919
6994
|
break;
|
|
6920
6995
|
}
|
|
6921
6996
|
end = this.contentEnds[k];
|
|
@@ -7260,12 +7335,12 @@ function blockAt(blocks, offset) {
|
|
|
7260
7335
|
|
|
7261
7336
|
// source/splice.ts
|
|
7262
7337
|
var SourceSpliceError = class extends Error {
|
|
7338
|
+
code;
|
|
7263
7339
|
constructor(code, message) {
|
|
7264
7340
|
super(message);
|
|
7265
7341
|
this.code = code;
|
|
7266
7342
|
this.name = "SourceSpliceError";
|
|
7267
7343
|
}
|
|
7268
|
-
code;
|
|
7269
7344
|
};
|
|
7270
7345
|
function blockEdit(block, text) {
|
|
7271
7346
|
return { start: block.start, end: block.end, text };
|
|
@@ -7597,6 +7672,7 @@ exports.compareWithExistingKindSchema = compareWithExistingKindSchema;
|
|
|
7597
7672
|
exports.convertAiSchemaToBlockFields = convertAiSchemaToBlockFields;
|
|
7598
7673
|
exports.createFingerprinter = createFingerprinter;
|
|
7599
7674
|
exports.createKindStreamParser = createKindStreamParser;
|
|
7675
|
+
exports.createKindValidator = createKindValidator;
|
|
7600
7676
|
exports.decodeDirective = decodeDirective;
|
|
7601
7677
|
exports.describeDualGateFailure = describeDualGateFailure;
|
|
7602
7678
|
exports.directiveDisplay = directiveDisplay;
|