@ai-matrx/content-ir 0.5.0 → 0.7.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/dist/index.d.cts CHANGED
@@ -1656,6 +1656,54 @@ declare function collectReferencedKinds(fields: Record<string, FieldSchema>): st
1656
1656
  declare function collectSchemaReferencedKinds(schema: KindSchema): string[];
1657
1657
  declare function kindSchemaToJsonSchema(kind: string, resolve: (kind: string) => KindSchema | undefined, options?: KindJsonSchemaOptions): KindJsonSchemaExport | null;
1658
1658
 
1659
+ /**
1660
+ * JSON Schema → KindSchema — THE registry-facing direction.
1661
+ *
1662
+ * 🚨 WHY THIS FILE IS THE POINT OF THE WHOLE CONVERT LAYER (Arman's ruling,
1663
+ * 2026-08-29): a kind's fields must be DERIVED from its schema, never stored a
1664
+ * second time. `content_ir.kind_definition` used to carry both — a JSON Schema
1665
+ * AND a flattened field list written beside it — and the two had already
1666
+ * diverged on 13 of the 62 live kinds that carried both: stored lists holding
1667
+ * `__kind` as if it were a data field, enums flattened to bare strings,
1668
+ * min/max bounds and required flags the schema states and the copy never
1669
+ * learned. A cache that can disagree with its source is not a cache.
1670
+ *
1671
+ * The heavy lifting lives in `openai-schema-converter.ts` (it also serves the
1672
+ * agent-authoring flow, which needs the problems/dropped-metadata detail).
1673
+ * This module is the narrow, honest door the registry calls: one schema in,
1674
+ * one `KindSchema` out, plus whatever child kinds the schema declared inline
1675
+ * or through `$defs`.
1676
+ *
1677
+ * Accepts both storage shapes seen in the wild: a bare JSON Schema, and the
1678
+ * provider `{name, schema, strict}` response-format envelope that 5 live rows
1679
+ * carry.
1680
+ */
1681
+
1682
+ type KindSchemaFromJsonResult = {
1683
+ /**
1684
+ * The requested kind's schema, or null when the input could not be read as
1685
+ * an object contract at all. NEVER a partial guess: a field the vocabulary
1686
+ * cannot express degrades to `json` (widening, always safe), and only a
1687
+ * structurally unusable root yields null.
1688
+ */
1689
+ schema: KindSchema | null;
1690
+ /**
1691
+ * Child kinds the schema declared inline or via `$defs`, keyed by slug.
1692
+ * A registry that ingests these gets the whole tree from ONE row's schema —
1693
+ * which is how a nested kind renders before its children's rows load.
1694
+ */
1695
+ children: Record<string, KindSchema>;
1696
+ /** Conversion notes. `severity: "error"` entries are worth screaming about. */
1697
+ problems: ConversionProblem[];
1698
+ };
1699
+ /**
1700
+ * Derive `kind`'s field schema from its JSON Schema.
1701
+ *
1702
+ * Pure and synchronous — no registry, no IO — so a host can call it from a
1703
+ * warm load, a cold fetch, a reducer, or a test.
1704
+ */
1705
+ declare function kindSchemaFromJsonSchema(kind: string, jsonSchema: unknown): KindSchemaFromJsonResult;
1706
+
1659
1707
  /**
1660
1708
  * Streaming partial kinds — the TS twin of the Python producer's contract.
1661
1709
  *
@@ -1979,4 +2027,4 @@ declare function emitPayloadJson(kind: string, value: unknown): string;
1979
2027
  */
1980
2028
  declare function emitPayloadFence(kind: string, value: unknown): string;
1981
2029
 
