@ai-matrx/content-ir 0.8.0 → 0.10.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.
Files changed (45) hide show
  1. package/CHANGELOG.md +79 -0
  2. package/README.md +24 -5
  3. package/dist/convert.cjs +1680 -0
  4. package/dist/convert.cjs.map +1 -0
  5. package/dist/convert.d.cts +230 -0
  6. package/dist/convert.d.ts +230 -0
  7. package/dist/convert.js +1666 -0
  8. package/dist/convert.js.map +1 -0
  9. package/dist/core.cjs +2493 -0
  10. package/dist/core.cjs.map +1 -0
  11. package/dist/core.d.cts +370 -0
  12. package/dist/core.d.ts +370 -0
  13. package/dist/core.js +2452 -0
  14. package/dist/core.js.map +1 -0
  15. package/dist/index.cjs +11 -1
  16. package/dist/index.cjs.map +1 -1
  17. package/dist/index.d.cts +9 -2030
  18. package/dist/index.d.ts +9 -2030
  19. package/dist/index.js +11 -1
  20. package/dist/index.js.map +1 -1
  21. package/dist/ir-tree-DbLVxbf1.d.cts +441 -0
  22. package/dist/ir-tree-Dsc_66ek.d.ts +441 -0
  23. package/dist/ir-types-95bA2cXH.d.cts +119 -0
  24. package/dist/ir-types-95bA2cXH.d.ts +119 -0
  25. package/dist/kind-schema.types-CwncWj9U.d.cts +139 -0
  26. package/dist/kind-schema.types-CwncWj9U.d.ts +139 -0
  27. package/dist/registry.cjs +468 -0
  28. package/dist/registry.cjs.map +1 -0
  29. package/dist/registry.d.cts +357 -0
  30. package/dist/registry.d.ts +357 -0
  31. package/dist/registry.js +456 -0
  32. package/dist/registry.js.map +1 -0
  33. package/dist/session.cjs +2052 -0
  34. package/dist/session.cjs.map +1 -0
  35. package/dist/session.d.cts +75 -0
  36. package/dist/session.d.ts +75 -0
  37. package/dist/session.js +2047 -0
  38. package/dist/session.js.map +1 -0
  39. package/dist/wire.cjs +310 -0
  40. package/dist/wire.cjs.map +1 -0
  41. package/dist/wire.d.cts +326 -0
  42. package/dist/wire.d.ts +326 -0
  43. package/dist/wire.js +291 -0
  44. package/dist/wire.js.map +1 -0
  45. package/package.json +73 -1
