@ai-matrx/content-ir 0.21.2 → 0.22.2
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 +41 -0
- package/dist/index.cjs +1 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/source.cjs +1 -0
- package/dist/source.cjs.map +1 -1
- package/dist/source.js +1 -0
- package/dist/source.js.map +1 -1
- package/dist/surfaces.cjs +3437 -0
- package/dist/surfaces.cjs.map +1 -0
- package/dist/surfaces.d.cts +870 -0
- package/dist/surfaces.d.ts +870 -0
- package/dist/surfaces.js +3354 -0
- package/dist/surfaces.js.map +1 -0
- package/package.json +15 -2
|
@@ -0,0 +1,870 @@
|
|
|
1
|
+
import { C as CanonicalBlockIR } from './ir-types-95bA2cXH.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* THE KIND SIGNAL of a JSON region's text — the one answer to "could this
|
|
5
|
+
* still be a kind?" (Arman, 2026-09-30):
|
|
6
|
+
*
|
|
7
|
+
* 1. The moment it COULD be a kind → display as a kind (its loader).
|
|
8
|
+
* 2. The moment we know WHICH kind → that kind (the parser's job).
|
|
9
|
+
* 3. The moment we know it is not a kind → it is JSON, and JSON is fine.
|
|
10
|
+
*
|
|
11
|
+
* "Could" is decided by the FIRST KEY. Until the first key has fully arrived
|
|
12
|
+
* the region is `undecided` and nothing raw is shown. A first key of `__kind`
|
|
13
|
+
* — or a `__kind` key anywhere in the text, at any depth, at any time — is
|
|
14
|
+
* `kind`. A complete first key that is anything else, with no `__kind` seen,
|
|
15
|
+
* is `not_kind`: the region streams live as JSON, and flips to `kind` the
|
|
16
|
+
* instant a `__kind` key shows up later.
|
|
17
|
+
*
|
|
18
|
+
* Pure and text-only on purpose: it must answer for every frame of every
|
|
19
|
+
* region, including ones whose parser never opened (an unlabelled fence, a
|
|
20
|
+
* reload, a plain markdown fence).
|
|
21
|
+
*/
|
|
22
|
+
type JsonKindSignal = "undecided" | "kind" | "not_kind";
|
|
23
|
+
/**
|
|
24
|
+
* Options for the JSON-text readers: `json5` widens the key rule to JSON5's;
|
|
25
|
+
* `markdown` also reads the markdown-escaped key (`"\_\_kind"`, P8);
|
|
26
|
+
* `escaped` also reads the backslash-escaped key of a string-held kind
|
|
27
|
+
* (`\"__kind\"`, R3 round 6 — screen and search text only).
|
|
28
|
+
*/
|
|
29
|
+
interface KindTextOptions {
|
|
30
|
+
json5?: boolean;
|
|
31
|
+
markdown?: boolean;
|
|
32
|
+
escaped?: boolean;
|
|
33
|
+
/** Also read a Python-repr key (`{'__kind': 'flashcard_set'}`) — text contexts only (K4). */
|
|
34
|
+
python?: boolean;
|
|
35
|
+
/** Also read a typographic-quoted key (`“__kind”`, `‘__kind’`) — text contexts only (round 8). */
|
|
36
|
+
smart?: boolean;
|
|
37
|
+
/** Also read an HTML-entity key (`"__kind"`, `"__kind"`) — text contexts only (round 8). */
|
|
38
|
+
entity?: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* Also read a JavaScript object-literal key (`{ __kind: 'flashcard_set' }` —
|
|
41
|
+
* what Node's console prints, a sandbox tool's output) — key position with a
|
|
42
|
+
* quoted value, text contexts only (L-2, round 9).
|
|
43
|
+
*/
|
|
44
|
+
js?: boolean;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* EVERY spelling of the key a reader still sees as `__kind` (owner ruling,
|
|
48
|
+
* round 8): literal, `\u005f`-escaped, markdown-escaped `\_\_kind`,
|
|
49
|
+
* backslash-escaped quotes `\"__kind\"`, zero-width characters anywhere in
|
|
50
|
+
* the key, Python repr `'__kind'`, typographic quotes `“__kind”` and HTML
|
|
51
|
+
* entities `"__kind"`. THE options every TEXT context (prose,
|
|
52
|
+
* titles, exports, previews, the screen scan) passes; JSON contexts keep the
|
|
53
|
+
* default, where those spellings are string VALUES (and `valueCarriesKind`
|
|
54
|
+
* reads the strings with this set).
|
|
55
|
+
*/
|
|
56
|
+
declare const ALL_KIND_SPELLINGS: Readonly<KindTextOptions>;
|
|
57
|
+
/**
|
|
58
|
+
* THE CONVERSION BOUNDARY (owner ruling, round 10): only REAL JSON is ever
|
|
59
|
+
* converted — the literal key, its `\u005f` escapes, the markdown-escaped
|
|
60
|
+
* `"\_\_kind"` (markdown draws it as the literal key) and zero-width characters
|
|
61
|
+
* inside the key. Every other spelling in free text (backslash-escaped
|
|
62
|
+
* `\"__kind\"` in prose, Python repr, a JavaScript literal, typographic quotes,
|
|
63
|
+
* entities) is DETECTION ONLY: the leak sentinel reports it, every renderer,
|
|
64
|
+
* converter, label and export leaves it exactly as written. Real output emits
|
|
65
|
+
* JSON; guessing at free text dropped and reordered people's words (rounds 8–9).
|
|
66
|
+
* A kind held as a JSON STRING inside JSON is read by parsing (`textCarriesKind`).
|
|
67
|
+
*/
|
|
68
|
+
declare const JSON_KIND_SPELLINGS: Readonly<KindTextOptions>;
|
|
69
|
+
/** Whether text holds the key spelled as real JSON (`JSON_KIND_SPELLINGS`). */
|
|
70
|
+
declare function hasJsonKindKey(source: string): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Whether text holds the key ONLY in a detection-only spelling (round 10):
|
|
73
|
+
* a spelling the sentinel reports and no renderer converts.
|
|
74
|
+
*/
|
|
75
|
+
declare function hasDetectionOnlyKindKey(source: string): boolean;
|
|
76
|
+
/** The text without zero-width characters (unchanged — same string — when it has none). */
|
|
77
|
+
declare function withoutZeroWidth(text: string): string;
|
|
78
|
+
/** Whether a fence language is JSON5 (the one context that widens the key rule). */
|
|
79
|
+
declare function isJson5Language(lang: string | null | undefined): boolean;
|
|
80
|
+
declare function hasKindKey(source: string, options?: KindTextOptions): boolean;
|
|
81
|
+
/**
|
|
82
|
+
* EXOTIC spellings (owner ruling, round 9): double HTML entities
|
|
83
|
+
* (`&quot;`), `_` underscores, upper-case / padded entities, fullwidth
|
|
84
|
+
* quotes, bidi marks, invisible operators and combining joiners inside the key.
|
|
85
|
+
* DETECTION ONLY — the leak sentinel and the frame judge report them; no
|
|
86
|
+
* renderer converts them (an adversarial spelling is a defect to see, not a
|
|
87
|
+
* shape to guess at).
|
|
88
|
+
*/
|
|
89
|
+
declare function hasExoticKindKey(text: string): boolean;
|
|
90
|
+
/** Whether TEXT holds the key in ANY spelling a reader sees as `__kind` (round 8). */
|
|
91
|
+
declare function hasKindKeyAnySpelling(source: string): boolean;
|
|
92
|
+
/** Whether a `__kind` value is a readable slug (ruling (c): anything else is broken output). */
|
|
93
|
+
declare function isKindSlug(value: unknown): value is string;
|
|
94
|
+
/**
|
|
95
|
+
* The first complete `__kind` slug in the text, or null. For a LOADER only —
|
|
96
|
+
* which kind's skeleton to show while the region arrives. Never an identity:
|
|
97
|
+
* the parser owns which kind a region actually is.
|
|
98
|
+
*/
|
|
99
|
+
declare function firstKindSlug(source: string, options?: KindTextOptions): string | null;
|
|
100
|
+
declare function endsInPartialKindKey(text: string): boolean;
|
|
101
|
+
/**
|
|
102
|
+
* The text after any LEADING JSONC comments and whitespace (`// note`,
|
|
103
|
+
* `/* … *\/`) — a ```jsonc / ```json / unlabelled fence that opens with a
|
|
104
|
+
* comment still decides on its first key (X3). An unterminated leading
|
|
105
|
+
* comment (still arriving) leaves nothing: undecided, never raw.
|
|
106
|
+
*/
|
|
107
|
+
declare function withoutLeadingJsonComments(text: string): string;
|
|
108
|
+
declare function jsonKindSignal(text: string | null | undefined, options?: KindTextOptions): JsonKindSignal;
|
|
109
|
+
/**
|
|
110
|
+
* A ```json5 body as plain JSON, when the difference is only what JSON5 adds
|
|
111
|
+
* that models actually write: comments, unquoted identifier keys, single-quoted
|
|
112
|
+
* keys/strings and trailing commas. Null when the result still will not parse.
|
|
113
|
+
*/
|
|
114
|
+
declare function json5AsJson(text: string): string | null;
|
|
115
|
+
/**
|
|
116
|
+
* A Python repr of a dict/list (`{'__kind': 'flashcard_set', 'ok': True}`) as
|
|
117
|
+
* JSON text, or null when it is not one. Strings may be single- or
|
|
118
|
+
* double-quoted; `True` / `False` / `None` become JSON literals.
|
|
119
|
+
*/
|
|
120
|
+
declare function pythonReprAsJson(text: string): string | null;
|
|
121
|
+
/** Whether text holds a Python-repr `'__kind'` key (key position, quoted value). */
|
|
122
|
+
declare function hasPythonKindKey(text: string): boolean;
|
|
123
|
+
/** Where the Python-repr value opening at `start` (`{` or `[`) closes (exclusive), or null. */
|
|
124
|
+
declare function pythonBalancedEnd(text: string, start: number): number | null;
|
|
125
|
+
/**
|
|
126
|
+
* THE ONE SPELLING NORMALIZER (K4 round 7, widened round 8, rebuilt round 9).
|
|
127
|
+
* Every text detector, converter and label function runs it (directly, or
|
|
128
|
+
* through `hasKindKeyAnySpelling`) so a kind spelled any REALISTIC way the
|
|
129
|
+
* screen still reads as a kind converts like any other. Each spelled region —
|
|
130
|
+
* from the `{` that owns the key to where its own grammar ends — is rewritten
|
|
131
|
+
* as canonical JSON:
|
|
132
|
+
*
|
|
133
|
+
* zero-width in the key · HTML entities · typographic quotes ·
|
|
134
|
+
* backslash-escaped quotes (any depth) · markdown-escaped `\_` · Python repr ·
|
|
135
|
+
* JavaScript object literal — and any combination of them in one key
|
|
136
|
+
*
|
|
137
|
+
* DO NO HARM (owner ruling, round 9): only characters INSIDE a matched region
|
|
138
|
+
* change (a zero-width character only inside the key itself), a region never
|
|
139
|
+
* reaches past the point where its grammar breaks (an unclosed region in prose
|
|
140
|
+
* ends there and the text after it stays), and the scan is one linear pass.
|
|
141
|
+
* Quoted source (inline code, non-JSON fences) stays as written, and a WHOLE
|
|
142
|
+
* JSON text is never rewritten (a spelling inside it is a string VALUE).
|
|
143
|
+
* Text with no non-canonical spelling comes back as the same string.
|
|
144
|
+
*/
|
|
145
|
+
declare function normalizeKindSpellings(source: string): string;
|
|
146
|
+
/** How a kind key is spelled — which decoders turn its region into JSON. */
|
|
147
|
+
type KindSpellingFamily = "lifted" | "escaped" | "markdown" | "python" | "smart" | "entity" | "js";
|
|
148
|
+
/**
|
|
149
|
+
* A kind region in a REALISTIC spelling (round 9). `[start, end)` is the raw
|
|
150
|
+
* region (`{` to where its grammar ended); `[rewriteStart, rewriteEnd)` is what
|
|
151
|
+
* the normalizer replaces (the key alone for a literal key holding only a
|
|
152
|
+
* zero-width character). `status`: `complete` (balanced), `prefix` (still
|
|
153
|
+
* arriving — runs to the end of the text) or `broken` (its grammar failed at
|
|
154
|
+
* `end`; the text after it is NOT part of it). `decoded` is the region's text
|
|
155
|
+
* with its spelling undone (still Python / JS for those families).
|
|
156
|
+
*/
|
|
157
|
+
interface KindSpellingRegion {
|
|
158
|
+
start: number;
|
|
159
|
+
end: number;
|
|
160
|
+
rewriteStart: number;
|
|
161
|
+
rewriteEnd: number;
|
|
162
|
+
family: KindSpellingFamily;
|
|
163
|
+
status: "complete" | "prefix" | "broken";
|
|
164
|
+
decoded: string;
|
|
165
|
+
/** Whether the key carried the markdown `\_` (the region was markdown-decoded). */
|
|
166
|
+
markdown: boolean;
|
|
167
|
+
/** A literal key's canonical text (the normalizer's whole rewrite for that family). */
|
|
168
|
+
keyText?: string;
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* A cheap pre-check every scanner runs first: no key spelling can exist
|
|
172
|
+
* without `kind` (or a zero-width character splitting it). Linear, no regex
|
|
173
|
+
* restarts — the plain text of every frame pays only this.
|
|
174
|
+
*/
|
|
175
|
+
declare function mayHoldKindKey(text: string): boolean;
|
|
176
|
+
/**
|
|
177
|
+
* THE ONE LINEAR SCAN for kind regions in a realistic spelling (round 9):
|
|
178
|
+
* every candidate is found from a `kind` occurrence, its owning `{` from a
|
|
179
|
+
* forward-only brace cursor, quoted source once, and each region is decoded
|
|
180
|
+
* and bounded by its own grammar in work proportional to its length. Regions
|
|
181
|
+
* are returned in order and never overlap; a region's inner keys belong to it.
|
|
182
|
+
* A key whose `{` grammar fails BEFORE the key is not a region (prose braces).
|
|
183
|
+
*/
|
|
184
|
+
declare function scanKindSpellingRegions(text: string, options?: {
|
|
185
|
+
families?: "json" | "all";
|
|
186
|
+
from?: number;
|
|
187
|
+
}): KindSpellingRegion[];
|
|
188
|
+
/**
|
|
189
|
+
* Past this many characters an open bare-JSON region is not re-read for a
|
|
190
|
+
* prose break (a hot-path budget: the check is linear in the region, run per
|
|
191
|
+
* line / fragment). A fragment that breaks into prose does so within its first
|
|
192
|
+
* lines; a long region is real JSON streaming.
|
|
193
|
+
*/
|
|
194
|
+
declare const BARE_REGION_GRAMMAR_BUDGET = 16384;
|
|
195
|
+
/**
|
|
196
|
+
* Whether an open bare-JSON region's text has BROKEN INTO PROSE by its own JSON
|
|
197
|
+
* grammar (round 10, C1): `{"status": "ok", "items": [` then a line of words,
|
|
198
|
+
* `{\"__kind\":…} and the rest`, `{ some code`. Such a region was never JSON:
|
|
199
|
+
* it reads as text. THE one answer the live accumulator (per line, budgeted)
|
|
200
|
+
* and the reload splitter (whole region, `firstBudget` — the same first 16 KB
|
|
201
|
+
* the live check reads) share, so live ≡ reload (round 11, H1). A region still
|
|
202
|
+
* validly open (or complete) is not broken.
|
|
203
|
+
*/
|
|
204
|
+
declare function bareRegionBreaksIntoProse(text: string, options?: {
|
|
205
|
+
firstBudget?: boolean;
|
|
206
|
+
}): boolean;
|
|
207
|
+
/**
|
|
208
|
+
* Where a LITERAL kind object (`text` opens at its `{`) breaks into prose —
|
|
209
|
+
* `{"__kind":"note","title":"Hi" and then…` — after its key: the end of the
|
|
210
|
+
* region, or null (complete, still arriving, or merely malformed). THE one
|
|
211
|
+
* answer the converters, the prose leaf and the live accumulator share, so a
|
|
212
|
+
* settled unclosed object reads the same live and reloaded (L-4, round 9).
|
|
213
|
+
*/
|
|
214
|
+
declare function kindObjectProseBreak(text: string): number | null;
|
|
215
|
+
/** Which JSON-like grammar bounds a region: strict JSON, Python repr, or a JavaScript literal. */
|
|
216
|
+
type GrammarDialect = "json" | "python" | "js";
|
|
217
|
+
type KindGrammarVerdict = {
|
|
218
|
+
status: "complete";
|
|
219
|
+
end: number;
|
|
220
|
+
} | {
|
|
221
|
+
status: "prefix";
|
|
222
|
+
} | {
|
|
223
|
+
status: "broken";
|
|
224
|
+
at: number;
|
|
225
|
+
cut: number;
|
|
226
|
+
prose: boolean;
|
|
227
|
+
};
|
|
228
|
+
/**
|
|
229
|
+
* Where a JSON-like value opening at 0 ends by its OWN grammar (H-1, round 9):
|
|
230
|
+
* `complete` at its balanced close, `prefix` when the text ends while it is
|
|
231
|
+
* still valid (arriving), or `broken` at the first character that cannot
|
|
232
|
+
* continue it — `cut` is the end of the last whole token before that (after a
|
|
233
|
+
* value, a `,`, or an opener), so the text after `cut` is never part of it.
|
|
234
|
+
* A raw newline inside a string breaks it (JSON strings never hold one), so an
|
|
235
|
+
* unclosed string never runs past its line. One pass, no allocation per char.
|
|
236
|
+
*/
|
|
237
|
+
declare function kindGrammar(s: string, dialect?: GrammarDialect, from?: number): KindGrammarVerdict;
|
|
238
|
+
/** A complete region as JSON text (Python / JS converted), or null when it will not read. */
|
|
239
|
+
declare function regionJson(region: Pick<KindSpellingRegion, "family" | "decoded">): string | null;
|
|
240
|
+
/**
|
|
241
|
+
* A BROKEN (settled, unclosed) region closed where its grammar ended: a
|
|
242
|
+
* dangling `,` or `key:` dropped, every open container closed — the reading
|
|
243
|
+
* the label is drawn from. Null when even that will not read.
|
|
244
|
+
*/
|
|
245
|
+
declare function closedJson(region: Pick<KindSpellingRegion, "family" | "decoded">): string | null;
|
|
246
|
+
/**
|
|
247
|
+
* The VALUE form of the same question, for renderers handed parsed data
|
|
248
|
+
* instead of text (the value grid, the JSON viewers): does this value carry a
|
|
249
|
+
* kind anywhere — an object with a string `__kind`, at any depth, or a string
|
|
250
|
+
* that holds a kind REGION (`textCarriesKind`: whole kind JSON, or prose with
|
|
251
|
+
* a kind in it — a ```json fence, inline JSON — outside quoted source)? A raw
|
|
252
|
+
* renderer that answers yes renders the value through the one value door
|
|
253
|
+
* (`AnswerValueView`) instead.
|
|
254
|
+
*/
|
|
255
|
+
declare function valueCarriesKind(value: unknown): boolean;
|
|
256
|
+
/**
|
|
257
|
+
* A STRING value that holds a kind region (H1, round 5): text that is kind
|
|
258
|
+
* JSON, or prose with a kind region in it by THE markdown definition
|
|
259
|
+
* (`markdownCarriesKind` — outside quoted source, markdown-escaped key too).
|
|
260
|
+
* `{answer: "Here are your cards: ```json {…kind…}```"}` carries its kind.
|
|
261
|
+
*/
|
|
262
|
+
declare function textCarriesKind(text: string): boolean;
|
|
263
|
+
/**
|
|
264
|
+
* Text that IS a JSON object/array carrying a `__kind` key (not prose
|
|
265
|
+
* mentioning one) — the gate before a `JSON.parse` of the whole text. For
|
|
266
|
+
* "does this string hold a kind anywhere", read `textCarriesKind`.
|
|
267
|
+
*/
|
|
268
|
+
declare function isKindJsonText(text: string): boolean;
|
|
269
|
+
/** The kind slug a value claims for itself at its root, or null. */
|
|
270
|
+
declare function rootKindSlug(value: unknown): string | null;
|
|
271
|
+
/** Whether a fence's language makes its body a JSON region (any case; none counts). */
|
|
272
|
+
declare function isJsonFenceLanguage(lang: string | null | undefined): boolean;
|
|
273
|
+
/**
|
|
274
|
+
* Where a kind in markdown is the model QUOTING SOURCE, never data (the
|
|
275
|
+
* owner's ruling, 2026-09-30): inside an inline code span, or inside a fence
|
|
276
|
+
* whose language is not JSON (```ts, ```xml, ```markdown …). Everything else
|
|
277
|
+
* — prose, a blockquote, a list item, a table cell, a 4-space indented block,
|
|
278
|
+
* a JSON fence — is data. [start, end) spans, in order. THE one definition:
|
|
279
|
+
* the splitter, the live accumulator and the leaf gate all read it, so a leaf
|
|
280
|
+
* and the pipeline can never disagree about what is a kind region.
|
|
281
|
+
*/
|
|
282
|
+
declare function quotedSourceRanges(text: string): Array<[number, number]>;
|
|
283
|
+
/**
|
|
284
|
+
* Whether an XML card SHOWS SOURCE (the owner's rulings, round 3): a ```xml
|
|
285
|
+
* FENCE is the model quoting source — a kind inside it stays as written (a).
|
|
286
|
+
* An XML TAG the model wraps content in (`<answer>`, `<output>`, any generic
|
|
287
|
+
* tag, closed or not) is STRUCTURE (b): the splitter and the accumulator mark
|
|
288
|
+
* every piece of it `genericXmlContainer`, and a kind inside its prose renders
|
|
289
|
+
* as the kind. THE one answer — XmlBlock's callers and the frame judge read it.
|
|
290
|
+
*/
|
|
291
|
+
declare function isQuotedSourceXmlBlock(block: {
|
|
292
|
+
metadata?: Record<string, unknown> | null;
|
|
293
|
+
}): boolean;
|
|
294
|
+
/**
|
|
295
|
+
* Where the front matter that opens `source` ends (0 when none): an optional
|
|
296
|
+
* byte-order mark, a first line that is exactly `---` or `+++`, through the
|
|
297
|
+
* same fence (YAML also `...`). Front matter is document properties, never
|
|
298
|
+
* content — a `{"__kind":…}` VALUE inside it is never a kind block, in the
|
|
299
|
+
* static splitter or the live accumulator (RC-B3r round 3, C1).
|
|
300
|
+
*/
|
|
301
|
+
declare function frontMatterEnd(source: string): number;
|
|
302
|
+
/**
|
|
303
|
+
* The MARKDOWN form: does this prose hold a kind REGION — a `__kind` key
|
|
304
|
+
* anywhere outside quoted source (see `quotedSourceRanges`)? A leaf that
|
|
305
|
+
* answers yes hands the text to the pipeline (`MarkdownStream`), which lifts
|
|
306
|
+
* the region by the same definition — prose, table cell, indented block,
|
|
307
|
+
* blockquote, JSON fence, or the whole text being kind JSON.
|
|
308
|
+
*/
|
|
309
|
+
declare function markdownCarriesKind(source: string): boolean;
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Recover complete self-described kind objects from ANY containing text.
|
|
313
|
+
*
|
|
314
|
+
* Markdown, code fences, and XML are arrival containers, not type authority.
|
|
315
|
+
* Once a complete JSON object directly declares a non-empty `__kind`, that
|
|
316
|
+
* object is its own Content IR region even when an outer parser already
|
|
317
|
+
* classified the surrounding bytes as code, XML, or prose.
|
|
318
|
+
*
|
|
319
|
+
* Generic XML opts into literal-context exclusion so tag attributes, code,
|
|
320
|
+
* comments, and CDATA remain examples owned by their container. Otherwise the
|
|
321
|
+
* scanner is syntax-agnostic about the outer container. It only promotes candidates that independently pass JSON.parse and carry a
|
|
322
|
+
* direct string discriminator. Failed/malformed candidates remain untouched.
|
|
323
|
+
*/
|
|
324
|
+
interface EmbeddedKindJsonRegion {
|
|
325
|
+
start: number;
|
|
326
|
+
end: number;
|
|
327
|
+
content: string;
|
|
328
|
+
kind: string;
|
|
329
|
+
}
|
|
330
|
+
type EmbeddedKindJsonPiece = {
|
|
331
|
+
type: "container";
|
|
332
|
+
content: string;
|
|
333
|
+
} | {
|
|
334
|
+
type: "kind";
|
|
335
|
+
content: string;
|
|
336
|
+
kind: string;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* JSON punctuation that only held kinds together — the `[`, `,` and `]` of
|
|
340
|
+
* an array of kinds. Kept so the partition stays lossless; never rendered
|
|
341
|
+
* (a lone `[` drawn as a JSON card is noise, not content — A6).
|
|
342
|
+
*/
|
|
343
|
+
| {
|
|
344
|
+
type: "chrome";
|
|
345
|
+
content: string;
|
|
346
|
+
}
|
|
347
|
+
/**
|
|
348
|
+
* The non-kind DATA of a JSON wrapper around kinds (`{"result":{…kind…},
|
|
349
|
+
* "note":"x"}`, A7): `content` is the source span it replaces (lossless),
|
|
350
|
+
* `json` is the wrapper's value with every kind removed — valid JSON, drawn
|
|
351
|
+
* as genuine JSON. A wrapper that holds only kinds has no residual piece.
|
|
352
|
+
*/
|
|
353
|
+
| {
|
|
354
|
+
type: "residual";
|
|
355
|
+
content: string;
|
|
356
|
+
json: string;
|
|
357
|
+
};
|
|
358
|
+
/**
|
|
359
|
+
* For every `{` / `[` in `text`: the end (exclusive) of the string-aware
|
|
360
|
+
* balanced JSON value opening there, or -1 (never balances). Each opener's
|
|
361
|
+
* reading starts outside a string, exactly as if read alone; one right-to-left
|
|
362
|
+
* pass reuses each nested opener's own answer (its reading from inside an
|
|
363
|
+
* enclosing value is the same reading), so the whole table is linear — a
|
|
364
|
+
* reading per opener was quadratic on thousands of unclosed `{` (round 11, P5).
|
|
365
|
+
*/
|
|
366
|
+
declare function balancedEnds(text: string): Int32Array;
|
|
367
|
+
|
|
368
|
+
interface EmbeddedKindSearchOptions {
|
|
369
|
+
/** Generic XML: code, comments, CDATA and tags are literal (the XML card shows them). */
|
|
370
|
+
excludeLiteralContexts?: boolean;
|
|
371
|
+
/**
|
|
372
|
+
* With `excludeLiteralContexts` (an XML TAG — structure, ruling (b) round 3):
|
|
373
|
+
* a ```json / ```jsonc / ```json5 / unlabelled fence is NOT literal. A kind
|
|
374
|
+
* that is its whole body leaves with the fence's own lines as chrome, so
|
|
375
|
+
* the XML pieces around it hold no orphan fence marker.
|
|
376
|
+
*/
|
|
377
|
+
liftJsonFences?: boolean;
|
|
378
|
+
/**
|
|
379
|
+
* Markdown: inline code spans and non-JSON fences are the model quoting
|
|
380
|
+
* source (`quotedSourceRanges`, the owner's ruling 2026-09-30) — never lifted.
|
|
381
|
+
*/
|
|
382
|
+
excludeQuotedSource?: boolean;
|
|
383
|
+
}
|
|
384
|
+
declare function findEmbeddedKindJsonRegions(source: string, options?: EmbeddedKindSearchOptions): EmbeddedKindJsonRegion[];
|
|
385
|
+
/** Losslessly partition a container around every recovered kind region. */
|
|
386
|
+
declare function splitAroundEmbeddedKindJson(source: string, options?: EmbeddedKindSearchOptions): EmbeddedKindJsonPiece[];
|
|
387
|
+
/**
|
|
388
|
+
* A recovered PROSE piece, shaped exactly as the live stream shapes the same
|
|
389
|
+
* bytes (A5, 2026-09-30): the stream splits `Here: {"__kind":…} after` into
|
|
390
|
+
* three lines as it arrives, so its prose blocks are trimmed at the end (every
|
|
391
|
+
* text block is) and, after a kind, start where the next character does — the
|
|
392
|
+
* spaces after the object and the one line break that ended its line are the
|
|
393
|
+
* boundary, not content. Both hosts call this on every text piece, so a live
|
|
394
|
+
* message and its reload draw the same blocks.
|
|
395
|
+
*/
|
|
396
|
+
declare function normalizeRecoveredProsePiece(content: string, followsKind: boolean): string;
|
|
397
|
+
/**
|
|
398
|
+
* Every recovered container piece, by its container's block type: prose by
|
|
399
|
+
* the rule above, code byte-verbatim, and a SECTION (`thinking`, `info`, …)
|
|
400
|
+
* trimmed — the live stream splits a kind out of a section as it arrives
|
|
401
|
+
* (A8) and each part is a section body, which is trimmed like a whole one.
|
|
402
|
+
*/
|
|
403
|
+
declare function normalizeRecoveredContainerPiece(content: string, containerType: string, followsKind: boolean): string;
|
|
404
|
+
/**
|
|
405
|
+
* A complete JSON value (object or array) that holds at least one kind, as
|
|
406
|
+
* one region: a recovered kind region widened to the OUTERMOST complete,
|
|
407
|
+
* parseable JSON value that contains it — a kindless wrapper
|
|
408
|
+
* (`{"result":{…kind…},"note":…}`, A7) or an array of kinds and plain values.
|
|
409
|
+
* For DESTINATION transforms (export, copy, speech) that convert the value
|
|
410
|
+
* whole; the renderer partitions the same bytes with
|
|
411
|
+
* {@link splitAroundEmbeddedKindJson}. Built on THE region finder above.
|
|
412
|
+
*/
|
|
413
|
+
interface KindCarryingJsonRegion {
|
|
414
|
+
start: number;
|
|
415
|
+
end: number;
|
|
416
|
+
content: string;
|
|
417
|
+
value: unknown;
|
|
418
|
+
}
|
|
419
|
+
declare function findKindCarryingJsonValues(source: string, options?: {
|
|
420
|
+
excludeLiteralContexts?: boolean;
|
|
421
|
+
}): KindCarryingJsonRegion[];
|
|
422
|
+
/**
|
|
423
|
+
* A kind that can never complete as written: [start, end) and the text of
|
|
424
|
+
* its region. Two shapes, by the same ownership rule as the finder above:
|
|
425
|
+
* - a CLOSED object whose root declares `__kind` but does not parse (the
|
|
426
|
+
* finder's malformed owner) — bounded;
|
|
427
|
+
* - an UNCLOSED JSON object or array at the tail (a stream cut off, a
|
|
428
|
+
* truncated store) holding a `"__kind"` key anywhere — runs to the end,
|
|
429
|
+
* from its outermost opener (a kindless wrapper is cut with its kind).
|
|
430
|
+
* For destinations that must say "<Kind> did not finish" instead of printing
|
|
431
|
+
* the fragment. Complete values (kind or not) are skipped whole.
|
|
432
|
+
*/
|
|
433
|
+
interface BrokenKindJsonRegion {
|
|
434
|
+
start: number;
|
|
435
|
+
end: number;
|
|
436
|
+
content: string;
|
|
437
|
+
}
|
|
438
|
+
/**
|
|
439
|
+
* Round 10 (C1): a broken region is bounded by its OWN JSON grammar. An opener
|
|
440
|
+
* owns a kind key only when its grammar reaches the key; it runs to the end of
|
|
441
|
+
* the text only while it is still validly open, else it ends at its cut. A
|
|
442
|
+
* stray `[[`, `{"`, `{{`, `["`, an unrelated earlier object or a pasted
|
|
443
|
+
* schema never extends a region over the prose after it. A balanced span that
|
|
444
|
+
* does not parse is a region only when it reads once trailing commas go.
|
|
445
|
+
* Linear: key positions once, each opener's grammar stops at its break.
|
|
446
|
+
*/
|
|
447
|
+
declare function findBrokenKindJsonRegions(source: string, options?: {
|
|
448
|
+
excludeLiteralContexts?: boolean;
|
|
449
|
+
}): BrokenKindJsonRegion[];
|
|
450
|
+
|
|
451
|
+
/**
|
|
452
|
+
* Answer TEXT → the readable markdown a person meant, for DISPLAY and EXPORT
|
|
453
|
+
* destinations only (a note, a task, a file, a print, a clipboard copy, the
|
|
454
|
+
* speaker, a plain-text slot). Rule (Arman, 2026-09-30): a kind is never shown
|
|
455
|
+
* as raw JSON — every `{"__kind":…}` region in the text (bare, or the whole
|
|
456
|
+
* body of a ```json / unlabelled fence) becomes that kind's markdown through
|
|
457
|
+
* the ONE kind → markdown converter (`kindValueToMarkdown`: the registry's
|
|
458
|
+
* `toMarkdown` facet, else `genericKindMarkdown`).
|
|
459
|
+
*
|
|
460
|
+
* 🚨 Never call this on data that is STORED or PASSED to a machine: `__kind`
|
|
461
|
+
* is part of the data. This is a destination transform, the same as
|
|
462
|
+
* `unwrapKindEnvelopes`. Kindless text returns byte for byte.
|
|
463
|
+
*
|
|
464
|
+
* Regions come from the one embedded-kind region finder
|
|
465
|
+
* (`findEmbeddedKindJsonRegions`); the signal is the one detector
|
|
466
|
+
* (`hasKindKey`). Nobody writes a second one.
|
|
467
|
+
*/
|
|
468
|
+
/**
|
|
469
|
+
* The one-line broken state of a kind that never completed (≤60 chars) — the
|
|
470
|
+
* SAME words the compact preview shows (`AnswerTextPreview`), so an export of
|
|
471
|
+
* a cut-off answer says what the screen said.
|
|
472
|
+
*/
|
|
473
|
+
declare function unfinishedKindLabel(kind: string | null): string;
|
|
474
|
+
/** The one-line note for structured output whose `__kind` cannot name a kind. */
|
|
475
|
+
declare const UNREADABLE_KIND_NOTE = "Structured output could not be read";
|
|
476
|
+
/**
|
|
477
|
+
* The export transform. Kindless text returns byte for byte; every kind
|
|
478
|
+
* region becomes readable markdown, and a kind that can never complete (cut
|
|
479
|
+
* off, malformed) becomes its one-line "<Kind> did not finish" note — never
|
|
480
|
+
* the fragment.
|
|
481
|
+
*/
|
|
482
|
+
declare function kindTextToMarkdown(raw: string | null | undefined): string;
|
|
483
|
+
interface KindTextPreview {
|
|
484
|
+
/** The readable text: complete kinds as markdown, an arriving kind cut off. */
|
|
485
|
+
text: string;
|
|
486
|
+
/** The slug of a kind still arriving at the end of the text (its loader), else null. */
|
|
487
|
+
pendingKind: string | null;
|
|
488
|
+
/** True when a kind is arriving but its slug has not been read yet. */
|
|
489
|
+
pendingUnnamed: boolean;
|
|
490
|
+
}
|
|
491
|
+
/**
|
|
492
|
+
* A COMPACT, possibly still-streaming preview of answer text (a toast, a
|
|
493
|
+
* hover card, a list row): complete kinds read as their markdown; a kind
|
|
494
|
+
* still arriving is cut from the text and named in `pendingKind` so the
|
|
495
|
+
* caller shows that kind's loader — the raw JSON never shows mid-stream.
|
|
496
|
+
*/
|
|
497
|
+
declare function kindTextPreview(raw: string | null | undefined): KindTextPreview;
|
|
498
|
+
|
|
499
|
+
/**
|
|
500
|
+
* THE ONE-LINE FORM of a kind — what an INLINE surface shows where a kind
|
|
501
|
+
* region sits in its text (P6, round 4): a collapsed card preview, a
|
|
502
|
+
* notification body, an extraction cell, a table cell. An inline/preview level
|
|
503
|
+
* cannot mount a kind component, so a kind reads as its instance title and
|
|
504
|
+
* kind name (`**Cells** · Flashcard Set`), an unfinished one as its kind name
|
|
505
|
+
* alone, and an unreadable one as "Structured output". Never the JSON.
|
|
506
|
+
*
|
|
507
|
+
* LIGHT on purpose — the inline level must not pull the kind registry or the
|
|
508
|
+
* block pipeline: the region finder (`embedded-kind-json.ts`), the detector
|
|
509
|
+
* and the title derivation (`studio/instance-title.ts`) only.
|
|
510
|
+
*/
|
|
511
|
+
/**
|
|
512
|
+
* One line for a kind VALUE: `**Title** · Kind Name`, or the kind name alone.
|
|
513
|
+
* `plain` drops the markdown emphasis (`Title · Kind Name`) for slots that
|
|
514
|
+
* draw text as written — a tooltip, a `title` attribute, a clamped caption.
|
|
515
|
+
*/
|
|
516
|
+
declare function kindOneLine(value: unknown, options?: {
|
|
517
|
+
plain?: boolean;
|
|
518
|
+
}): string;
|
|
519
|
+
/**
|
|
520
|
+
* The text with every kind region (complete, unfinished or unreadable) in
|
|
521
|
+
* prose replaced by its one-line form. Quoted source (inline code, non-JSON
|
|
522
|
+
* fences) stays as written. Text with no kind key comes back unchanged.
|
|
523
|
+
*/
|
|
524
|
+
declare function inlineKindText(raw: string, options?: {
|
|
525
|
+
plain?: boolean;
|
|
526
|
+
}): string;
|
|
527
|
+
/**
|
|
528
|
+
* A complete JSON kind region whose `__kind` cannot name a kind (`{"__kind":
|
|
529
|
+
* ["x"], …}`, `{"__kind": 5}`) → the one-line unreadable note, the words the
|
|
530
|
+
* export writes (`UNREADABLE_KIND_NOTE`), instead of raw JSON (round 11, L2).
|
|
531
|
+
*/
|
|
532
|
+
declare function unreadableKindsAsNote(text: string): string;
|
|
533
|
+
/**
|
|
534
|
+
* CATALOG PROSE as a person reads it (ruling (a), round 6): a skill / agent /
|
|
535
|
+
* tool description that shows an example kind JSON (`emit a
|
|
536
|
+
* {"__kind": "math_problem"} block`) is documentation — the example reads as
|
|
537
|
+
* its kind's one-line label, never the JSON. Plain text out, for text AND
|
|
538
|
+
* attribute slots (`title`, tooltips). Display transform only: the stored
|
|
539
|
+
* description is never rewritten.
|
|
540
|
+
*/
|
|
541
|
+
declare function catalogProseText(text: string | null | undefined): string;
|
|
542
|
+
/**
|
|
543
|
+
* THE PROSE LEAF's kind reading (round 10 boundary): a REAL JSON kind region
|
|
544
|
+
* the pipeline cannot lift — a settled object whose grammar BROKE in prose
|
|
545
|
+
* (`{"__kind":"note","title":"Hi" and then…`), or a markdown-escaped key
|
|
546
|
+
* (`"\_\_kind"`) — reads as its one-line label, then every character after
|
|
547
|
+
* its cut as written. A complete literal kind is the pipeline's (lifted).
|
|
548
|
+
* Every NON-JSON spelling (`{\"__kind\":…}` in prose, repr, a JS literal,
|
|
549
|
+
* typographic quotes, entities) is left EXACTLY as written — detection only.
|
|
550
|
+
* Called by the one prose leaf live and reloaded text both pass through, so
|
|
551
|
+
* live ≡ reload. One linear pass, memoized per text; text with no such region
|
|
552
|
+
* comes back as the same string.
|
|
553
|
+
*/
|
|
554
|
+
declare function spelledKindsAsOneLine(text: string): string;
|
|
555
|
+
/**
|
|
556
|
+
* Round 10, detection-only spellings drawn EXACTLY as written: a non-JSON
|
|
557
|
+
* kind spelling in prose (`{\"__kind\":…}`, repr, a JS literal, typographic
|
|
558
|
+
* quotes, entities) becomes an inline code span, so markdown neither eats its
|
|
559
|
+
* backslashes nor decodes its entities — the screen shows the source byte for
|
|
560
|
+
* byte, as quoted source. Nothing outside a region changes; text with no such
|
|
561
|
+
* region comes back as the same string. One linear pass, memoized per text.
|
|
562
|
+
* (A markdown-escaping pass did the same job and hung the renderer on nested
|
|
563
|
+
* escapes — never reintroduce it.)
|
|
564
|
+
*/
|
|
565
|
+
declare function nonJsonKindsAsCode(text: string): string;
|
|
566
|
+
|
|
567
|
+
/**
|
|
568
|
+
* A JSON REGION INSIDE A BLOCKQUOTE leaves the quote (V1, the never-raw law).
|
|
569
|
+
*
|
|
570
|
+
* A model sometimes quotes its whole answer — `> ```json` / `> {"__kind":…}` —
|
|
571
|
+
* and every line then starts with `>`. Neither host could see the region: the
|
|
572
|
+
* live accumulator classifies a `>` line as prose, the static splitter keeps
|
|
573
|
+
* the quote as one text block, so the kind was drawn as raw JSON inside a
|
|
574
|
+
* blockquote in chat, on reload, on public shared pages and in tool results.
|
|
575
|
+
*
|
|
576
|
+
* THE RULE: a blockquote holds prose, never a data region. A JSON-family
|
|
577
|
+
* fence (```json / ```jsonc / ```json5 / unlabelled, any case, ``` or ~~~)
|
|
578
|
+
* opening on a quoted line, or a quoted line whose JSON could be a kind (the
|
|
579
|
+
* first-key rule, `jsonKindSignal`), is LIFTED: its quote prefix is removed
|
|
580
|
+
* from every line of the region, so the region becomes an ordinary top-level
|
|
581
|
+
* fence / bare JSON object between two quotes. The quote before it renders as
|
|
582
|
+
* a quote, the region as its kind, the quote after it as a new quote. Quoted
|
|
583
|
+
* text that is not a JSON region is never touched — and a fence of another
|
|
584
|
+
* language (```ts, ```xml, ```markdown, quoted or not) is the model quoting
|
|
585
|
+
* SOURCE, so nothing inside it is lifted (the owner's ruling, 2026-09-30).
|
|
586
|
+
*
|
|
587
|
+
* ONE transform, both hosts: the live accumulator pushes every delta through
|
|
588
|
+
* a `QuotedKindLift` before its line machine; the static splitter runs
|
|
589
|
+
* `liftQuotedKindRegions` on the whole text first. The transform is
|
|
590
|
+
* chunk-invariant (decisions are taken only at points every chunking reaches
|
|
591
|
+
* with the same bytes), so live = reload byte for byte.
|
|
592
|
+
*/
|
|
593
|
+
/**
|
|
594
|
+
* The streaming lift. `push` returns the bytes that are safe to hand on now;
|
|
595
|
+
* a line whose fate is not known yet (a quoted line that may open a JSON
|
|
596
|
+
* region) is held — never shown raw — until it is. `flush` releases what is
|
|
597
|
+
* held, as written, at the end of the stream (or a hard boundary).
|
|
598
|
+
*/
|
|
599
|
+
declare class QuotedKindLift {
|
|
600
|
+
private mode;
|
|
601
|
+
/** The current line's bytes not yet handed on (held while undecided). */
|
|
602
|
+
private held;
|
|
603
|
+
/** The current line's bytes so far (handed on or not), as received. */
|
|
604
|
+
private line;
|
|
605
|
+
/** Whether the rest of the current line passes straight through. */
|
|
606
|
+
private passing;
|
|
607
|
+
/** Prefix stripped from the current line's handed-on bytes (passing lines). */
|
|
608
|
+
private stripping;
|
|
609
|
+
push(text: string): string;
|
|
610
|
+
flush(): string;
|
|
611
|
+
private pushChar;
|
|
612
|
+
/** Try to decide the current line before it ends; returns bytes released. */
|
|
613
|
+
private decideMidLine;
|
|
614
|
+
/** Hand on `bytes` and let the rest of the line pass straight through. */
|
|
615
|
+
private release;
|
|
616
|
+
private endLine;
|
|
617
|
+
/**
|
|
618
|
+
* A complete line met with no region open. `held` is what was not handed
|
|
619
|
+
* on yet: the whole line when it was held to the end, otherwise "" (it was
|
|
620
|
+
* released mid-line as prose or as an unquoted line).
|
|
621
|
+
*/
|
|
622
|
+
private lineFromNone;
|
|
623
|
+
/** A held quoted JSON start, re-judged after each complete line. */
|
|
624
|
+
private settleCandidate;
|
|
625
|
+
}
|
|
626
|
+
/** The whole-text form, for the static splitter (identical bytes to any streaming of `source`). */
|
|
627
|
+
declare function liftQuotedKindRegions(source: string): string;
|
|
628
|
+
|
|
629
|
+
/**
|
|
630
|
+
* THE MARKDOWN-ESCAPED KIND (P8, round 4). A model that escapes markdown in
|
|
631
|
+
* its whole answer writes `{"\_\_kind":"flashcard\_set",…}`. No JSON reader
|
|
632
|
+
* sees a kind there (`\_` is not even a JSON escape), but the markdown
|
|
633
|
+
* renderer un-escapes it, so the reader saw `{"__kind":…}` drawn raw.
|
|
634
|
+
*
|
|
635
|
+
* THE RULE: the key `"\_\_kind"` IS the key `"__kind"` (the detector reads it
|
|
636
|
+
* in text contexts, `hasKindKey(…, { markdown: true })`), and inside the JSON
|
|
637
|
+
* object that holds it every `\_` is `_`. ONE transform, both hosts: the live
|
|
638
|
+
* accumulator pushes every delta through a `MarkdownEscapedKindJson` before
|
|
639
|
+
* its line machine; the static splitter runs `unescapeMarkdownKindJson` on the
|
|
640
|
+
* whole text first. Character-driven and chunk-invariant, so live = reload.
|
|
641
|
+
*
|
|
642
|
+
* Also here (decided, round 4): a DOUBLE-ENCODED kind — the whole answer is a
|
|
643
|
+
* JSON string literal whose value is kind JSON (`"{\"__kind\":…}"`) — reads as
|
|
644
|
+
* that kind (`decodeDoubleEncodedKindText`, whole text, settled readers only).
|
|
645
|
+
*/
|
|
646
|
+
/**
|
|
647
|
+
* A ZERO-WIDTH character inside the key (`"__\u200Bkind"`, round 8): the
|
|
648
|
+
* screen reads `"__kind"`, so the key is rewritten as `"__kind"` before
|
|
649
|
+
* anything else reads the text, and the normal kind route (fence, standalone,
|
|
650
|
+
* prose) takes it. Only a complete key is rewritten — a zero-width character
|
|
651
|
+
* anywhere else stays. Character-driven and chunk-invariant (live = reload).
|
|
652
|
+
*/
|
|
653
|
+
declare class ZeroWidthKindKey {
|
|
654
|
+
/** Bytes that may still become the key — held, never shown. */
|
|
655
|
+
private pending;
|
|
656
|
+
push(text: string): string;
|
|
657
|
+
flush(): string;
|
|
658
|
+
private pushChar;
|
|
659
|
+
}
|
|
660
|
+
declare class MarkdownEscapedKindJson {
|
|
661
|
+
/** The zero-width key spelling is read first (round 8) — one transform, both hosts. */
|
|
662
|
+
private zeroWidth;
|
|
663
|
+
/** Bytes that may still become the escaped key — held, never shown. */
|
|
664
|
+
private pending;
|
|
665
|
+
/** Inside the object holding a rewritten key: bracket depth (0 = outside). */
|
|
666
|
+
private depth;
|
|
667
|
+
private inString;
|
|
668
|
+
/** A held backslash inside the object (its fate depends on the next char). */
|
|
669
|
+
private escape;
|
|
670
|
+
push(text: string): string;
|
|
671
|
+
private pushUnescape;
|
|
672
|
+
flush(): string;
|
|
673
|
+
private pushChar;
|
|
674
|
+
private insideObject;
|
|
675
|
+
}
|
|
676
|
+
/** The whole-text form, for the static splitter (identical bytes to any streaming of `source`). */
|
|
677
|
+
declare function unescapeMarkdownKindJson(source: string): string;
|
|
678
|
+
/**
|
|
679
|
+
* A whole answer that is a JSON STRING literal holding kind JSON → that kind
|
|
680
|
+
* JSON; anything else unchanged.
|
|
681
|
+
*/
|
|
682
|
+
declare function decodeDoubleEncodedKindText(source: string): string;
|
|
683
|
+
|
|
684
|
+
/**
|
|
685
|
+
* A KIND AS AN IMAGE'S ALT TEXT (P9, round 4): ``. The
|
|
686
|
+
* prose split lifted the object out and left `!` and `(url)` behind as two
|
|
687
|
+
* stray prose blocks after reload (and live). The model meant the kind: the
|
|
688
|
+
* image wrapper is chrome — `` after it are
|
|
689
|
+
* dropped, the object stays where it was and renders as its kind. A kindless
|
|
690
|
+
* object in alt text (first key decided not `__kind`) is left as written.
|
|
691
|
+
*
|
|
692
|
+
* ONE transform, both hosts (like `quoted-kind-lift.ts`): the live accumulator
|
|
693
|
+
* pushes every delta through a `KindImageAltUnwrap`; the static splitter runs
|
|
694
|
+
* `unwrapKindImageAlt` on the whole text. Character-driven and chunk-invariant.
|
|
695
|
+
*/
|
|
696
|
+
declare class KindImageAltUnwrap {
|
|
697
|
+
private mode;
|
|
698
|
+
/** Held: `!` / `. */
|
|
699
|
+
private held;
|
|
700
|
+
private depth;
|
|
701
|
+
private inString;
|
|
702
|
+
private escape;
|
|
703
|
+
push(text: string): string;
|
|
704
|
+
flush(): string;
|
|
705
|
+
/** Track JSON structure; returns true when the object just closed. */
|
|
706
|
+
private track;
|
|
707
|
+
private pushChar;
|
|
708
|
+
}
|
|
709
|
+
/** The whole-text form, for the static splitter (identical bytes to any streaming of `source`). */
|
|
710
|
+
declare function unwrapKindImageAlt(source: string): string;
|
|
711
|
+
|
|
712
|
+
/**
|
|
713
|
+
* Answer TEXT → ONE readable line, for a person's compact label (a card
|
|
714
|
+
* subtitle, a rule name, a link-preview description, a list row). A kind is
|
|
715
|
+
* never shown as raw JSON (Arman, 2026-09-30): a kind answer reads as
|
|
716
|
+
* "<Kind> · <instance title>" (`deriveInstanceTitle`, the derivation saved
|
|
717
|
+
* instances use); prose with a kind in it reads as the prose's first line;
|
|
718
|
+
* a kind that never completed reads as its one-line broken note.
|
|
719
|
+
* Kindless text is whitespace-collapsed and clipped, nothing else.
|
|
720
|
+
*
|
|
721
|
+
* Destination transform only — never call it on stored or machine-bound text.
|
|
722
|
+
*/
|
|
723
|
+
/** One line, at most `max` characters, never containing a `__kind` key. */
|
|
724
|
+
declare function kindTextLabel(raw: string | null | undefined, max?: number): string;
|
|
725
|
+
/**
|
|
726
|
+
* A conversation TITLE as a person reads it (R4, round 6): a title that holds
|
|
727
|
+
* kind JSON reads as its one-line kind label; any other title — and null —
|
|
728
|
+
* comes back as it is. Read boundaries and title renderers call this; the
|
|
729
|
+
* stored title is never rewritten.
|
|
730
|
+
*/
|
|
731
|
+
declare function conversationTitleText(title: string | null | undefined): string | null;
|
|
732
|
+
|
|
733
|
+
/**
|
|
734
|
+
* Shared plumbing for kind → markdown export facets (`toMarkdown`).
|
|
735
|
+
*
|
|
736
|
+
* The FORWARD leg of the artifact ⇄ markdown two-way layer: every facet
|
|
737
|
+
* turns a kind's ZERO-LOSS value object into clean human-readable markdown
|
|
738
|
+
* (headings / lists / bold — never a JSON dump), following two laws:
|
|
739
|
+
*
|
|
740
|
+
* 1. `__kind` discriminators are transport metadata — never rendered.
|
|
741
|
+
* 2. Nothing silently vanishes: keys a facet doesn't understand (plus the
|
|
742
|
+
* declared `additionalDetails` bag every top-level kind schema carries)
|
|
743
|
+
* are appended under a small "Additional details" key: value section via
|
|
744
|
+
* `collectExtras` + `additionalDetailsSection`.
|
|
745
|
+
*
|
|
746
|
+
* `genericKindMarkdown` is the fallback for kinds WITHOUT a `toMarkdown`
|
|
747
|
+
* facet (and for unregistered kinds): readable markdown built from the value
|
|
748
|
+
* itself — headings, bold-label lists, tables — never a JSON dump.
|
|
749
|
+
*/
|
|
750
|
+
declare function isRecordValue(value: unknown): value is Record<string, unknown>;
|
|
751
|
+
/**
|
|
752
|
+
* One-line rendering of an arbitrary value for key: value lists. Scalars
|
|
753
|
+
* render as text, scalar arrays join with ", ", anything structural falls
|
|
754
|
+
* back to inline JSON in a code span (zero loss, still one line).
|
|
755
|
+
*/
|
|
756
|
+
declare function formatInlineValue(value: unknown): string;
|
|
757
|
+
/**
|
|
758
|
+
* Collect the keys a facet does NOT understand. Skips `__kind`,
|
|
759
|
+
* null/undefined, and the facet's known keys; merges the contents of a
|
|
760
|
+
* declared `additionalDetails` object bag (the schema-blessed extras
|
|
761
|
+
* channel) into the same flat map so both extra channels surface together.
|
|
762
|
+
*/
|
|
763
|
+
declare function collectExtras(value: Record<string, unknown>, knownKeys: Iterable<string>): Record<string, unknown>;
|
|
764
|
+
/**
|
|
765
|
+
* A field's own name, as words — `violations_not_fixed` → "Violations not
|
|
766
|
+
* fixed", `wordCountAfter` → "Word count after".
|
|
767
|
+
*
|
|
768
|
+
* 🚨 WALK 18, DEFECT D. The finished Masterwork deliverable an Expert hands a
|
|
769
|
+
* customer carried `violations_not_fixed: []` — a key out of a schema we
|
|
770
|
+
* declared, printed at a person. A label is the one place a field name is
|
|
771
|
+
* GUARANTEED to reach a reader, so the resolution lives here, beside the
|
|
772
|
+
* extras plumbing, for every RENDERER that puts a structured field on a
|
|
773
|
+
* screen: underscores and camel humps become spaces, the first letter is
|
|
774
|
+
* capitalised, and nothing else changes.
|
|
775
|
+
*
|
|
776
|
+
* Deliberately NOT applied inside {@link extrasList}. That list is the
|
|
777
|
+
* markdown/EXPORT leg (`features/canvas/export/exportArtifactMarkdown.ts`
|
|
778
|
+
* writes a file somebody — or something — reads back), and a key spelled as
|
|
779
|
+
* prose cannot be read back as a key. A screen resolves; a file keeps the key.
|
|
780
|
+
*/
|
|
781
|
+
declare function plainFieldLabel(key: string): string;
|
|
782
|
+
/** Render extras as a key: value bullet list (no heading). Null when empty. */
|
|
783
|
+
declare function extrasList(extras: Record<string, unknown>): string | null;
|
|
784
|
+
/**
|
|
785
|
+
* The canonical "Additional details" section — appended at the END of a
|
|
786
|
+
* kind's markdown so nothing silently vanishes. Null when there is nothing
|
|
787
|
+
* to say (callers filter with `joinBlocks`).
|
|
788
|
+
*/
|
|
789
|
+
declare function additionalDetailsSection(extras: Record<string, unknown>, headingLevel?: "##" | "###" | "####"): string | null;
|
|
790
|
+
/** Join markdown blocks with blank lines, dropping empty/null ones. */
|
|
791
|
+
declare function joinBlocks(blocks: Array<string | null | undefined>): string;
|
|
792
|
+
/** "flashcard_set" → "Flashcard Set"; "Artifact" when there is nothing to say. */
|
|
793
|
+
declare function humanizeKind(kind: string): string;
|
|
794
|
+
/** Renders a nested kind value as markdown (the registry's converter). */
|
|
795
|
+
type NestedKindMarkdown = (value: Record<string, unknown>) => string;
|
|
796
|
+
/**
|
|
797
|
+
* Fallback markdown for kinds with no `toMarkdown` facet (or unregistered
|
|
798
|
+
* kinds): READABLE markdown built from the value itself (kind-never-raw,
|
|
799
|
+
* Arman 2026-09-30 — a kind is never shown as raw JSON, an export included).
|
|
800
|
+
* Heading = the instance title (`deriveInstanceTitle`), then the kind's
|
|
801
|
+
* name; scalar fields as a bold-label list; arrays of uniform scalar records
|
|
802
|
+
* as a table, other arrays as nested lists; nested plain objects as
|
|
803
|
+
* sections; nested KINDS through `nested` (the registry converter —
|
|
804
|
+
* `kindValueToMarkdown` passes itself; default: this function). Never the
|
|
805
|
+
* `__kind` key, never a JSON fence. Every field still appears (zero loss in
|
|
806
|
+
* content; the discriminator is named in words by the subtitle).
|
|
807
|
+
*/
|
|
808
|
+
declare function genericKindMarkdown(kind: string, value: Record<string, unknown>, nested?: NestedKindMarkdown): string;
|
|
809
|
+
/**
|
|
810
|
+
* Readable markdown for a value that is NOT itself a kind — a kindless JSON
|
|
811
|
+
* wrapper around kinds, or a run of plain values beside kinds in an array —
|
|
812
|
+
* so a destination (export, copy) never prints it as JSON. Same rendering as
|
|
813
|
+
* a kind's body in {@link genericKindMarkdown} (bold-label scalars, tables for
|
|
814
|
+
* uniform records, nested lists, sections), nested kinds through `nested`.
|
|
815
|
+
*/
|
|
816
|
+
declare function plainValueMarkdown(value: unknown, nested?: NestedKindMarkdown): string;
|
|
817
|
+
|
|
818
|
+
type KindValueToMarkdown = (value: Record<string, unknown>, fallbackKind?: string) => string;
|
|
819
|
+
/** The host's registry-backed converter (matrx-frontend: `features/canvas/export/exportArtifactMarkdown`). */
|
|
820
|
+
declare function registerKindValueMarkdown(impl: KindValueToMarkdown | null): void;
|
|
821
|
+
declare function kindValueToMarkdown(value: Record<string, unknown>, fallbackKind?: string): string;
|
|
822
|
+
|
|
823
|
+
/**
|
|
824
|
+
* Instance TITLE derivation — pure, importable from server and client code
|
|
825
|
+
* (no supabase import; `instance-service.ts` consumes it on the write path).
|
|
826
|
+
*
|
|
827
|
+
* CROSS-REPO MIRROR: aidream `kind_instance.py` (`_TITLE_KEYS` +
|
|
828
|
+
* `derive_title` + `kind_shared.kind_title_key`) implements the SAME
|
|
829
|
+
* derivation order — explicit title → the kind's `metadata.title_key` field
|
|
830
|
+
* (per-kind override, non-empty scalar) → the shared key list → null.
|
|
831
|
+
* Change BOTH sides together.
|
|
832
|
+
*/
|
|
833
|
+
/** Mirrors aidream `kind_instance._TITLE_KEYS` — keep the two in lockstep. */
|
|
834
|
+
declare const INSTANCE_TITLE_KEYS: readonly ["title", "name", "label", "heading", "subject", "customer"];
|
|
835
|
+
/**
|
|
836
|
+
* The kind's per-kind instance-title override —
|
|
837
|
+
* `kind_definition.metadata.title_key` (a single data key naming the title
|
|
838
|
+
* field, e.g. `wine_name`). Set by the creator agent via `kind_create`;
|
|
839
|
+
* null when absent/blank/non-string. Server parity: `kind_shared.kind_title_key`.
|
|
840
|
+
*/
|
|
841
|
+
declare function kindTitleKeyFromMetadata(metadata: unknown): string | null;
|
|
842
|
+
/**
|
|
843
|
+
* Explicit title wins; else the kind's `metadata.title_key` field when it
|
|
844
|
+
* holds a non-empty scalar; else the first non-empty string under a shared
|
|
845
|
+
* title/name-ish key. The ORDER is a cross-repo contract — mirrored verbatim
|
|
846
|
+
* by aidream `kind_instance.derive_title`.
|
|
847
|
+
*/
|
|
848
|
+
declare function deriveInstanceTitle(data: Record<string, unknown>, explicit?: string | null, titleKey?: string | null): string | null;
|
|
849
|
+
|
|
850
|
+
/** Mirror the server's legacy quiz adapter while keeping source aliases in IR residue. */
|
|
851
|
+
declare function canonicalizeCompletedLegacyQuizEnvelope(envelope: CanonicalBlockIR, sourceText: string): CanonicalBlockIR;
|
|
852
|
+
|
|
853
|
+
/**
|
|
854
|
+
* Pure envelope helpers the chat package needs (chat-package-move P14): the Phase-2 shadow
|
|
855
|
+
* parity check ("does the envelope, reconstructed, deep-equal what JSON.parse sees?").
|
|
856
|
+
*
|
|
857
|
+
* A COMPARISON, NEVER A TRANSFORM — the one lawful shape of `stripKindDeep` outside the two doors.
|
|
858
|
+
* Markers are removed from BOTH sides, symmetrically, inside this predicate, so a marker the parser
|
|
859
|
+
* INJECTED (speculation / expectedRootKind) is not reported as a mismatch against a source that did
|
|
860
|
+
* not carry one. Only a boolean leaves; neither input is mutated and neither reduced value is ever
|
|
861
|
+
* returned, stored, or rendered (KINDS_EVERYWHERE_PLAN §4.2).
|
|
862
|
+
*/
|
|
863
|
+
|
|
864
|
+
declare function envelopeMatchesParsedSource(envelope: CanonicalBlockIR, parsedSource: unknown): boolean;
|
|
865
|
+
|
|
866
|
+
/** The decision-answers block's stable wire ids (render-block type and kind slug). */
|
|
867
|
+
declare const DECISION_ANSWERS_KIND = "decision_answers";
|
|
868
|
+
declare const DECISION_ANSWERS_BLOCK_TYPE = "decision_answers";
|
|
869
|
+
|
|
870
|
+
export { ALL_KIND_SPELLINGS, BARE_REGION_GRAMMAR_BUDGET, type BrokenKindJsonRegion, DECISION_ANSWERS_BLOCK_TYPE, DECISION_ANSWERS_KIND, type EmbeddedKindJsonPiece, type EmbeddedKindJsonRegion, type EmbeddedKindSearchOptions, type GrammarDialect, INSTANCE_TITLE_KEYS, JSON_KIND_SPELLINGS, type JsonKindSignal, type KindCarryingJsonRegion, type KindGrammarVerdict, KindImageAltUnwrap, type KindSpellingFamily, type KindSpellingRegion, type KindTextOptions, type KindTextPreview, type KindValueToMarkdown, MarkdownEscapedKindJson, type NestedKindMarkdown, QuotedKindLift, UNREADABLE_KIND_NOTE, ZeroWidthKindKey, additionalDetailsSection, balancedEnds, bareRegionBreaksIntoProse, canonicalizeCompletedLegacyQuizEnvelope, catalogProseText, closedJson, collectExtras, conversationTitleText, decodeDoubleEncodedKindText, deriveInstanceTitle, endsInPartialKindKey, envelopeMatchesParsedSource, extrasList, findBrokenKindJsonRegions, findEmbeddedKindJsonRegions, findKindCarryingJsonValues, firstKindSlug, formatInlineValue, frontMatterEnd, genericKindMarkdown, hasDetectionOnlyKindKey, hasExoticKindKey, hasJsonKindKey, hasKindKey, hasKindKeyAnySpelling, hasPythonKindKey, humanizeKind, inlineKindText, isJson5Language, isJsonFenceLanguage, isKindJsonText, isKindSlug, isQuotedSourceXmlBlock, isRecordValue, joinBlocks, json5AsJson, jsonKindSignal, kindGrammar, kindObjectProseBreak, kindOneLine, kindTextLabel, kindTextPreview, kindTextToMarkdown, kindTitleKeyFromMetadata, kindValueToMarkdown, liftQuotedKindRegions, markdownCarriesKind, mayHoldKindKey, nonJsonKindsAsCode, normalizeKindSpellings, normalizeRecoveredContainerPiece, normalizeRecoveredProsePiece, plainFieldLabel, plainValueMarkdown, pythonBalancedEnd, pythonReprAsJson, quotedSourceRanges, regionJson, registerKindValueMarkdown, rootKindSlug, scanKindSpellingRegions, spelledKindsAsOneLine, splitAroundEmbeddedKindJson, textCarriesKind, unescapeMarkdownKindJson, unfinishedKindLabel, unreadableKindsAsNote, unwrapKindImageAlt, valueCarriesKind, withoutLeadingJsonComments, withoutZeroWidth };
|