1982
- export { type AnyPartialKindEvent, type ArrayItemKindBinding, type ArrayItemScalarType, type BlockSchemaDraft, type CanonicalBlockIR, type CanonicalContent, type CanonicalSegment, type CompleteValueEnvelopeOptions, type CompliantKindSnapshot, type ContentRegionInit, type ConversionProblem, type DroppedMetadata, type DualGateDefinition, type DualGateInput, type DualGateResolvedComponent, type DualGateResult, type FieldComparison, type FieldSchema, type Fingerprinter, IR_ENVELOPE_CACHE_VERSION, IR_ENVELOPE_KEY, IR_PARTIAL_KEY, IR_VERSION, type InboundEnvelopeHooks, type InboundEnvelopeVerdict, type IrDiscriminator, type IrEnvelopeCache, type IrKindState, type IrPath, type IrResidue, type IrStructuredNode, IrTree, type IrTreeNode, type ItemKindRefCheck, JSON_DISCRIMINATOR, type JsonPath, type JsonSchemaNode, JsonStreamTokenizer, type JsonToken, KIND_KEY, type KindBlockProps, type KindDefinition, type KindEdgeSpec, type KindJsonSchemaExport, type KindJsonSchemaOptions, type KindResolution, type KindSchema, KindStorageError, type KindStorageShape, type KindStreamEvent, KindStreamParser, type KindStreamParserOptions, type KindTier, type KindVerdict, type LegResult, NODE_OUTCOME_KIND, type NodeOutcomeWrapper, type NormalizeJsonRegionOptions, ParseSession, type ParseSessionOptions, type PartialKindEvent, type PartialKindNode, type PartialKindState, type Punct, ROOT_STORAGE_NAME, RUN_RESULT_KIND, type RawObjectCause, type RecordValueType, type RegionEndReason, type RegionFormat, type RegionSourceKind, type RetractedKindEvent, type RunResultWrapper, type SavePlanEntry, type SavePlanValidation, type ScalarFieldType, type SchemaConversionResult, type SchemaLayoutMode, type SchemaResolver, type StoredFieldElement, type SupersededKindEvent, advancePartialKind, buildAgentSchemaWithRenderBlockSupport, buildCompliantKindSnapshot, classifyInboundEnvelopeMetadata, collectReferencedKinds, collectSchemaReferencedKinds, compareWithExistingKindSchema, convertAiSchemaToBlockFields, createFingerprinter, createKindStreamParser, describeDualGateFailure, disposeParseSession, emitPayloadFence, emitPayloadJson, emptyValueForFieldSchema, envelopeCacheFromEnvelopes, envelopeFromCompleteValue, fenceDiscriminator, fieldsToDbPayload, fingerprintText, formatBlockLabel, getParseSession, injectKindIntoObjectSchema, irPathIsUnderOrEqual, irPathKey, irPathLabel, irPathsEqual, isCanonicalBlockIR, isDuplicateBlockSlug, isEmptyResidue, isIrEnvelopeCache, isJsonAnyField, isProvisionalKind, isScalarArrayType, isTerminalKindEvent, kindSchemaToJsonSchema, kindSchemaToStorage, kindVerdictOf, makePartialKindStalenessGate, mergeResidueIntoValue, normalizeAiSchemaInput, normalizeJsonRegion, openParseSession, readEnvelope, readNodeOutcomeValue, readObjectKind, readOutputRef, readPartialKindEvent, readRunResultValue, reconstructRegionValue, rehydrateNodeOutcome, rehydrateRunResult, reuseEnvelopeIfCurrent, runKindDualGate, runSchemaConversion, sanitizeInboundEnvelopeMetadata, sanitizeInboundPartialKindMetadata, scalarArrayItemType, schemaLayoutMode, schemaStructureDepth, setJsonRootKeyLookup, storageToKindSchema, stripKindDeep, validateBlockSchemaSavePlan, validateStructuralLeg, withRootKind, xmlDiscriminator };
2030
+ export { type AnyPartialKindEvent, type ArrayItemKindBinding, type ArrayItemScalarType, type BlockSchemaDraft, type CanonicalBlockIR, type CanonicalContent, type CanonicalSegment, type CompleteValueEnvelopeOptions, type CompliantKindSnapshot, type ContentRegionInit, type ConversionProblem, type DroppedMetadata, type DualGateDefinition, type DualGateInput, type DualGateResolvedComponent, type DualGateResult, type FieldComparison, type FieldSchema, type Fingerprinter, IR_ENVELOPE_CACHE_VERSION, IR_ENVELOPE_KEY, IR_PARTIAL_KEY, IR_VERSION, type InboundEnvelopeHooks, type InboundEnvelopeVerdict, type IrDiscriminator, type IrEnvelopeCache, type IrKindState, type IrPath, type IrResidue, type IrStructuredNode, IrTree, type IrTreeNode, type ItemKindRefCheck, JSON_DISCRIMINATOR, type JsonPath, type JsonSchemaNode, JsonStreamTokenizer, type JsonToken, KIND_KEY, type KindBlockProps, type KindDefinition, type KindEdgeSpec, type KindJsonSchemaExport, type KindJsonSchemaOptions, type KindResolution, type KindSchema, type KindSchemaFromJsonResult, KindStorageError, type KindStorageShape, type KindStreamEvent, KindStreamParser, type KindStreamParserOptions, type KindTier, type KindVerdict, type LegResult, NODE_OUTCOME_KIND, type NodeOutcomeWrapper, type NormalizeJsonRegionOptions, ParseSession, type ParseSessionOptions, type PartialKindEvent, type PartialKindNode, type PartialKindState, type Punct, ROOT_STORAGE_NAME, RUN_RESULT_KIND, type RawObjectCause, type RecordValueType, type RegionEndReason, type RegionFormat, type RegionSourceKind, type RetractedKindEvent, type RunResultWrapper, type SavePlanEntry, type SavePlanValidation, type ScalarFieldType, type SchemaConversionResult, type SchemaLayoutMode, type SchemaResolver, type StoredFieldElement, type SupersededKindEvent, advancePartialKind, buildAgentSchemaWithRenderBlockSupport, buildCompliantKindSnapshot, classifyInboundEnvelopeMetadata, collectReferencedKinds, collectSchemaReferencedKinds, compareWithExistingKindSchema, convertAiSchemaToBlockFields, createFingerprinter, createKindStreamParser, describeDualGateFailure, disposeParseSession, emitPayloadFence, emitPayloadJson, emptyValueForFieldSchema, envelopeCacheFromEnvelopes, envelopeFromCompleteValue, fenceDiscriminator, fieldsToDbPayload, fingerprintText, formatBlockLabel, getParseSession, injectKindIntoObjectSchema, irPathIsUnderOrEqual, irPathKey, irPathLabel, irPathsEqual, isCanonicalBlockIR, isDuplicateBlockSlug, isEmptyResidue, isIrEnvelopeCache, isJsonAnyField, isProvisionalKind, isScalarArrayType, isTerminalKindEvent, kindSchemaFromJsonSchema, kindSchemaToJsonSchema, kindSchemaToStorage, kindVerdictOf, makePartialKindStalenessGate, mergeResidueIntoValue, normalizeAiSchemaInput, normalizeJsonRegion, openParseSession, readEnvelope, readNodeOutcomeValue, readObjectKind, readOutputRef, readPartialKindEvent, readRunResultValue, reconstructRegionValue, rehydrateNodeOutcome, rehydrateRunResult, reuseEnvelopeIfCurrent, runKindDualGate, runSchemaConversion, sanitizeInboundEnvelopeMetadata, sanitizeInboundPartialKindMetadata, scalarArrayItemType, schemaLayoutMode, schemaStructureDepth, setJsonRootKeyLookup, storageToKindSchema, stripKindDeep, validateBlockSchemaSavePlan, validateStructuralLeg, withRootKind, xmlDiscriminator };
package/dist/index.d.ts CHANGED
@@ -1656,6 +1656,54 @@ declare function collectReferencedKinds(fields: Record<string, FieldSchema>): st
1656
1656
  declare function collectSchemaReferencedKinds(schema: KindSchema): string[];