@@ -0,0 +1,441 @@
1
+ import { f as IrPath, g as IrResidue, e as IrKindState, C as CanonicalBlockIR } from './ir-types-95bA2cXH.cjs';
2
+ import { a as KindSchema } from './kind-schema.types-CwncWj9U.cjs';
3
+
4
+ /**
5
+ * KindStreamParser — the streaming, schema-validating, __kind-discriminated
6
+ * JSON parser at the heart of content-ir.
7
+ *
8
+ * Frame-stack pushdown parser over JsonStreamTokenizer tokens. Every value is
9
+ * path-addressed; every object resolves a kind against the schema registry;
10
+ * schema-shaped `block_snapshot` events fire on field arrival so renderers
11
+ * get live partials; unknown/invalid structures degrade to `raw_object`
12
+ * instead of failing the stream.
13
+ *
14
+ * The pushdown discipline (commit → descend → never re-ask → backtrack):
15
+ * - SPECULATIVE DESCENT: when a parent field schema predicts a child's kind
16
+ * ({type:"object", kind} or {type:"array", itemKinds:[K]} with one member),
17
+ * the child commits to that kind THE INSTANT `{` opens and renders a
18
+ * placeholder snapshot. `__kind` arrival confirms (no-op), re-tags (allowed
19
+ * sibling kind), or backtracks to raw (contradiction). An object under a
20
+ * predicting parent doesn't even need `__kind` — prediction alone types it.
21
+ * - PENDING SCHEMA: an identified kind whose schema isn't loaded holds the
22
+ * node open (`pending_schema` event, fields keep accumulating), fires the
23
+ * resolver's cold fetch, and upgrades in place via `notifySchemaArrived` —
24
+ * even after the node (or the whole region) has closed.
25
+ * - POP-UP-ONE-LEVEL: node-scoped problems (duplicate key, schema violation,
26
+ * disallowed itemKind) mark THAT node raw and keep parsing the parent.
27
+ * Only grammar/tokenizer errors are region-fatal — and the host degrades
28
+ * the region to a plain code block, never the stream.
29
+ */
30
+
31
+ /** Kept as the historical name for the parser's event paths. */
32
+ type JsonPath = IrPath;
33
+ /**
34
+ * Schema source abstraction. A plain Record works for static sets; the
35
+ * registry supplies a resolver whose `request` fires a cold fetch and later
36
+ * calls `parser.notifySchemaArrived`.
37
+ */
38
+ interface SchemaResolver {
39
+ get(kind: string): KindSchema | undefined;
40
+ /** Fire-and-forget cold fetch. Absent = static source, unknown kinds go raw. */
41
+ request?(kind: string): void;
42
+ /**
43
+ * Optional per-resolver override for legacy root-key recognition. Most hosts
44
+ * leave this unset and register the lookup once via
45
+ * `setJsonRootKeyLookup` — see that function for why.
46
+ */
47
+ kindForJsonRootKey?(key: string): string | null;
48
+ }
49
+ declare function setJsonRootKeyLookup(lookup: ((key: string) => string | null) | null): void;
50
+ /**
51
+ * Why a node degraded off the `resolved` path.
52
+ *
53
+ * `"unverified"` is reserved for ONE situation: no schema was registered for
54
+ * an identified kind, so no check ever ran. Every other degrade — a schema
55
+ * violation, an array-item kind mismatch, a duplicate key, a bad field
56
+ * placement, a contradicted speculation — is `"invalid"`: something checked
57
+ * the node and it failed.
58
+ */
59
+ type RawObjectCause = "unverified" | "invalid";
60
+ type KindStreamEvent = {
61
+ type: "kind_identified";
62
+ kind: string;
63
+ path: JsonPath;
64
+ /** True when committed from the parent schema before __kind arrived. */
65
+ speculative?: boolean;
66
+ at: number;
67
+ } | {
68
+ type: "pending_kind";
69
+ path: JsonPath;
70
+ at: number;
71
+ } | {
72
+ type: "kind_wait_end";
73
+ path: JsonPath;
74
+ outcome: "identified" | "raw_fallback";
75
+ kind?: string;
76
+ reason?: string;
77
+ at: number;
78
+ } | {
79
+ type: "pending_schema";
80
+ kind: string;
81
+ path: JsonPath;
82
+ at: number;
83
+ } | {
84
+ type: "field";
85
+ kind: string;
86
+ path: JsonPath;
87
+ key: string;
88
+ value: unknown;
89
+ at: number;
90
+ } | {
91
+ type: "object_start";
92
+ path: JsonPath;
93
+ at: number;
94
+ } | {
95
+ type: "object_complete";
96
+ kind: string;
97
+ path: JsonPath;
98
+ value: Record<string, unknown>;
99
+ at: number;
100
+ } | {
101
+ type: "raw_object";
102
+ path: JsonPath;
103
+ value: unknown;
104
+ reason: string;
105
+ /**
106
+ * The kind that WAS identified for this node before it degraded — set
107
+ * for schema-availability degrades AND (since 2026-08-29) structural
108
+ * ones, so a payload that said what it is stays acknowledged as an
109
+ * instance of that kind. Absent only when nothing ever identified it
110
+ * (an object with no `__kind` at all).
111
+ */
112
+ kind?: string;
113
+ /**
114
+ * WHY this node is not `resolved` — the discriminator the render route
115
+ * reads. See `IrKindState` for why collapsing these two is an outage.
116
+ *
117
+ * - `"unverified"`: no schema was available, so nothing was checked.
118
+ * The value is intact and may be perfectly valid.
119
+ * - `"invalid"` (default): a check RAN and the node failed it, or the
120
+ * node is structurally broken (duplicate key, bad placement).
121
+ */
122
+ cause?: RawObjectCause;
123
+ at: number;
124
+ } | {
125
+ type: "optional_field_missing";
126
+ kind: string;
127
+ path: JsonPath;
128
+ field: string;
129
+ at: number;
130
+ } | {
131
+ type: "extra_field";
132
+ kind: string;
133
+ path: JsonPath;
134
+ field: string;
135
+ at: number;
136
+ } | {
137
+ type: "block_snapshot";
138
+ kind: string;
139
+ path: JsonPath;
140
+ value: Record<string, unknown>;
141
+ residue: IrResidue | null;
142
+ complete: boolean;
143
+ at: number;
144
+ } | {
145
+ type: "array_start";
146
+ path: JsonPath;
147
+ field: string;
148
+ at: number;
149
+ } | {
150
+ type: "complete";
151
+ kind: string;
152
+ value: unknown;
153
+ at: number;
154
+ } | {
155
+ type: "error";
156
+ reason: string;
157
+ at: number;
158
+ };
159
+ type KindStreamParserOptions = {
160
+ onEvent: (event: KindStreamEvent) => void;
161
+ schemas: Record<string, KindSchema> | SchemaResolver;
162
+ /**
163
+ * Known-context root prediction (e.g. "this agent's output schema is
164
+ * flashcard_set"). The root commits speculatively at `{` open — the Option-1
165
+ * provenance path for agents whose schemas don't carry __kind yet.
166
+ */
167
+ expectedRootKind?: string;
168
+ };
169
+ declare class KindStreamParser {
170
+ private readonly resolver;
171
+ private readonly stack;
172
+ private readonly objectKinds;
173
+ private readonly inlineSchemas;
174
+ private readonly recordSchemas;
175
+ private readonly rawObjectPaths;
176
+ /**
177
+ * Subtrees whose value domain is "any JSON" by schema (`json` / `json[]`
178
+ * fields, `record` with `values:"json"` members). OPAQUE by contract: no
179
+ * kind identification, no pending_kind, no raw_object degradation — unknown
180
+ * structure here is the declared shape, not a failure. Propagates to every
181
+ * descendant compound.
182
+ */
183
+ private readonly opaquePaths;
184
+ private readonly deferredFields;
185
+ private readonly awaitingKindPaths;
186
+ /** Paths whose kind came from parent-schema prediction, unconfirmed so far. */
187
+ private readonly speculativeKinds;
188
+ /**
189
+ * Kind named by the root object's FIRST key through the `json_root_key`
190
+ * surface registry — a candidate, adopted only at root finalize.
191
+ */
192
+ private rootSurfaceKind;
193
+ /** kind → paths (by key) waiting for the resolver's cold fetch. */
194
+ private readonly pendingSchemaPaths;
195
+ /** Pending-schema paths whose object already closed. */
196
+ private readonly closedPendingPaths;
197
+ /** Schemas delivered via notifySchemaArrived (overlay over the resolver). */
198
+ private readonly arrivedSchemas;
199
+ private tokenizer;
200
+ private root;
201
+ private rootKind;
202
+ private rootDone;
203
+ private failed;
204
+ private readonly options;
205
+ constructor(options: KindStreamParserOptions);
206
+ push(chunk: string): void;
207
+ end(): void;
208
+ private resolvePendingSchemasAsRaw;
209
+ /** True once the root value has closed — the region is fully consumed. */
210
+ get isComplete(): boolean;
211
+ get hasFailed(): boolean;
212
+ /**
213
+ * Upgrade-in-place: the registry's cold fetch answered. Pending nodes for
214
+ * this kind validate and complete (closed nodes retroactively); a null
215
+ * schema (fetch miss) drops them to raw. Safe to call after end().
216
+ */
217
+ notifySchemaArrived(kind: string, schema: KindSchema | null): void;
218
+ private handleToken;
219
+ private handleString;
220
+ private handlePunctuation;
221
+ private beginCompound;
222
+ /**
223
+ * THE JSON-ROOT-KEY SURFACE — `content_ir.kind_surface` rows of type
224
+ * `json_root_key`, live at last (they were inert phantom rows until
225
+ * 2026-08-20).
226
+ *
227
+ * A legacy payload such as `{"quiz_title": ...}` carries no `__kind`, but
228
+ * the ONE surface registry knows exactly which kind that root key names —
229
+ * the same lookup the SERVER performs before adapting the payload
230
+ * (`aidream .../processing/blocks/envelope.py`). Consulting it HERE, in the
231
+ * shared parser core, is what makes one place decide it: both hosts — the
232
+ * one-shot `normalizeJsonRegion` (DB reload / reconcile) and the live
233
+ * `openParseSession` (streaming) — build their parser through
234
+ * `createKindStreamParser`, so neither passes an option and neither can
235
+ * drift from the other.
236
+ *
237
+ * Recorded at the first root key; ADOPTED only when the root object closes
238
+ * (`completeTypedObject`). That is the surface registry's complete-only
239
+ * convergence law, and every json_root_key row is `streaming:false` — these
240
+ * legacy shapes are recognized by their whole payload, so speculating
241
+ * mid-stream would flash a kind component over an object that may never
242
+ * satisfy the schema. An explicit `expectedRootKind` (an agent's declared
243
+ * output schema) is stronger context and always wins; an actual `__kind`
244
+ * still wins over both.
245
+ */
246
+ private noteRootSurfaceKind;
247
+ /**
248
+ * Prediction from the parent schema: object field → declared kind; array
249
+ * item → sole itemKind; root → expectedRootKind. Only when the schema is
250
+ * actually resolvable (a prediction we can't validate against is not a
251
+ * commitment worth making).
252
+ */
253
+ private resolveSpeculativeKind;
254
+ /**
255
+ * A schema usable for OBJECT speculation/snapshots — root-form kinds
256
+ * (non-object data-only shapes) are never a valid object commitment.
257
+ */
258
+ private lookupObjectSchema;
259
+ private beginScalar;
260
+ private placeValue;
261
+ private acceptObjectKey;
262
+ private acceptColon;
263
+ private acceptComma;
264
+ private closeCompound;
265
+ /**
266
+ * True when a value placed at `path` sits directly under a json-any
267
+ * placement: a `json`/`json[]` FIELD, or a member of a `record` whose
268
+ * values are `"json"`. (Deeper descendants inherit via `opaquePaths`.)
269
+ */
270
+ private isJsonAnyPlacement;
271
+ private onValueFinalized;
272
+ /** __kind arrived for an object — confirm speculation, identify, or backtrack. */
273
+ private onKindDiscriminatorArrived;
274
+ /** A contradicted speculation may re-tag only where the new kind is legal. */
275
+ private speculativeRetagAllowed;
276
+ private addPendingSchemaPath;
277
+ private completeTypedObject;
278
+ /** Validate + complete an object whose value carries __kind. */
279
+ private finalizeTypedObject;
280
+ /** Validate + complete an object typed purely by parent prediction. */
281
+ private finalizeSpeculatedObject;
282
+ private validateArrayItemKind;
283
+ private completeRoot;
284
+ /** Mark a node raw (node-scoped failure) without killing the stream. */
285
+ private markNodeRaw;
286
+ /**
287
+ * Degrade ONE node off the resolved path.
288
+ *
289
+ * `cause` defaults to `"invalid"` deliberately: every call site that omits
290
+ * it is a real failure (validation, duplicate key, placement, contradicted
291
+ * speculation). ONLY the "no schema registered" sites pass `"unverified"`,
292
+ * and they are the reason the parameter exists — see `IrKindState`.
293
+ */
294
+ private emitRawObject;
295
+ private clearKindWait;
296
+ private emitFieldIfReady;
297
+ private flushDeferredFields;
298
+ private getLiveObjectValue;
299
+ private emitBlockSnapshotForObject;
300
+ /**
301
+ * On `complete` snapshots (and post-close schema upgrades) the frame has
302
+ * already been popped — the finalized value lives in the root tree.
303
+ */
304
+ private getFinalizedObjectValue;
305
+ private validateFieldPlacement;
306
+ private emitSchemaNotices;
307
+ private validateObjectAgainstSchema;
308
+ private validateFinalFieldValue;
309
+ private validateValueAgainstField;
310
+ private validateScalarField;
311
+ private validateRecordScalar;
312
+ private validateRecordObject;
313
+ private validateObjectAgainstFields;
314
+ private registerObjectContext;
315
+ private resolveParentFieldSchema;
316
+ private getObjectKindForPath;
317
+ private getDirectObjectKind;
318
+ private isAllowedSchemaField;
319
+ private parentFieldName;
320
+ private fieldKeyFromPath;
321
+ private isKindFieldPath;
322
+ private pathKey;
323
+ private lookupSchema;
324
+ private fail;
325
+ private emit;
326
+ private currentFrame;
327
+ }
328
+ declare function createKindStreamParser(options: KindStreamParserOptions): KindStreamParser;
329
+
330
+ /**
331
+ * IrTree — the immutable, structurally-shared view of a parsed region.
332
+ *
333
+ * Consumes KindStreamEvents and maintains one node per kind-resolved path.
334
+ * Node values are STABILIZED: compound children that are themselves kind
335
+ * nodes are substituted by their current tree value, so an update to
336
+ * cards[7] produces new identities for root → cards → cards[7] ONLY;
337
+ * cards[0..6] keep referential identity and memoized components bail out.
338
+ *
339
+ * Parser frame values are NEVER exposed — everything handed out is rebuilt
340
+ * copy-on-write, so it is safe to freeze (Redux dev-mode immutability) and
341
+ * safe to hold across renders.
342
+ *
343
+ * Both the live ParseSession and the one-shot normalizer build their
344
+ * CanonicalBlockIR from this tree — one assembly path, structurally
345
+ * identical output for stream and static input.
346
+ */
347
+
348
+ interface IrTreeNode {
349
+ kind: string;
350
+ kindState: IrKindState;
351
+ path: IrPath;
352
+ pathKey: string;
353
+ /** Stabilized immutable snapshot value (schema fields + __kind only). */
354
+ value: Record<string, unknown>;
355
+ residue: IrResidue | null;
356
+ complete: boolean;
357
+ /** Bumps on every update to this node (incl. child propagation). */
358
+ version: number;
359
+ }
360
+ declare class IrTree {
361
+ private readonly nodes;
362
+ private readonly rawPaths;
363
+ private readonly dirty;
364
+ /**
365
+ * KIND PRESERVATION (streaming db/cloud kinds): pathKey → identified kind
366
+ * for nodes whose kind is KNOWN (kind_identified / pending_schema) but that
367
+ * have no snapshot node yet because the schema is still cold-fetching.
368
+ * Without this, the envelope reports `kind: ""` for the whole pending
369
+ * window and the render seam can only show raw JSON.
370
+ */
371
+ private readonly identifiedKinds;
372
+ /** pathKeys currently waiting on a schema cold fetch. */
373
+ private readonly pendingSchemaPaths;
374
+ /**
375
+ * Early top-level scalar fields (title, loading_message, …) captured for
376
+ * identified-but-schema-pending nodes — the loading-component fuel. Scalars
377
+ * only (no live parser references can escape through here). Superseded the
378
+ * moment a real snapshot node exists.
379
+ */
380
+ private readonly earlyFields;
381
+ /**
382
+ * pathKey → identified kind preserved through a raw fallback (parser stamped
383
+ * `kind` on the raw_object event) — schema-availability degrades and, since
384
+ * 2026-08-29, structural ones too. Only a node nothing ever identified (no
385
+ * `__kind` at all) is absent here.
386
+ */
387
+ private readonly rawKinds;
388
+ /**
389
+ * pathKey → WHY the node degraded. `"unverified"` means no schema was
390
+ * available and nothing was ever checked; `"invalid"` means a check ran and
391
+ * failed. THE RENDER ROUTE BRANCHES ON THIS — see `IrKindState`. Absent =
392
+ * `"invalid"`, so a parser that predates the `cause` field (or any consumer
393
+ * hand-building events) keeps the strict, safe reading.
394
+ */
395
+ private readonly rawCauses;
396
+ private regionStatus;
397
+ private errorReason;
398
+ private rootRawValue;
399
+ /** Notices for degrades that tried to erase already-published data. */
400
+ private readonly rescueNotices;
401
+ private completedKind;
402
+ get status(): "streaming" | "complete" | "error";
403
+ applyEvent(event: KindStreamEvent): void;
404
+ getNode(pathKey: string): IrTreeNode | null;
405
+ listNodes(): IrTreeNode[];
406
+ isRawPath(pathKey: string): boolean;
407
+ /** Dirty pathKeys since the last drain — the flush/notify unit. */
408
+ drainDirty(): string[];
409
+ hasDirty(): boolean;
410
+ private upsertNode;
411
+ /**
412
+ * Substitute kind-node children with their current tree values so sibling
413
+ * identities are stable; deep-copy everything else so no live parser
414
+ * reference ever escapes.
415
+ */
416
+ private stabilizeValue;
417
+ /**
418
+ * COW spine rebuild: replace the child's slot in each ancestor kind-node's
419
+ * value, shallow-copying only the containers along the way. Siblings keep
420
+ * identity; every ancestor gets a new value identity + version bump.
421
+ */
422
+ private propagateToAncestors;
423
+ private findNearestAncestorNode;
424
+ private cloneAlong;
425
+ private markRaw;
426
+ /**
427
+ * A rescue means a degrade tried to erase data a user could already see —
428
+ * an upstream defect. It rides the envelope as a notice so it surfaces in the
429
+ * Error Inspector instead of being silently absorbed (`core/` is a pure
430
+ * kernel: no console, no capture — the notice IS the alarm).
431
+ */
432
+ private recordRescue;
433
+ /**
434
+ * Assemble the canonical envelope. ONE code path for stream + one-shot.
435
+ * Callers supply the fingerprint (one-shot hashes the source; live sessions
436
+ * keep an incremental hasher so no per-flush re-hash happens).
437
+ */
438
+ buildEnvelope(fingerprint: string): CanonicalBlockIR;
439
+ }
440
+
441
+ export { IrTree as I, type JsonPath as J, type KindStreamEvent as K, type RawObjectCause as R, type SchemaResolver as S, type IrTreeNode as a, KindStreamParser as b, type KindStreamParserOptions as c, createKindStreamParser as d, setJsonRootKeyLookup as s };