@ai-matrx/content-ir 0.9.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.
- package/CHANGELOG.md +63 -0
- package/README.md +24 -5
- package/dist/convert.cjs +1680 -0
- package/dist/convert.cjs.map +1 -0
- package/dist/convert.d.cts +230 -0
- package/dist/convert.d.ts +230 -0
- package/dist/convert.js +1666 -0
- package/dist/convert.js.map +1 -0
- package/dist/core.cjs +2493 -0
- package/dist/core.cjs.map +1 -0
- package/dist/core.d.cts +370 -0
- package/dist/core.d.ts +370 -0
- package/dist/core.js +2452 -0
- package/dist/core.js.map +1 -0
- package/dist/index.cjs +3 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -2030
- package/dist/index.d.ts +9 -2030
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/ir-tree-DbLVxbf1.d.cts +441 -0
- package/dist/ir-tree-Dsc_66ek.d.ts +441 -0
- package/dist/ir-types-95bA2cXH.d.cts +119 -0
- package/dist/ir-types-95bA2cXH.d.ts +119 -0
- package/dist/kind-schema.types-CwncWj9U.d.cts +139 -0
- package/dist/kind-schema.types-CwncWj9U.d.ts +139 -0
- package/dist/registry.cjs +468 -0
- package/dist/registry.cjs.map +1 -0
- package/dist/registry.d.cts +357 -0
- package/dist/registry.d.ts +357 -0
- package/dist/registry.js +456 -0
- package/dist/registry.js.map +1 -0
- package/dist/session.cjs +2052 -0
- package/dist/session.cjs.map +1 -0
- package/dist/session.d.cts +75 -0
- package/dist/session.d.ts +75 -0
- package/dist/session.js +2047 -0
- package/dist/session.js.map +1 -0
- package/dist/wire.cjs +310 -0
- package/dist/wire.cjs.map +1 -0
- package/dist/wire.d.cts +326 -0
- package/dist/wire.d.ts +326 -0
- package/dist/wire.js +291 -0
- package/dist/wire.js.map +1 -0
- package/package.json +73 -1
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { a as KindSchema, R as RecordValueType } from './kind-schema.types-CwncWj9U.cjs';
|
|
3
|
+
import { g as IrResidue, f as IrPath, C as CanonicalBlockIR } from './ir-types-95bA2cXH.cjs';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* KindDefinition — one kind, many facets. THE canonical registry entry.
|
|
7
|
+
*
|
|
8
|
+
* This does NOT merge BlockComponentRegistry or artifact-type-registry; the
|
|
9
|
+
* `legacyBlockType` and `artifact` facets are FACADES pointing into them, so
|
|
10
|
+
* migration is incremental and each registry keeps its own job.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* The uniform props contract for kind-driven block components. This is what
|
|
15
|
+
* de-special-cases flashcards: no component receives bespoke glue — every
|
|
16
|
+
* kind component gets exactly this shape.
|
|
17
|
+
*/
|
|
18
|
+
interface KindBlockProps {
|
|
19
|
+
kind: string;
|
|
20
|
+
schema: KindSchema;
|
|
21
|
+
/** Compliant snapshot value (schema fields + __kind). */
|
|
22
|
+
data: Record<string, unknown>;
|
|
23
|
+
status: "streaming" | "complete" | "error";
|
|
24
|
+
residue: IrResidue | null;
|
|
25
|
+
path: IrPath;
|
|
26
|
+
/** ParseSession identity for live child subscriptions; null after reload. */
|
|
27
|
+
identity: string | null;
|
|
28
|
+
/** Child-kind schema lookup (replaces passing allSchemas around). */
|
|
29
|
+
resolve: (kind: string) => KindSchema | undefined;
|
|
30
|
+
}
|
|
31
|
+
type KindTier = "eager" | "warm" | "cold";
|
|
32
|
+
interface KindDefinition {
|
|
33
|
+
/** Canonical slug — THE key. */
|
|
34
|
+
kind: string;
|
|
35
|
+
/** null until the warm/cold fetch delivers it. */
|
|
36
|
+
schema: KindSchema | null;
|
|
37
|
+
schemaSource: "system" | "flexible_data" | "content_ir";
|
|
38
|
+
tier: KindTier;
|
|
39
|
+
/** Component facet — lazy-loaded renderer for this kind. */
|
|
40
|
+
component?: {
|
|
41
|
+
load: () => Promise<{
|
|
42
|
+
default: ComponentType<KindBlockProps>;
|
|
43
|
+
}>;
|
|
44
|
+
};
|
|
45
|
+
/** Facade → BlockComponentRegistry type string (e.g. "flashcards"). */
|
|
46
|
+
legacyBlockType?: string;
|
|
47
|
+
/**
|
|
48
|
+
* Legacy-bridge facet: derive the existing component's `serverData` from a
|
|
49
|
+
* canonical envelope. This is what lets a kind light up the REAL component
|
|
50
|
+
* (FlashcardsBlock, …) with zero component changes during migration.
|
|
51
|
+
*/
|
|
52
|
+
toLegacyServerData?: (envelope: CanonicalBlockIR) => Record<string, unknown> | undefined;
|
|
53
|
+
/** Facade → artifact-type-registry canvasType. */
|
|
54
|
+
artifact?: {
|
|
55
|
+
canvasType: string;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* Markdown export facet — the FORWARD leg of artifact ⇄ markdown. Receives
|
|
59
|
+
* the ZERO-LOSS reconstructed value object (the CALLER reconstructs — for
|
|
60
|
+
* persisted structured artifacts `content.data` already IS that object;
|
|
61
|
+
* this facet only renders it; `__kind` discriminators may still be
|
|
62
|
+
* present and must be ignored). MUST produce human-readable markdown
|
|
63
|
+
* (headings / lists / bold), never a JSON dump — a fenced json body under
|
|
64
|
+
* a heading is acceptable only for inherently-code payloads (e.g. a
|
|
65
|
+
* schema_proposal's JSON Schema). Unknown extra keys the renderer doesn't
|
|
66
|
+
* understand MUST be appended under a small "Additional details"
|
|
67
|
+
* (key: value) section so nothing silently vanishes. Kinds without this
|
|
68
|
+
* facet fall back to `genericKindMarkdown` (kinds/kind-markdown-utils.ts).
|
|
69
|
+
*/
|
|
70
|
+
toMarkdown?: (value: Record<string, unknown>) => string;
|
|
71
|
+
persistence?: {
|
|
72
|
+
persistStructured: boolean;
|
|
73
|
+
};
|
|
74
|
+
/** Future XML tags / kind aliases resolving to this kind. */
|
|
75
|
+
discriminatorAliases?: string[];
|
|
76
|
+
/**
|
|
77
|
+
* PARTIAL-READY opt-in — the streaming partial-kinds posture.
|
|
78
|
+
*
|
|
79
|
+
* While a structured region streams, the server may announce a PROVISIONAL
|
|
80
|
+
* instance of this kind on `metadata.__ir_partial` (valid, closed JSON that
|
|
81
|
+
* may be missing required fields). The default posture is WITHHOLD: a
|
|
82
|
+
* provisional value is never routed to a component, and the block keeps its
|
|
83
|
+
* loading skeleton until the region completes — because a component that
|
|
84
|
+
* throws on an absent field must not be handed one.
|
|
85
|
+
*
|
|
86
|
+
* Setting this to `true` declares "this kind's component renders a partial
|
|
87
|
+
* value without throwing", and the provisional value is routed to the SAME
|
|
88
|
+
* component that renders the final one, filling in as tokens arrive. A kind
|
|
89
|
+
* with a `toLegacyServerData` bridge must ALSO pass `{ provisional: true }`
|
|
90
|
+
* to `makeCompleteEnvelopeBridge` (pinned by a test). A component that
|
|
91
|
+
* throws anyway is caught, screams, and permanently drops this kind back to
|
|
92
|
+
* withhold for the session.
|
|
93
|
+
*
|
|
94
|
+
* Contract: common-docs/systems/content-ir-system/STREAMING_PARTIAL_KINDS.md
|
|
95
|
+
*/
|
|
96
|
+
partialReady?: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Loading-library slug (`kind_definition.metadata.loading_component`) —
|
|
99
|
+
* which of the ~20 hardcoded loading components renders while this kind's
|
|
100
|
+
* instance streams in / its schema+component fetch is in flight. Null or
|
|
101
|
+
* unknown slugs fall back to the generic structured skeleton.
|
|
102
|
+
*/
|
|
103
|
+
loadingComponent?: string | null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Kind ↔ content_ir storage shape — the pure, DB-free reshaping between the
|
|
108
|
+
* consumed `KindSchema` and the `content_ir.kind_definition.data` array +
|
|
109
|
+
* `content_ir.kind_edge` rows.
|
|
110
|
+
*
|
|
111
|
+
* Two exact inverses:
|
|
112
|
+
* - `kindSchemaToStorage` — the MIGRATION / write direction: a parsed
|
|
113
|
+
* `KindSchema` (fields Record, targets inline) → an ORDERED `data` array
|
|
114
|
+
* (targets stripped) + externalized `kind_edge` specs (targets, keyed by
|
|
115
|
+
* field PATH). This is what pours `flexible_data` (and future authored
|
|
116
|
+
* kinds) into the canonical tables.
|
|
117
|
+
* - `storageToKindSchema` — the ADAPTER / read direction: `data` array +
|
|
118
|
+
* edges → the same `KindSchema` the parser/emitter consume, re-attaching
|
|
119
|
+
* `object.kind` / `array.itemKinds` from the edges by path.
|
|
120
|
+
*
|
|
121
|
+
* Design invariants (from the 2026-07-05 kind-registry storage design, since deleted):
|
|
122
|
+
* - The `data` element is `FieldSchema` + `name`, MINUS ref targets. Order is
|
|
123
|
+
* intrinsic to the array (fixes the jsonb key-reorder bug).
|
|
124
|
+
* - `kind_edge` is the SINGLE source of truth for kind→kind refs: `object`
|
|
125
|
+
* → one edge (position null); `array` → N edges (union) ordered by
|
|
126
|
+
* `position`. `field_name` is a dot-PATH so a ref nested inside an
|
|
127
|
+
* `inline_object` still gets a distinct, collision-free edge.
|
|
128
|
+
* - `inline_object` is structural: its `fields` is an ordered array, it never
|
|
129
|
+
* becomes a registry row and never carries `__kind`. Its nested refs DO get
|
|
130
|
+
* edges (path-prefixed) so cascade/pinning see every dependency. Its
|
|
131
|
+
* `open` flag persists on the element (losing it is the open-empty-object
|
|
132
|
+
* defect).
|
|
133
|
+
* - `union.kinds` refs externalize to edges exactly like `array.itemKinds`;
|
|
134
|
+
* the stored element keeps `hasKinds: true` so lost edges scream on read.
|
|
135
|
+
* - A NON-OBJECT ROOT (`KindSchema.root`) stores as ONE reserved element
|
|
136
|
+
* named `ROOT_STORAGE_NAME` ("__root") — the only element allowed in that
|
|
137
|
+
* kind's `data`. Real fields may never use the reserved name.
|
|
138
|
+
*
|
|
139
|
+
* NO imports of supabase / the DB — this is pure and unit-tested by round-trip
|
|
140
|
+
* (`__tests__/kind-storage-transform.test.ts`).
|
|
141
|
+
*/
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Reserved `data[]` element name for a NON-OBJECT ROOT form (`KindSchema.root`).
|
|
145
|
+
* A root-form kind stores exactly one element under this name; the read
|
|
146
|
+
* direction reconstructs `{ root }` instead of a field map. The write
|
|
147
|
+
* direction rejects any REAL field with this name — the name is the marker.
|
|
148
|
+
*/
|
|
149
|
+
declare const ROOT_STORAGE_NAME = "__root";
|
|
150
|
+
type StoredFieldBase = {
|
|
151
|
+
name: string;
|
|
152
|
+
required?: boolean;
|
|
153
|
+
nullable?: boolean;
|
|
154
|
+
/** Human guidance — mirrors FieldBase.description. */
|
|
155
|
+
description?: string;
|
|
156
|
+
/** Default VALUE (annotation-level) — mirrors FieldBase.default. */
|
|
157
|
+
default?: unknown;
|
|
158
|
+
};
|
|
159
|
+
/** One element of `kind_definition.data` — FieldSchema + name, ref targets removed. */
|
|
160
|
+
type StoredFieldElement = (StoredFieldBase & {
|
|
161
|
+
type: "string" | "boolean";
|
|
162
|
+
}) | (StoredFieldBase & {
|
|
163
|
+
type: "number";
|
|
164
|
+
min?: number;
|
|
165
|
+
max?: number;
|
|
166
|
+
step?: number;
|
|
167
|
+
}) | (StoredFieldBase & {
|
|
168
|
+
type: "string[]";
|
|
169
|
+
values?: string[];
|
|
170
|
+
open?: boolean;
|
|
171
|
+
}) | (StoredFieldBase & {
|
|
172
|
+
type: "number[]" | "boolean[]";
|
|
173
|
+
}) | (StoredFieldBase & {
|
|
174
|
+
type: "json";
|
|
175
|
+
}) | (StoredFieldBase & {
|
|
176
|
+
type: "json[]";
|
|
177
|
+
}) | (StoredFieldBase & {
|
|
178
|
+
type: "array";
|
|
179
|
+
}) | (StoredFieldBase & {
|
|
180
|
+
type: "object";
|
|
181
|
+
}) | (StoredFieldBase & {
|
|
182
|
+
type: "inline_object";
|
|
183
|
+
fields: StoredFieldElement[];
|
|
184
|
+
open?: boolean;
|
|
185
|
+
}) | (StoredFieldBase & {
|
|
186
|
+
type: "record";
|
|
187
|
+
values: RecordValueType;
|
|
188
|
+
}) | (StoredFieldBase & {
|
|
189
|
+
type: "enum";
|
|
190
|
+
values: string[];
|
|
191
|
+
open?: boolean;
|
|
192
|
+
}) | (StoredFieldBase & {
|
|
193
|
+
type: "union";
|
|
194
|
+
scalars: Array<"string" | "number" | "boolean">;
|
|
195
|
+
/** Marker that this union's kind refs live in edges (positions ordered). */
|
|
196
|
+
hasKinds?: boolean;
|
|
197
|
+
});
|
|
198
|
+
/** One `content_ir.kind_edge` row (child resolved to an id at insert time). */
|
|
199
|
+
type KindEdgeSpec = {
|
|
200
|
+
/** Field PATH in the parent's `data` (dot-notation into inline_objects). */
|
|
201
|
+
fieldPath: string;
|
|
202
|
+
/** Child kind slug — insert resolves this to `child_definition_id`. */
|
|
203
|
+
childKind: string;
|
|
204
|
+
/** Union (anyOf) ordering for array refs; null for a single object ref. */
|
|
205
|
+
position: number | null;
|
|
206
|
+
};
|
|
207
|
+
/** The full write payload for one kind: the ordered data array + its edges. */
|
|
208
|
+
type KindStorageShape = {
|
|
209
|
+
data: StoredFieldElement[];
|
|
210
|
+
edges: KindEdgeSpec[];
|
|
211
|
+
};
|
|
212
|
+
declare class KindStorageError extends Error {
|
|
213
|
+
constructor(message: string);
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* MIGRATION / write direction. Order of `data` follows `Object.entries(fields)`
|
|
217
|
+
* — the caller supplies the KindSchema whose field order is authoritative
|
|
218
|
+
* (prefer the compiled `system-kinds.ts` order for system kinds during the
|
|
219
|
+
* one-time flexible_data migration; jsonb order is the fallback for user kinds).
|
|
220
|
+
*/
|
|
221
|
+
declare function kindSchemaToStorage(schema: KindSchema): KindStorageShape;
|
|
222
|
+
/** ADAPTER / read direction — the exact inverse of `kindSchemaToStorage`. */
|
|
223
|
+
declare function storageToKindSchema(kind: string, shape: KindStorageShape): KindSchema;
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* The dual gate — Arman's law as executable code: a kind is only `is_active`
|
|
227
|
+
* when its canonical `sample_data` passes BOTH systems.
|
|
228
|
+
*
|
|
229
|
+
* 1. Structural (Pydantic): the sample validates against the kind's
|
|
230
|
+
* `emitted_json_schema`. Python's Pydantic is the AUTHORITATIVE owner of
|
|
231
|
+
* this leg, but it reads the SAME materialized `emitted_json_schema` — so
|
|
232
|
+
* this TS ajv check and the Python check validate the same sample against
|
|
233
|
+
* the same schema and agree by construction. A disagreement IS the
|
|
234
|
+
* screamer (a schema Pydantic can't express, or an ajv/Pydantic gap).
|
|
235
|
+
* 2. Render (UI): the sample lights up the kind's real component. TS is the
|
|
236
|
+
* AUTHORITATIVE owner of this leg. It is a PROXY for a DOM render, not a
|
|
237
|
+
* DOM render. Exactly what it checks, and nothing more:
|
|
238
|
+
* · the kind has something to render with (`legacyBlockType` or
|
|
239
|
+
* `component`);
|
|
240
|
+
* · for BRIDGED kinds, `toLegacyServerData(sample)` returns a plain
|
|
241
|
+
* object that is SEMANTICALLY non-empty — see
|
|
242
|
+
* `describeUnrenderableBridgeOutput` for the exact predicate;
|
|
243
|
+
* · BRIDGELESS kinds pass with a recorded caveat — nothing is verified.
|
|
244
|
+
*
|
|
245
|
+
* This catches the 2026-07-04 "No flashcards available yet" class: a
|
|
246
|
+
* bridge that returns `undefined`, `{}`, `{language:"json"}` (the raw
|
|
247
|
+
* code-region annotation), or an object whose every value is empty.
|
|
248
|
+
*
|
|
249
|
+
* What it does NOT do — stated plainly, because a gate that overclaims is
|
|
250
|
+
* worse than no gate: it does not mount the component, and it cannot know
|
|
251
|
+
* WHICH key carries the payload. `{title:"Cell Biology", cards:[]}` passes
|
|
252
|
+
* this leg on `title` alone. Proving the payload key is populated needs
|
|
253
|
+
* per-kind knowledge the gate deliberately does not have; a DOM-level
|
|
254
|
+
* render check is the deeper leg, deferred to an RTL harness.
|
|
255
|
+
*
|
|
256
|
+
* Both legs necessary, neither sufficient. Fail either → `isActive: false` and
|
|
257
|
+
* the caller reports it loudly (Error Inspector, `content-ir`) and holds the
|
|
258
|
+
* row out of production. This module is PURE (deps injected) so it runs in the
|
|
259
|
+
* harness, in CI, and in a browser author-save alike.
|
|
260
|
+
*
|
|
261
|
+
* Ownership split (the 2026-07-05 kind-registry storage design, since deleted; the live contract is the code below): the caller writes the outcome
|
|
262
|
+
* to the LIVE `content_ir.kind_definition` row's `is_active`; the canonical
|
|
263
|
+
* `_version_capture` trigger snapshots that state into `history.row_versions`
|
|
264
|
+
* (never a post-hoc history mutation).
|
|
265
|
+
*/
|
|
266
|
+
|
|
267
|
+
/** The facets the render leg needs — a structural subset of KindDefinition. */
|
|
268
|
+
interface DualGateDefinition {
|
|
269
|
+
legacyBlockType?: string;
|
|
270
|
+
toLegacyServerData?: (envelope: CanonicalBlockIR) => Record<string, unknown> | undefined;
|
|
271
|
+
component?: {
|
|
272
|
+
load: () => Promise<unknown>;
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* The render leg's second satisfier: an ACTIVE `role='output'` component
|
|
277
|
+
* resolved from `content_ir.kind_component`. Feed this from
|
|
278
|
+
* `resolveComponent(kind, "web", "output")`.
|
|
279
|
+
*
|
|
280
|
+
* Why this exists: the render leg originally consulted only the compiled TS
|
|
281
|
+
* registry, so an agent-authored kind whose renderer is a `source='db'` row was
|
|
282
|
+
* structurally unable to pass — `definition` came back null and the gate said
|
|
283
|
+
* "no component" about a kind that had a live, working one. Six authored kinds
|
|
284
|
+
* (wine_tasting, employee_card, employee_roster, employee_of_the_week,
|
|
285
|
+
* flashcard_deck, arman_video_prompt) sat permanently inactive because of it.
|
|
286
|
+
*
|
|
287
|
+
* NOT a mirror of `content_ir.evaluate_kind_activation`. The SQL render leg is
|
|
288
|
+
* presence-only — it checks that an active `role='output'` row exists, because
|
|
289
|
+
* SQL cannot execute a TypeScript bridge. THIS leg is strictly stronger: for a
|
|
290
|
+
* compiled kind it also runs `toLegacyServerData` and rejects semantically
|
|
291
|
+
* empty output (the "No <kind> available" class).
|
|
292
|
+
*
|
|
293
|
+
* The asymmetry is deliberate and bounded: SQL is the FLOOR (necessary, and
|
|
294
|
+
* sufficient for DB-authored components, which own no bridge), while this leg
|
|
295
|
+
* is the CEILING for compiled kinds. Consequence to know: activating a COMPILED
|
|
296
|
+
* kind whose bridge is broken would pass the RPC and fail here. Compiled kinds
|
|
297
|
+
* are activated by developers through `scripts/shape/activate-kinds.ts`, which
|
|
298
|
+
* runs this leg — the studio control only ever reaches owner-authored kinds.
|
|
299
|
+
* If that ever stops being true, the browser control must run this gate before
|
|
300
|
+
* enabling its button.
|
|
301
|
+
*/
|
|
302
|
+
interface DualGateResolvedComponent {
|
|
303
|
+
componentKey: string;
|
|
304
|
+
/** The row's own render-trust verdict (R6). Inactive rows do not satisfy. */
|
|
305
|
+
isActive: boolean;
|
|
306
|
+
/** "bundled" | "db" — reported in the leg detail, never gates the verdict. */
|
|
307
|
+
source: string;
|
|
308
|
+
}
|
|
309
|
+
interface DualGateInput {
|
|
310
|
+
kind: string;
|
|
311
|
+
/** The canonical instance (kind_definition.sample_data). */
|
|
312
|
+
sample: Record<string, unknown>;
|
|
313
|
+
/** The materialized kind_definition.emitted_json_schema (plain, no __kind). */
|
|
314
|
+
emittedJsonSchema: unknown;
|
|
315
|
+
/** The registry definition for the kind (or null when unregistered). */
|
|
316
|
+
definition: DualGateDefinition | null;
|
|
317
|
+
/**
|
|
318
|
+
* The resolver's `(kind, web, output)` answer, when the caller has one.
|
|
319
|
+
* Omit (or pass null) to check the compiled registry alone.
|
|
320
|
+
*/
|
|
321
|
+
resolvedComponent?: DualGateResolvedComponent | null;
|
|
322
|
+
/**
|
|
323
|
+
* True when the kind is a generated data-only contract
|
|
324
|
+
* (`metadata.family` ∈ workflow_io | tool_io | action_io | agent_io).
|
|
325
|
+
* Those are passed between nodes and never rendered, so the render leg is
|
|
326
|
+
* structurally inapplicable — the same `n/a` doctrine the shape doctor uses.
|
|
327
|
+
* Failing them would be noise, and noise erodes the gate.
|
|
328
|
+
*/
|
|
329
|
+
dataOnly?: boolean;
|
|
330
|
+
}
|
|
331
|
+
interface LegResult {
|
|
332
|
+
ok: boolean;
|
|
333
|
+
detail?: string;
|
|
334
|
+
}
|
|
335
|
+
interface DualGateResult {
|
|
336
|
+
/** True only when BOTH legs pass — the value the caller writes to is_active. */
|
|
337
|
+
isActive: boolean;
|
|
338
|
+
structural: LegResult;
|
|
339
|
+
render: LegResult;
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* The structural leg, exported on its own so the shape doctor
|
|
343
|
+
* (`shape-doctor.ts`) RECOMPUTES gate validation with the exact same ajv
|
|
344
|
+
* config + marker semantics as activation (verbatim first, marker-free retry
|
|
345
|
+
* second) — never a parallel validator. `sample` is `unknown` (not `Record`) because kind examples may
|
|
346
|
+
* legitimately be scalars/arrays (workflow I/O kinds like `text`/`number`).
|
|
347
|
+
*/
|
|
348
|
+
declare function validateStructuralLeg(sample: unknown, emittedJsonSchema: unknown): LegResult;
|
|
349
|
+
declare function runKindDualGate(input: DualGateInput): DualGateResult;
|
|
350
|
+
/**
|
|
351
|
+
* One-line, Error-Inspector-ready reason for a failed gate (empty string when
|
|
352
|
+
* it passed). The caller feeds this to `captureError({ source: "content-ir" })`
|
|
353
|
+
* and sets `is_active=false`.
|
|
354
|
+
*/
|
|
355
|
+
declare function describeDualGateFailure(kind: string, result: DualGateResult): string;
|
|
356
|
+
|
|
357
|
+
export { type DualGateDefinition, type DualGateInput, type DualGateResolvedComponent, type DualGateResult, type KindBlockProps, type KindDefinition, type KindEdgeSpec, KindStorageError, type KindStorageShape, type KindTier, type LegResult, ROOT_STORAGE_NAME, type StoredFieldElement, describeDualGateFailure, kindSchemaToStorage, runKindDualGate, storageToKindSchema, validateStructuralLeg };
|