1657
1657
  declare function kindSchemaToJsonSchema(kind: string, resolve: (kind: string) => KindSchema | undefined, options?: KindJsonSchemaOptions): KindJsonSchemaExport | null;
1658
1658
 
1659
+ /**
1660
+ * JSON Schema → KindSchema — THE registry-facing direction.
1661
+ *
1662
+ * 🚨 WHY THIS FILE IS THE POINT OF THE WHOLE CONVERT LAYER (Arman's ruling,
1663
+ * 2026-08-29): a kind's fields must be DERIVED from its schema, never stored a
1664
+ * second time. `content_ir.kind_definition` used to carry both — a JSON Schema
1665
+ * AND a flattened field list written beside it — and the two had already
1666
+ * diverged on 13 of the 62 live kinds that carried both: stored lists holding
1667
+ * `__kind` as if it were a data field, enums flattened to bare strings,
1668
+ * min/max bounds and required flags the schema states and the copy never
1669
+ * learned. A cache that can disagree with its source is not a cache.
1670
+ *
1671
+ * The heavy lifting lives in `openai-schema-converter.ts` (it also serves the
1672
+ * agent-authoring flow, which needs the problems/dropped-metadata detail).
1673
+ * This module is the narrow, honest door the registry calls: one schema in,
1674
+ * one `KindSchema` out, plus whatever child kinds the schema declared inline
1675
+ * or through `$defs`.
1676
+ *
1677
+ * Accepts both storage shapes seen in the wild: a bare JSON Schema, and the
1678
+ * provider `{name, schema, strict}` response-format envelope that 5 live rows
1679
+ * carry.
1680
+ */
1681
+
1682
+ type KindSchemaFromJsonResult = {
1683
+ /**
1684
+ * The requested kind's schema, or null when the input could not be read as
1685
+ * an object contract at all. NEVER a partial guess: a field the vocabulary
1686
+ * cannot express degrades to `json` (widening, always safe), and only a
1687
+ * structurally unusable root yields null.
1688
+ */
1689
+ schema: KindSchema | null;
1690
+ /**
1691
+ * Child kinds the schema declared inline or via `$defs`, keyed by slug.
1692
+ * A registry that ingests these gets the whole tree from ONE row's schema —
1693
+ * which is how a nested kind renders before its children's rows load.
1694
+ */
1695
+ children: Record<string, KindSchema>;
1696
+ /** Conversion notes. `severity: "error"` entries are worth screaming about. */
1697
+ problems: ConversionProblem[];
1698
+ };
1699
+ /**
1700
+ * Derive `kind`'s field schema from its JSON Schema.
1701
+ *
1702
+ * Pure and synchronous — no registry, no IO — so a host can call it from a
1703
+ * warm load, a cold fetch, a reducer, or a test.
1704
+ */
1705
+ declare function kindSchemaFromJsonSchema(kind: string, jsonSchema: unknown): KindSchemaFromJsonResult;
1706
+
1659
1707
  /**
1660
1708
  * Streaming partial kinds — the TS twin of the Python producer's contract.
1661
1709
  *
@@ -1979,4 +2027,4 @@ declare function emitPayloadJson(kind: string, value: unknown): string;
1979
2027
  */
1980
2028
  declare function emitPayloadFence(kind: string, value: unknown): string;
1981
2029
 
1982
- export { type AnyPartialKindEvent, type ArrayItemKindBinding, type ArrayItemScalarType, type BlockSchemaDraft, type CanonicalBlockIR, type CanonicalContent, type CanonicalSegment, type CompleteValueEnvelopeOptions, type CompliantKindSnapshot, type ContentRegionInit, type ConversionProblem, type DroppedMetadata, type DualGateDefinition, type DualGateInput, type DualGateResolvedComponent, type DualGateResult, type FieldComparison, type FieldSchema, type Fingerprinter, IR_ENVELOPE_CACHE_VERSION, IR_ENVELOPE_KEY, IR_PARTIAL_KEY, IR_VERSION, type InboundEnvelopeHooks, type InboundEnvelopeVerdict, type IrDiscriminator, type IrEnvelopeCache, type IrKindState, type IrPath, type IrResidue, type IrStructuredNode, IrTree, type IrTreeNode, type ItemKindRefCheck, JSON_DISCRIMINATOR, type JsonPath, type JsonSchemaNode, JsonStreamTokenizer, type JsonToken, KIND_KEY, type KindBlockProps, type KindDefinition, type KindEdgeSpec, type KindJsonSchemaExport, type KindJsonSchemaOptions, type KindResolution, type KindSchema, KindStorageError, type KindStorageShape, type KindStreamEvent, KindStreamParser, type KindStreamParserOptions, type KindTier, type KindVerdict, type LegResult, NODE_OUTCOME_KIND, type NodeOutcomeWrapper, type NormalizeJsonRegionOptions, ParseSession, type ParseSessionOptions, type PartialKindEvent, type PartialKindNode, type PartialKindState, type Punct, ROOT_STORAGE_NAME, RUN_RESULT_KIND, type RawObjectCause, type RecordValueType, type RegionEndReason, type RegionFormat, type RegionSourceKind, type RetractedKindEvent, type RunResultWrapper, type SavePlanEntry, type SavePlanValidation, type ScalarFieldType, type SchemaConversionResult, type SchemaLayoutMode, type SchemaResolver, type StoredFieldElement, type SupersededKindEvent, advancePartialKind, buildAgentSchemaWithRenderBlockSupport, buildCompliantKindSnapshot, classifyInboundEnvelopeMetadata, collectReferencedKinds, collectSchemaReferencedKinds, compareWithExistingKindSchema, convertAiSchemaToBlockFields, createFingerprinter, createKindStreamParser, describeDualGateFailure, disposeParseSession, emitPayloadFence, emitPayloadJson, emptyValueForFieldSchema, envelopeCacheFromEnvelopes, envelopeFromCompleteValue, fenceDiscriminator, fieldsToDbPayload, fingerprintText, formatBlockLabel, getParseSession, injectKindIntoObjectSchema, irPathIsUnderOrEqual, irPathKey, irPathLabel, irPathsEqual, isCanonicalBlockIR, isDuplicateBlockSlug, isEmptyResidue, isIrEnvelopeCache, isJsonAnyField, isProvisionalKind, isScalarArrayType, isTerminalKindEvent, kindSchemaToJsonSchema, kindSchemaToStorage, kindVerdictOf, makePartialKindStalenessGate, mergeResidueIntoValue, normalizeAiSchemaInput, normalizeJsonRegion, openParseSession, readEnvelope, readNodeOutcomeValue, readObjectKind, readOutputRef, readPartialKindEvent, readRunResultValue, reconstructRegionValue, rehydrateNodeOutcome, rehydrateRunResult, reuseEnvelopeIfCurrent, runKindDualGate, runSchemaConversion, sanitizeInboundEnvelopeMetadata, sanitizeInboundPartialKindMetadata, scalarArrayItemType, schemaLayoutMode, schemaStructureDepth, setJsonRootKeyLookup, storageToKindSchema, stripKindDeep, validateBlockSchemaSavePlan, validateStructuralLeg, withRootKind, xmlDiscriminator };
2030
+ export { type AnyPartialKindEvent, type ArrayItemKindBinding, type ArrayItemScalarType, type BlockSchemaDraft, type CanonicalBlockIR, type CanonicalContent, type CanonicalSegment, type CompleteValueEnvelopeOptions, type CompliantKindSnapshot, type ContentRegionInit, type ConversionProblem, type DroppedMetadata, type DualGateDefinition, type DualGateInput, type DualGateResolvedComponent, type DualGateResult, type FieldComparison, type FieldSchema, type Fingerprinter, IR_ENVELOPE_CACHE_VERSION, IR_ENVELOPE_KEY, IR_PARTIAL_KEY, IR_VERSION, type InboundEnvelopeHooks, type InboundEnvelopeVerdict, type IrDiscriminator, type IrEnvelopeCache, type IrKindState, type IrPath, type IrResidue, type IrStructuredNode, IrTree, type IrTreeNode, type ItemKindRefCheck, JSON_DISCRIMINATOR, type JsonPath, type JsonSchemaNode, JsonStreamTokenizer, type JsonToken, KIND_KEY, type KindBlockProps, type KindDefinition, type KindEdgeSpec, type KindJsonSchemaExport, type KindJsonSchemaOptions, type KindResolution, type KindSchema, type KindSchemaFromJsonResult, KindStorageError, type KindStorageShape, type KindStreamEvent, KindStreamParser, type KindStreamParserOptions, type KindTier, type KindVerdict, type LegResult, NODE_OUTCOME_KIND, type NodeOutcomeWrapper, type NormalizeJsonRegionOptions, ParseSession, type ParseSessionOptions, type PartialKindEvent, type PartialKindNode, type PartialKindState, type Punct, ROOT_STORAGE_NAME, RUN_RESULT_KIND, type RawObjectCause, type RecordValueType, type RegionEndReason, type RegionFormat, type RegionSourceKind, type RetractedKindEvent, type RunResultWrapper, type SavePlanEntry, type SavePlanValidation, type ScalarFieldType, type SchemaConversionResult, type SchemaLayoutMode, type SchemaResolver, type StoredFieldElement, type SupersededKindEvent, advancePartialKind, buildAgentSchemaWithRenderBlockSupport, buildCompliantKindSnapshot, classifyInboundEnvelopeMetadata, collectReferencedKinds, collectSchemaReferencedKinds, compareWithExistingKindSchema, convertAiSchemaToBlockFields, createFingerprinter, createKindStreamParser, describeDualGateFailure, disposeParseSession, emitPayloadFence, emitPayloadJson, emptyValueForFieldSchema, envelopeCacheFromEnvelopes, envelopeFromCompleteValue, fenceDiscriminator, fieldsToDbPayload, fingerprintText, formatBlockLabel, getParseSession, injectKindIntoObjectSchema, irPathIsUnderOrEqual, irPathKey, irPathLabel, irPathsEqual, isCanonicalBlockIR, isDuplicateBlockSlug, isEmptyResidue, isIrEnvelopeCache, isJsonAnyField, isProvisionalKind, isScalarArrayType, isTerminalKindEvent, kindSchemaFromJsonSchema, kindSchemaToJsonSchema, kindSchemaToStorage, kindVerdictOf, makePartialKindStalenessGate, mergeResidueIntoValue, normalizeAiSchemaInput, normalizeJsonRegion, openParseSession, readEnvelope, readNodeOutcomeValue, readObjectKind, readOutputRef, readPartialKindEvent, readRunResultValue, reconstructRegionValue, rehydrateNodeOutcome, rehydrateRunResult, reuseEnvelopeIfCurrent, runKindDualGate, runSchemaConversion, sanitizeInboundEnvelopeMetadata, sanitizeInboundPartialKindMetadata, scalarArrayItemType, schemaLayoutMode, schemaStructureDepth, setJsonRootKeyLookup, storageToKindSchema, stripKindDeep, validateBlockSchemaSavePlan, validateStructuralLeg, withRootKind, xmlDiscriminator };
package/dist/index.js CHANGED
@@ -3171,6 +3171,29 @@ function buildAgentSchemaWithRenderBlockSupport(input, rootKindSlug, arrayBindin
3171
3171
  }
3172
3172
  return updatedRoot;
3173
3173
  }
3174
+ function resolveRef(ref, ctx) {
3175
+ if (ref === "#" || ref === "#/") {
3176
+ return { slug: ctx.schemaName, node: ctx.rootSchema };
3177
+ }
3178
+ const match = /^#\/(?:\$defs|definitions)\/(.+)$/.exec(ref);
3179
+ if (!match) return null;
3180
+ const name = decodeURIComponent(
3181
+ (match[1] ?? "").replace(/~1/g, "/").replace(/~0/g, "~")
3182
+ );
3183
+ const node = ctx.defs[name];
3184
+ if (!isRecord4(node)) return null;
3185
+ const declared = isRecord4(node.properties) ? readBlockKindFromProperties(node.properties) : null;
3186
+ return { slug: declared ?? name, node };
3187
+ }
3188
+ function refToObjectField(resolved, path, ctx) {
3189
+ if (ctx.refsInProgress.has(resolved.slug)) return;
3190
+ ctx.refsInProgress.add(resolved.slug);
3191
+ try {
3192
+ registerDeclaredKindDraft(resolved.slug, resolved.node, path, ctx);
3193
+ } finally {
3194
+ ctx.refsInProgress.delete(resolved.slug);
3195
+ }
3196
+ }
3174
3197
  function isAnyValueSchema(node) {
3175
3198
  return node.type === void 0 && node.enum === void 0 && node.const === void 0 && node.properties === void 0 && node.items === void 0 && node.additionalProperties === void 0 && node.anyOf === void 0 && node.oneOf === void 0 && node.allOf === void 0 && node.$ref === void 0;
3176
3199
  }
@@ -3207,12 +3230,21 @@ function convertProperty(fieldName, node, required, path, ctx) {
3207
3230
  }
3208
3231
  function convertPropertyCore(fieldName, node, required, path, ctx) {
3209
3232
  if (typeof node.$ref === "string") {
3210
- ctx.problems.push({
3211
- severity: "error",
3212
- path,
3213
- message: `$ref is not supported ("${node.$ref}"). Inline the schema manually.`
3214
- });
3215
- return null;
3233
+ const resolved = resolveRef(node.$ref, ctx);
3234
+ if (!resolved) {
3235
+ ctx.problems.push({
3236
+ severity: "error",
3237
+ path,
3238
+ message: `Unresolvable $ref ("${node.$ref}") \u2014 only "#", "#/$defs/<name>" and "#/definitions/<name>" are supported.`
3239
+ });
3240
+ return null;
3241
+ }
3242
+ refToObjectField(resolved, path, ctx);
3243
+ return {
3244
+ ...requiredNullableFlags(required),
3245
+ type: "object",
3246
+ kind: resolved.slug
3247
+ };
3216
3248
  }
3217
3249
  if (Array.isArray(node.anyOf) || Array.isArray(node.oneOf)) {
3218
3250
  const variants = node.anyOf ?? node.oneOf;
@@ -3228,12 +3260,18 @@ function convertPropertyCore(fieldName, node, required, path, ctx) {
3228
3260
  continue;
3229
3261
  }
3230
3262
  if (typeof variant.$ref === "string") {
3231
- ctx.problems.push({
3232
- severity: "error",
3233
- path,
3234
- message: `$ref inside anyOf/oneOf is not supported ("${variant.$ref}"). Inline the schema manually.`
3235
- });
3236
- unsupported = true;
3263
+ const resolvedVariant = resolveRef(variant.$ref, ctx);
3264
+ if (!resolvedVariant) {
3265
+ ctx.problems.push({
3266
+ severity: "error",
3267
+ path,
3268
+ message: `Unresolvable $ref inside anyOf/oneOf ("${variant.$ref}").`
3269
+ });
3270
+ unsupported = true;
3271
+ continue;
3272
+ }
3273
+ refToObjectField(resolvedVariant, path, ctx);
3274
+ memberKinds.push(resolvedVariant.slug);
3237
3275
  continue;
3238
3276
  }
3239
3277
  const { type: type2, nullable: nullable2 } = resolvePrimaryType(variant);
@@ -3436,6 +3474,27 @@ function convertPropertyCore(fieldName, node, required, path, ctx) {
3436
3474
  });
3437
3475
  return null;
3438
3476
  }
3477
+ if (typeof itemNode.$ref === "string") {
3478
+ const resolvedItem = resolveRef(itemNode.$ref, ctx);
3479
+ if (!resolvedItem) {
3480
+ ctx.problems.push({
3481
+ severity: "error",
3482
+ path: `${path}[]`,
3483
+ message: `Unresolvable $ref in array items ("${itemNode.$ref}").`
3484
+ });
3485
+ return null;
3486
+ }
3487
+ refToObjectField(resolvedItem, `${path}[]`, ctx);
3488
+ ctx.arrayBindings.push({
3489
+ arrayField: fieldName,
3490
+ itemKindSlug: resolvedItem.slug
3491
+ });
3492
+ return {
3493
+ ...requiredNullableFlags(required, nullable),
3494
+ type: "array",
3495
+ itemKinds: [resolvedItem.slug]
3496
+ };
3497
+ }
3439
3498
  if (isAnyValueSchema(itemNode)) {
3440
3499
  return {
3441
3500
  ...requiredNullableFlags(required, nullable),
@@ -3470,11 +3529,29 @@ function convertPropertyCore(fieldName, node, required, path, ctx) {
3470
3529
  }
3471
3530
  const itemKinds = [];
3472
3531
  for (const variant of itemVariants) {
3532
+ if (isRecord4(variant) && typeof variant.$ref === "string") {
3533
+ const resolvedVariant = resolveRef(variant.$ref, ctx);
3534
+ if (!resolvedVariant) {
3535
+ ctx.problems.push({
3536
+ severity: "error",
3537
+ path: `${path}[]`,
3538
+ message: `Unresolvable $ref in array items anyOf ("${variant.$ref}").`
3539
+ });
3540
+ return null;
3541
+ }
3542
+ itemKinds.push(resolvedVariant.slug);
3543
+ refToObjectField(resolvedVariant, `${path}[]<${resolvedVariant.slug}>`, ctx);
3544
+ ctx.arrayBindings.push({
3545
+ arrayField: fieldName,
3546
+ itemKindSlug: resolvedVariant.slug
3547
+ });
3548
+ continue;
3549
+ }
3473
3550
  if (!isRecord4(variant) || !isRecord4(variant.properties)) {
3474
3551
  ctx.problems.push({
3475
3552
  severity: "error",
3476
3553
  path: `${path}[]`,
3477
- message: "Array items anyOf/oneOf variants must be inline objects declaring __kind."
3554
+ message: "Array items anyOf/oneOf variants must be inline objects declaring __kind, or $refs to defs."
3478
3555
  });
3479
3556
  return null;
3480
3557
  }
@@ -3608,6 +3685,14 @@ function convertPropertyCore(fieldName, node, required, path, ctx) {
3608
3685
  kind: referencedKind
3609
3686
  };
3610
3687
  }
3688
+ if (Object.keys(nestedFields).length === 0 && !apIsOpen && isRecord4(ap) && KIND_KEY in node.properties) {
3689
+ const apType = resolvePrimaryType(ap).type;
3690
+ return {
3691
+ ...requiredNullableFlags(required, nullable),
3692
+ type: "record",
3693
+ values: apType === "string" || apType === "number" || apType === "boolean" ? apType : "json"
3694
+ };
3695
+ }
3611
3696
  let open = apIsOpen;
3612
3697
  if (!apIsOpen && isRecord4(ap)) {
3613
3698
  ctx.problems.push({
@@ -3724,12 +3809,21 @@ function normalizeAiSchemaInput(input) {
3724
3809
  return { name: null, strict: null, rootSchema: null, parseErrors };
3725
3810
  }
3726
3811
  function convertAiSchemaToBlockFields(schemaName, rootSchema, strict) {
3812
+ const rawDefs = isRecord4(rootSchema.$defs) ? rootSchema.$defs : isRecord4(rootSchema.definitions) ? rootSchema.definitions : {};
3813
+ const defs = {};
3814
+ for (const [name, node] of Object.entries(rawDefs)) {
3815
+ if (isRecord4(node)) defs[name] = node;
3816
+ }
3727
3817
  const ctx = {
3728
3818
  schemaName,
3819
+ strict,
3729
3820
  problems: [],
3730
3821
  droppedMetadata: [],
3731
3822
  blockSchemas: [],
3732
- arrayBindings: []
3823
+ arrayBindings: [],
3824
+ defs,
3825
+ rootSchema,
3826
+ refsInProgress: /* @__PURE__ */ new Set()
3733
3827
  };
3734
3828
  ctx.droppedMetadata.push(...collectDropped(rootSchema, ""));
3735
3829
  const rootAp = rootSchema.additionalProperties;
@@ -4195,6 +4289,41 @@ function kindSchemaToJsonSchema(kind, resolve, options = {}) {
4195
4289
  return { name: kind, schema: { ...rootNode, $defs: defs }, strict, unresolved };
4196
4290
  }
4197
4291
 
4292
+ // convert/json-schema-to-kind.ts
4293
+ function kindSchemaFromJsonSchema(kind, jsonSchema) {
4294
+ if (jsonSchema === null || jsonSchema === void 0) {
4295
+ return { schema: null, children: {}, problems: [] };
4296
+ }
4297
+ const normalized = normalizeAiSchemaInput(jsonSchema);
4298
+ const rootSchema = normalized.rootSchema ?? (typeof jsonSchema === "object" && !Array.isArray(jsonSchema) ? jsonSchema : null);
4299
+ if (!rootSchema) {
4300
+ return {
4301
+ schema: null,
4302
+ children: {},
4303
+ problems: [
4304
+ {
4305
+ severity: "error",
4306
+ path: "",
4307
+ message: `Kind "${kind}": emitted_json_schema is not a JSON object.`
4308
+ }
4309
+ ]
4310
+ };
4311
+ }
4312
+ const converted = convertAiSchemaToBlockFields(kind, rootSchema, false);
4313
+ let schema = null;
4314
+ const children = {};
4315
+ for (const draft of converted.blockSchemas) {
4316
+ const asKindSchema = {
4317
+ kind: draft.slug,
4318
+ fields: draft.fields,
4319
+ ...draft.root ? { root: draft.root } : {}
4320
+ };
4321
+ if (draft.slug === kind) schema = asKindSchema;
4322
+ else children[draft.slug] = asKindSchema;
4323
+ }
4324
+ return { schema, children, problems: converted.problems };
4325
+ }
4326
+
4198
4327
  // wire/partial-kind.ts
4199
4328
  var IR_PARTIAL_KEY = "__ir_partial";
4200
4329
  var PARTIAL_STATES = [
@@ -4477,6 +4606,6 @@ function emitPayloadFence(kind, value) {
4477
4606
  return "```json\n" + emitPayloadJson(kind, value) + "\n```";
4478
4607
  }
4479
4608
 
4480
- export { IR_ENVELOPE_CACHE_VERSION, IR_ENVELOPE_KEY, IR_PARTIAL_KEY, IR_VERSION, IrTree, JSON_DISCRIMINATOR, JsonStreamTokenizer, KIND_KEY, KindStorageError, KindStreamParser, NODE_OUTCOME_KIND, ParseSession, ROOT_STORAGE_NAME, RUN_RESULT_KIND, advancePartialKind, buildAgentSchemaWithRenderBlockSupport, buildCompliantKindSnapshot, classifyInboundEnvelopeMetadata, collectReferencedKinds, collectSchemaReferencedKinds, compareWithExistingKindSchema, convertAiSchemaToBlockFields, createFingerprinter, createKindStreamParser, describeDualGateFailure, disposeParseSession, emitPayloadFence, emitPayloadJson, emptyValueForFieldSchema, envelopeCacheFromEnvelopes, envelopeFromCompleteValue, fenceDiscriminator, fieldsToDbPayload, fingerprintText, formatBlockLabel, getParseSession, injectKindIntoObjectSchema, irPathIsUnderOrEqual, irPathKey, irPathLabel, irPathsEqual, isCanonicalBlockIR, isDuplicateBlockSlug, isEmptyResidue, isIrEnvelopeCache, isJsonAnyField, isProvisionalKind, isScalarArrayType, isTerminalKindEvent, kindSchemaToJsonSchema, kindSchemaToStorage, kindVerdictOf, makePartialKindStalenessGate, mergeResidueIntoValue, normalizeAiSchemaInput, normalizeJsonRegion, openParseSession, readEnvelope, readNodeOutcomeValue, readObjectKind, readOutputRef, readPartialKindEvent, readRunResultValue, reconstructRegionValue, rehydrateNodeOutcome, rehydrateRunResult, reuseEnvelopeIfCurrent, runKindDualGate, runSchemaConversion, sanitizeInboundEnvelopeMetadata, sanitizeInboundPartialKindMetadata, scalarArrayItemType, schemaLayoutMode, schemaStructureDepth, setJsonRootKeyLookup, storageToKindSchema, stripKindDeep, validateBlockSchemaSavePlan, validateStructuralLeg, withRootKind, xmlDiscriminator };
4609
+ export { IR_ENVELOPE_CACHE_VERSION, IR_ENVELOPE_KEY, IR_PARTIAL_KEY, IR_VERSION, IrTree, JSON_DISCRIMINATOR, JsonStreamTokenizer, KIND_KEY, KindStorageError, KindStreamParser, NODE_OUTCOME_KIND, ParseSession, ROOT_STORAGE_NAME, RUN_RESULT_KIND, advancePartialKind, buildAgentSchemaWithRenderBlockSupport, buildCompliantKindSnapshot, classifyInboundEnvelopeMetadata, collectReferencedKinds, collectSchemaReferencedKinds, compareWithExistingKindSchema, convertAiSchemaToBlockFields, createFingerprinter, createKindStreamParser, describeDualGateFailure, disposeParseSession, emitPayloadFence, emitPayloadJson, emptyValueForFieldSchema, envelopeCacheFromEnvelopes, envelopeFromCompleteValue, fenceDiscriminator, fieldsToDbPayload, fingerprintText, formatBlockLabel, getParseSession, injectKindIntoObjectSchema, irPathIsUnderOrEqual, irPathKey, irPathLabel, irPathsEqual, isCanonicalBlockIR, isDuplicateBlockSlug, isEmptyResidue, isIrEnvelopeCache, isJsonAnyField, isProvisionalKind, isScalarArrayType, isTerminalKindEvent, kindSchemaFromJsonSchema, kindSchemaToJsonSchema, kindSchemaToStorage, kindVerdictOf, makePartialKindStalenessGate, mergeResidueIntoValue, normalizeAiSchemaInput, normalizeJsonRegion, openParseSession, readEnvelope, readNodeOutcomeValue, readObjectKind, readOutputRef, readPartialKindEvent, readRunResultValue, reconstructRegionValue, rehydrateNodeOutcome, rehydrateRunResult, reuseEnvelopeIfCurrent, runKindDualGate, runSchemaConversion, sanitizeInboundEnvelopeMetadata, sanitizeInboundPartialKindMetadata, scalarArrayItemType, schemaLayoutMode, schemaStructureDepth, setJsonRootKeyLookup, storageToKindSchema, stripKindDeep, validateBlockSchemaSavePlan, validateStructuralLeg, withRootKind, xmlDiscriminator };
4481
4610
  //# sourceMappingURL=index.js.map
4482
4611
  //# sourceMappingURL=index.js.map