@llui/vite-plugin 0.0.38 → 0.0.40

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.
@@ -1 +1 @@
1
- {"version":3,"file":"msg-schema.d.ts","sourceRoot":"","sources":["../src/msg-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAA;AAE3B;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,YAAY,GACpB,MAAM,GACN;IAAE,IAAI,EAAE,aAAa,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GACxC;IACE,IAAI,EAAE,qBAAqB,CAAA;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;CACnD,CAAA;AAEL;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,YAAY,CAAA;IAClB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB;sCACkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,YAAY,CAAA;AAElD,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;CACnD;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,IAAI,YAAY,CAE1D;AAED,0DAA0D;AAC1D,wBAAgB,SAAS,CAAC,CAAC,EAAE,QAAQ,GAAG,YAAY,CAEnD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAc,GAAG,SAAS,GAAG,IAAI,CAE3F;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAiB,GAAG,SAAS,GAAG,IAAI,CAEjG;AAqBD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,GAAG,EAAE,CAAC,oBAAoB,CAAC,CAAA;AAsD1E;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,EAAE,CAAC,iBAAiB,EAC5B,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,SAAqB,GAC/B,QAAQ,CAwBV;AAyVD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,EAAE,CAAC,QAAQ,EACjB,SAAS,GAAE,SAAqB,EAChC,KAAK,SAAkB,GACtB,YAAY,CA8Hd"}
1
+ {"version":3,"file":"msg-schema.d.ts","sourceRoot":"","sources":["../src/msg-schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAA;AAE3B;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,YAAY,GACpB,MAAM,GACN;IAAE,IAAI,EAAE,aAAa,CAAC,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC,CAAA;CAAE,GAClD;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,YAAY,CAAA;CAAE,GACxC;IACE,IAAI,EAAE,qBAAqB,CAAA;IAC3B,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;CACnD,CAAA;AAEL;;;;;;;GAOG;AACH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,YAAY,CAAA;IAClB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAA;IACnB;sCACkC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb;;;;;;;;;;;;;;;;;OAiBG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,MAAM,MAAM,QAAQ,GAAG,YAAY,GAAG,YAAY,CAAA;AAElD,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAA;CACnD;AAED,mEAAmE;AACnE,wBAAgB,WAAW,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,IAAI,YAAY,CAE1D;AAED,0DAA0D;AAC1D,wBAAgB,SAAS,CAAC,CAAC,EAAE,QAAQ,GAAG,YAAY,CAEnD;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAc,GAAG,SAAS,GAAG,IAAI,CAE3F;AAED,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAE,MAAiB,GAAG,SAAS,GAAG,IAAI,CAEjG;AAqBD;;;;;;;;;;GAUG;AACH,MAAM,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,EAAE,EAAE,CAAC,QAAQ,GAAG,EAAE,CAAC,oBAAoB,CAAC,CAAA;AAsD1E;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,EAAE,CAAC,iBAAiB,EAC5B,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,SAAqB,GAC/B,QAAQ,CAwBV;AAmVD,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,EAAE,CAAC,QAAQ,EACjB,SAAS,GAAE,SAAqB,EAChC,KAAK,SAAkB,GACtB,YAAY,CA8Hd"}
@@ -313,13 +313,7 @@ function tryExtractDiscriminatedUnion(union, typeIndex, depth) {
313
313
  const name = member.name.text;
314
314
  if (name === discriminant)
315
315
  continue;
316
- const peeled = member.type ? peelOptionalUnion(member.type) : null;
317
- const innerType = peeled?.type ?? member.type;
318
- const baseType = innerType
319
- ? resolveFieldType(innerType, typeIndex, depth)
320
- : 'unknown';
321
- const optional = member.questionToken !== undefined || peeled?.isImplicitOptional === true;
322
- fields[name] = optional ? { type: baseType, optional: true } : baseType;
316
+ fields[name] = resolveMember(member, typeIndex, depth);
323
317
  }
324
318
  variants[value] = fields;
325
319
  }
@@ -584,24 +578,50 @@ export function resolveFieldType(type, typeIndex = new Map(), depth = MAX_FIELD_
584
578
  }
585
579
  return 'unknown';
586
580
  }
581
+ /**
582
+ * Resolve a single property signature to a MsgField. Centralised
583
+ * here so every nested call site (interface members, inline-object
584
+ * members, DU variant fields) picks up the same `T | undefined` peel
585
+ * rules AND reads `@should` / `@validates` JSDoc. Before this helper
586
+ * existed, JSDoc was only honored on top-level Msg variant fields
587
+ * via `buildFieldDescriptor` — annotations on `interface
588
+ * Alternative.image` etc. were silently dropped, so domain types
589
+ * couldn't carry guidance for the agent.
590
+ *
591
+ * Source for the JSDoc reader is recovered from the member's own
592
+ * SourceFile, which means cross-file types (interfaces imported from
593
+ * another package) carry their JSDoc through transparently.
594
+ */
595
+ function resolveMember(member, typeIndex, depth) {
596
+ const peeled = member.type ? peelOptionalUnion(member.type) : null;
597
+ const innerType = peeled?.type ?? member.type;
598
+ const baseType = innerType
599
+ ? resolveFieldType(innerType, typeIndex, depth)
600
+ : 'unknown';
601
+ const optional = member.questionToken !== undefined || peeled?.isImplicitOptional === true;
602
+ const sourceText = member.getSourceFile().text;
603
+ const jsdoc = readMemberJSDoc(sourceText, member);
604
+ const hint = readShouldHint(jsdoc);
605
+ const validates = readValidatesTag(jsdoc);
606
+ if (!optional && hint === null && validates === null)
607
+ return baseType;
608
+ const rich = { type: baseType };
609
+ if (optional)
610
+ rich.optional = true;
611
+ if (hint !== null) {
612
+ rich.priority = 'should';
613
+ rich.hint = hint;
614
+ }
615
+ if (validates !== null)
616
+ rich.validates = validates;
617
+ return rich;
618
+ }
587
619
  function collectInlineShape(lit, typeIndex, depth) {
588
620
  const shape = {};
589
621
  for (const member of lit.members) {
590
622
  if (!ts.isPropertySignature(member) || !member.name || !ts.isIdentifier(member.name))
591
623
  continue;
592
- const name = member.name.text;
593
- const peeled = member.type ? peelOptionalUnion(member.type) : null;
594
- const innerType = peeled?.type ?? member.type;
595
- const baseType = innerType
596
- ? resolveFieldType(innerType, typeIndex, depth)
597
- : 'unknown';
598
- const optional = member.questionToken !== undefined || peeled?.isImplicitOptional === true;
599
- if (!optional) {
600
- shape[name] = baseType;
601
- }
602
- else {
603
- shape[name] = { type: baseType, optional: true };
604
- }
624
+ shape[member.name.text] = resolveMember(member, typeIndex, depth);
605
625
  }
606
626
  return shape;
607
627
  }
@@ -610,19 +630,7 @@ function collectInterfaceShape(iface, typeIndex, depth) {
610
630
  for (const member of iface.members) {
611
631
  if (!ts.isPropertySignature(member) || !member.name || !ts.isIdentifier(member.name))
612
632
  continue;
613
- const name = member.name.text;
614
- const peeled = member.type ? peelOptionalUnion(member.type) : null;
615
- const innerType = peeled?.type ?? member.type;
616
- const baseType = innerType
617
- ? resolveFieldType(innerType, typeIndex, depth)
618
- : 'unknown';
619
- const optional = member.questionToken !== undefined || peeled?.isImplicitOptional === true;
620
- if (!optional) {
621
- shape[name] = baseType;
622
- }
623
- else {
624
- shape[name] = { type: baseType, optional: true };
625
- }
633
+ shape[member.name.text] = resolveMember(member, typeIndex, depth);
626
634
  }
627
635
  return shape;
628
636
  }
@@ -1 +1 @@
1
- {"version":3,"file":"msg-schema.js","sourceRoot":"","sources":["../src/msg-schema.ts"],"names":[],"mappings":"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","sourcesContent":["import ts from 'typescript'\n\n/**\n * The \"bare type\" of a field. Covers five cases:\n * - primitive keyword as a string: `'string'`, `'number'`, `'boolean'`, `'unknown'`\n * - literal union: `{enum: ['a', 'b']}` for strings, `{enum: [1, 2, 3]}`\n * for numbers, `{enum: [true]}` for booleans. Mixed-type literal\n * unions stay `'unknown'`.\n * - nested object shape: `{kind: 'object', shape: {...}}` — emitted when\n * a field's type is a local interface/type alias the extractor could\n * follow (depth-limited; cross-file references stay `'unknown'`).\n * - array of element type: `{kind: 'array', element: <bare type>}`.\n * - discriminated union of objects: `{kind: 'discriminated-union',\n * discriminant: 'kind', variants: {a: {...}, b: {...}}}`. Emitted\n * when every member of a union is an object literal sharing one\n * literal-string property name with distinct values. Symmetric with\n * how the top-level Msg union itself is encoded — same shape,\n * recursed.\n *\n * The synthesizer in `@llui/agent`'s `list_actions` walks these to build\n * copy-paste-ready payload examples; the validator in `send_message`\n * walks them too (treating object/array as \"any\" since deep validation\n * is the reducer's job).\n */\nexport type MsgFieldType =\n | string\n | { enum: ReadonlyArray<string | number | boolean> }\n | { kind: 'object'; shape: Record<string, MsgField> }\n | { kind: 'array'; element: MsgFieldType }\n | {\n kind: 'discriminated-union'\n discriminant: string\n variants: Record<string, Record<string, MsgField>>\n }\n\n/**\n * Rich per-field descriptor. Emitted only when there's something\n * beyond the bare type to communicate — optionality, an explicit\n * priority hint, a freeform agent hint, or a runtime validation\n * predicate. When everything but `type` is unset, the producer emits\n * the bare `MsgFieldType` instead so variants without annotations\n * stay byte-cheap in the bundle.\n */\nexport interface MsgFieldRich {\n type: MsgFieldType\n /** Mirrors TypeScript's `?:` optional marker. Required fields omit this. */\n optional?: boolean\n /**\n * Strength signal for optional fields. Borrows RFC 2119's `SHOULD`:\n * the LLM ought to fill it in unless it has a specific reason not\n * to. Required fields don't carry a priority — TS already conveys\n * \"must\" via the type system. Currently the only level; future\n * extensions could add `'recommended'` or similar.\n */\n priority?: 'should'\n /** Freeform consequence-shaped explanation. Surfaced verbatim to\n * the LLM at affordance time. */\n hint?: string\n /**\n * Boolean JS expression that must hold for the field's value to be\n * accepted. The expression has `v` bound to the field's runtime\n * value; everything else is global (Math, JSON, RegExp, etc.).\n * Authored as `@validates(\"expr\")` JSDoc — the compiler captures\n * the source string verbatim and the validator compiles it lazily\n * with `new Function`, caching across calls.\n *\n * Examples:\n * @validates(\"v >= 0 && v <= 100\") // weight 0–100\n * @validates(\"v.length > 0\") // non-empty string\n * @validates(\"/^[a-z0-9-]+$/.test(v)\") // slug format\n *\n * The predicate runs ONLY at the agent boundary. Human-driven\n * dispatches bypass it because TypeScript already validated the\n * call site. Use for invariants the type system can't express\n * (numeric ranges, format predicates, length bounds).\n */\n validates?: string\n}\n\nexport type MsgField = MsgFieldType | MsgFieldRich\n\nexport interface MsgSchema {\n discriminant: string\n variants: Record<string, Record<string, MsgField>>\n}\n\n/** True when `f` is a rich descriptor (object with `type` key). */\nexport function isRichField(f: MsgField): f is MsgFieldRich {\n return typeof f === 'object' && f !== null && !Array.isArray(f) && 'type' in f\n}\n\n/** Extracts the bare type from either descriptor form. */\nexport function fieldType(f: MsgField): MsgFieldType {\n return isRichField(f) ? f.type : f\n}\n\nexport function extractMsgSchema(source: string, typeName: string = 'Msg'): MsgSchema | null {\n return extractDiscriminatedUnionSchema(source, typeName)\n}\n\nexport function extractEffectSchema(source: string, typeName: string = 'Effect'): MsgSchema | null {\n return extractDiscriminatedUnionSchema(source, typeName)\n}\n\nfunction extractDiscriminatedUnionSchema(source: string, typeName: string): MsgSchema | null {\n const sf = ts.createSourceFile('input.ts', source, ts.ScriptTarget.Latest, true)\n const typeIndex = buildTypeIndex(sf)\n\n for (const stmt of sf.statements) {\n if (!ts.isTypeAliasDeclaration(stmt)) continue\n if (stmt.name.text !== typeName) continue\n\n const variants: MsgSchema['variants'] = {}\n collectVariants(stmt.type, variants, source, typeIndex)\n\n if (Object.keys(variants).length === 0) return null\n\n return { discriminant: 'type', variants }\n }\n\n return null\n}\n\n/**\n * Index of type aliases and interfaces visible from a source file,\n * keyed by name. Lets the field-type resolver follow `Criterion[]` →\n * `interface Criterion { … }` and emit a nested object shape rather\n * than `'unknown'`.\n *\n * The cross-file resolver pipeline (`cross-file-resolver.ts`) builds\n * an enriched index that includes types imported from sibling files —\n * follow `GridSorting` → `'rank' | 'crit-X' | 'crit-Y'` → `{enum: […]}`\n * even when the alias lives in `./state.ts` not the Msg-defining file.\n */\nexport type TypeIndex = Map<string, ts.TypeNode | ts.InterfaceDeclaration>\n\nfunction buildTypeIndex(sf: ts.SourceFile): TypeIndex {\n const index: TypeIndex = new Map()\n for (const stmt of sf.statements) {\n if (ts.isTypeAliasDeclaration(stmt)) {\n index.set(stmt.name.text, stmt.type)\n } else if (ts.isInterfaceDeclaration(stmt)) {\n index.set(stmt.name.text, stmt)\n }\n }\n return index\n}\n\nfunction collectVariants(\n type: ts.TypeNode,\n variants: MsgSchema['variants'],\n source: string,\n typeIndex: TypeIndex,\n): void {\n if (ts.isUnionTypeNode(type)) {\n for (const member of type.types) {\n collectVariants(member, variants, source, typeIndex)\n }\n return\n }\n\n if (ts.isTypeLiteralNode(type)) {\n let discriminantValue: string | null = null\n const fields: Record<string, MsgField> = {}\n\n for (const member of type.members) {\n if (!ts.isPropertySignature(member) || !member.name || !ts.isIdentifier(member.name)) continue\n\n const name = member.name.text\n const memberType = member.type\n\n if (name === 'type' && memberType) {\n // Extract the discriminant value\n if (ts.isLiteralTypeNode(memberType) && ts.isStringLiteral(memberType.literal)) {\n discriminantValue = memberType.literal.text\n }\n continue\n }\n\n fields[name] = buildFieldDescriptor(member, source, typeIndex)\n }\n\n if (discriminantValue) {\n variants[discriminantValue] = fields\n }\n }\n}\n\n/**\n * Build a single field descriptor from a property signature: type,\n * optionality, and any `@should(\"…\")` JSDoc hint. Emits the compact\n * bare form when there's nothing extra to communicate; otherwise the\n * rich `{type, optional?, priority?, hint?}` shape.\n *\n * Exported so the cross-file resolver (which walks the same property\n * signatures when the Msg type lives in a different file from the\n * `component()` call) can produce identical descriptors. Without\n * sharing this helper, JSDoc hints would silently disappear whenever\n * a Msg union got resolved across module boundaries.\n */\nexport function buildFieldDescriptor(\n member: ts.PropertySignature,\n source: string,\n typeIndex: TypeIndex = new Map(),\n): MsgField {\n const peeled = member.type ? peelOptionalUnion(member.type) : null\n const innerType = peeled?.type ?? member.type\n const baseType: MsgFieldType = innerType\n ? resolveFieldType(innerType, typeIndex, MAX_FIELD_DEPTH)\n : 'unknown'\n const optional = member.questionToken !== undefined || peeled?.isImplicitOptional === true\n const jsdoc = readMemberJSDoc(source, member)\n const hint = readShouldHint(jsdoc)\n const validates = readValidatesTag(jsdoc)\n\n if (!optional && hint === null && validates === null) {\n return baseType\n }\n const rich: MsgFieldRich = { type: baseType }\n if (optional) rich.optional = true\n if (hint !== null) {\n rich.priority = 'should'\n rich.hint = hint\n }\n if (validates !== null) {\n rich.validates = validates\n }\n return rich\n}\n\n/**\n * Detect `T | undefined` (or `undefined | T`, or `T1 | T2 | undefined`)\n * and return the union without the `undefined` branch plus a flag\n * marking the field as implicitly optional. Mirrors the runtime\n * semantics: `field: T | undefined` is exactly equivalent to\n * `field?: T` — the agent should be able to omit the field entirely.\n *\n * Pre-strict-null codebases (decisive among them) declare optional\n * fields as `field: T | undefined` rather than `field?: T`. Without\n * this peel, the union doesn't match `tryExtractLiteralUnion` (one\n * branch isn't a literal) or `tryExtractDiscriminatedUnion` (the\n * `undefined` branch isn't an object literal), so the whole thing\n * collapses to `'unknown'` and the agent has to spell out\n * `field: undefined` literally on every payload.\n *\n * Returns the original node and `isImplicitOptional: false` when the\n * union has no `undefined` branch — caller then resolves it via the\n * normal pipeline. Returns the original node and `false` when ALL\n * branches are `undefined` (pathological — let it fall through to\n * unknown rather than fabricating a shape).\n */\nfunction peelOptionalUnion(type: ts.TypeNode): {\n type: ts.TypeNode\n isImplicitOptional: boolean\n} {\n if (!ts.isUnionTypeNode(type)) return { type, isImplicitOptional: false }\n const isUndefined = (t: ts.TypeNode): boolean => t.kind === ts.SyntaxKind.UndefinedKeyword\n const nonUndefined = type.types.filter((t) => !isUndefined(t))\n if (nonUndefined.length === type.types.length) return { type, isImplicitOptional: false }\n if (nonUndefined.length === 0) return { type, isImplicitOptional: false }\n if (nonUndefined.length === 1 && nonUndefined[0]) {\n return { type: nonUndefined[0], isImplicitOptional: true }\n }\n // 'a' | 'b' | undefined → rebuild as 'a' | 'b' so it can run through\n // tryExtractLiteralUnion / tryExtractDiscriminatedUnion as if the\n // undefined branch had never been there.\n return {\n type: ts.factory.createUnionTypeNode(nonUndefined),\n isImplicitOptional: true,\n }\n}\n\n/**\n * Recursion bound for nested type resolution. Stops the extractor\n * before it spirals on self-referential or mutually-recursive types\n * (`type Tree = { children: Tree[] }`).\n *\n * Only NAMED-TYPE LOOKUPS decrement this budget — chasing\n * `type Foo = …` through the typeIndex, or expanding an\n * `interface X` reference. Inline structural traversal (array\n * elements, inline object literals, inline discriminated unions) is\n * free, since cycles can only re-enter resolution via a named\n * reference. This means a deeply-nested but finite type tree like\n * `Matrix/AddCriteria.criteria[].type(quantity).clamp` (5+ inline\n * hops, 3 named-type hops: Criterion → CriterionType → Clamp) fully\n * resolves rather than collapsing to `'unknown'` half-way through.\n *\n * 5 named-type hops is plenty for production Msg payloads. Cyclic\n * named types still terminate via the decrement-and-bail rule.\n */\nconst MAX_FIELD_DEPTH = 5\n\n/**\n * Detect literal-only unions whose members all share one primitive\n * type — `'a' | 'b' | 'c'`, `1 | 2 | 3`, or `true | false`. Returns\n * the enum descriptor on success; null if any member isn't a literal\n * of the same type as the others.\n *\n * Mixed-type unions (`'a' | 1`) and unions that include non-literal\n * members fall through. The agent gets `'unknown'` for those rather\n * than an enum that loses the type information mid-list.\n */\nfunction tryExtractLiteralUnion(\n union: ts.UnionTypeNode,\n): { enum: Array<string | number | boolean> } | null {\n const values: Array<string | number | boolean> = []\n let kind: 'string' | 'number' | 'boolean' | null = null\n\n for (const member of union.types) {\n if (!ts.isLiteralTypeNode(member)) return null\n const lit = member.literal\n if (ts.isStringLiteral(lit)) {\n if (kind === null) kind = 'string'\n else if (kind !== 'string') return null\n values.push(lit.text)\n } else if (ts.isNumericLiteral(lit)) {\n if (kind === null) kind = 'number'\n else if (kind !== 'number') return null\n const n = Number(lit.text)\n if (!Number.isFinite(n)) return null\n values.push(n)\n } else if (lit.kind === ts.SyntaxKind.TrueKeyword) {\n if (kind === null) kind = 'boolean'\n else if (kind !== 'boolean') return null\n values.push(true)\n } else if (lit.kind === ts.SyntaxKind.FalseKeyword) {\n if (kind === null) kind = 'boolean'\n else if (kind !== 'boolean') return null\n values.push(false)\n } else {\n return null\n }\n }\n\n if (values.length === 0) return null\n return { enum: values }\n}\n\n/**\n * Detect a discriminated union of object types — every member is an\n * object literal (or named type alias resolving to one) and every\n * member declares the same property as a string-literal type with a\n * value distinct from every other member's. Examples:\n *\n * {kind:'a'} | {kind:'b', x:number} → discriminant 'kind'\n * {tag:'x',v:1} | {tag:'y',v:'s'} → discriminant 'tag'\n *\n * Returns the union descriptor on success; null on any failure\n * (different shape per branch, no shared discriminant key, non-literal\n * discriminant value, primitive member, etc.). Bailing to null lets\n * the caller emit `'unknown'` rather than a partially-valid descriptor.\n *\n * `depth` is the budget for resolving each branch's payload. The\n * caller subtracts one before calling, since detecting the union\n * itself doesn't consume budget — recursing into branches does.\n */\nfunction tryExtractDiscriminatedUnion(\n union: ts.UnionTypeNode,\n typeIndex: TypeIndex,\n depth: number,\n): {\n kind: 'discriminated-union'\n discriminant: string\n variants: Record<string, Record<string, MsgField>>\n} | null {\n // Resolve each branch to its underlying object literal node, chasing\n // through type-alias references in the local index. Returns null if\n // any branch isn't an object-literal-shaped type.\n const branches: ts.TypeLiteralNode[] = []\n for (const member of union.types) {\n const lit = resolveToTypeLiteral(member, typeIndex)\n if (lit === null) return null\n branches.push(lit)\n }\n if (branches.length === 0) return null\n\n // Find a property name that EVERY branch declares with a string-\n // literal value, and where the values are pairwise distinct.\n // Iterate over the first branch's properties; for each candidate\n // name, check the rest.\n const first = branches[0]\n if (!first) return null\n let discriminant: string | null = null\n let firstBranchValue: string | null = null\n for (const member of first.members) {\n if (!ts.isPropertySignature(member) || !member.name || !ts.isIdentifier(member.name)) continue\n if (!member.type) continue\n if (!ts.isLiteralTypeNode(member.type) || !ts.isStringLiteral(member.type.literal)) continue\n const candidate = member.name.text\n\n const valuesByBranch: string[] = [member.type.literal.text]\n let ok = true\n for (let i = 1; i < branches.length; i++) {\n const branch = branches[i]\n if (!branch) {\n ok = false\n break\n }\n const otherValue = literalDiscriminantValue(branch, candidate)\n if (otherValue === null) {\n ok = false\n break\n }\n valuesByBranch.push(otherValue)\n }\n if (!ok) continue\n\n // All distinct?\n const uniq = new Set(valuesByBranch)\n if (uniq.size !== valuesByBranch.length) continue\n\n discriminant = candidate\n firstBranchValue = member.type.literal.text\n break\n }\n\n if (discriminant === null || firstBranchValue === null) return null\n\n // Build the variant payload map. Each variant's payload is the\n // branch's properties EXCEPT the discriminant itself (which the\n // synthesizer re-adds at example time, like the top-level Msg `type`).\n const variants: Record<string, Record<string, MsgField>> = {}\n for (const branch of branches) {\n const value = literalDiscriminantValue(branch, discriminant)\n if (value === null) return null\n const fields: Record<string, MsgField> = {}\n for (const member of branch.members) {\n if (!ts.isPropertySignature(member) || !member.name || !ts.isIdentifier(member.name)) continue\n const name = member.name.text\n if (name === discriminant) continue\n const peeled = member.type ? peelOptionalUnion(member.type) : null\n const innerType = peeled?.type ?? member.type\n const baseType: MsgFieldType = innerType\n ? resolveFieldType(innerType, typeIndex, depth)\n : 'unknown'\n const optional = member.questionToken !== undefined || peeled?.isImplicitOptional === true\n fields[name] = optional ? { type: baseType, optional: true } : baseType\n }\n variants[value] = fields\n }\n\n return { kind: 'discriminated-union', discriminant, variants }\n}\n\n/**\n * Resolve a type node down to an inline object-literal type node,\n * following one level of named-reference indirection through the local\n * index. Returns null when the type isn't (or can't be reduced to) an\n * object literal. We only chase one hop because every additional hop\n * needs a depth budget to terminate, and discriminated-union detection\n * is bounded by the outer caller's budget already.\n */\nfunction resolveToTypeLiteral(t: ts.TypeNode, typeIndex: TypeIndex): ts.TypeLiteralNode | null {\n if (ts.isTypeLiteralNode(t)) return t\n if (ts.isTypeReferenceNode(t) && ts.isIdentifier(t.typeName)) {\n const target = typeIndex.get(t.typeName.text)\n if (!target) return null\n if (ts.isInterfaceDeclaration(target)) {\n // Synthesize a TypeLiteralNode-like shape from the interface\n // members. Cheaper than reconstructing the AST: we only need\n // the members to drive collectInlineShape semantics, but the\n // discriminated-union detector reads property signatures, which\n // interfaces have directly. We shim via a property-list view.\n return interfaceToTypeLiteralLike(target)\n }\n if (ts.isTypeNode(target)) {\n // Type alias: recurse one level.\n return resolveToTypeLiteral(target, typeIndex)\n }\n }\n return null\n}\n\n/**\n * Adapter for interface declarations: discriminated-union detection\n * and field iteration only need the members list, which both\n * `TypeLiteralNode` and `InterfaceDeclaration` expose. We return the\n * interface cast as a TypeLiteralNode-shaped object so the rest of\n * this file's helpers (which check `ts.isPropertySignature(member)`)\n * work uniformly across both node kinds.\n */\nfunction interfaceToTypeLiteralLike(iface: ts.InterfaceDeclaration): ts.TypeLiteralNode {\n return { members: iface.members } as unknown as ts.TypeLiteralNode\n}\n\n/**\n * Detect a branded-primitive intersection — `string & {__brand: B}`,\n * `number & {readonly __brand: 'UID'}`, etc. Returns the underlying\n * primitive keyword on success; null when the intersection isn't this\n * shape.\n *\n * Conventional encodings recognised:\n * string & {__brand: T} // type-fest's basic brand\n * string & { __brand: 'UID' } // hand-rolled\n * number & { readonly __brand } // readonly form\n *\n * Branches:\n * - Exactly one primitive-keyword member (StringKeyword, NumberKeyword,\n * BooleanKeyword) — the runtime base type.\n * - One or more TypeLiteralNode members whose every property is a\n * `__brand`-prefixed marker. Other property names disqualify (the\n * intersection is mixing in real fields, not a brand).\n */\nfunction tryExtractBrandedPrimitive(intersection: ts.IntersectionTypeNode): MsgFieldType | null {\n let primitive: 'string' | 'number' | 'boolean' | null = null\n let sawBrandTag = false\n\n for (const member of intersection.types) {\n if (member.kind === ts.SyntaxKind.StringKeyword) {\n if (primitive !== null) return null\n primitive = 'string'\n continue\n }\n if (member.kind === ts.SyntaxKind.NumberKeyword) {\n if (primitive !== null) return null\n primitive = 'number'\n continue\n }\n if (member.kind === ts.SyntaxKind.BooleanKeyword) {\n if (primitive !== null) return null\n primitive = 'boolean'\n continue\n }\n if (ts.isTypeLiteralNode(member)) {\n // Every property in this literal must look like a brand marker\n // (`__brand`, `__type`, etc. — anything starting with `__`). If\n // a real-named field appears, this isn't a brand intersection.\n let onlyBrandFields = true\n let hasField = false\n for (const prop of member.members) {\n if (!ts.isPropertySignature(prop) || !prop.name) continue\n hasField = true\n const propName = ts.isIdentifier(prop.name)\n ? prop.name.text\n : ts.isStringLiteral(prop.name)\n ? prop.name.text\n : ''\n if (!propName.startsWith('__')) {\n onlyBrandFields = false\n break\n }\n }\n if (!onlyBrandFields || !hasField) return null\n sawBrandTag = true\n continue\n }\n // Any other member shape (e.g. another intersection, generic\n // reference, etc.) — bail to be conservative.\n return null\n }\n\n if (primitive === null || !sawBrandTag) return null\n return primitive\n}\n\n/**\n * Read a string-literal property value from an object-literal-like\n * member list, or null if the named property isn't present, isn't a\n * property signature, or isn't typed as a string literal.\n */\nfunction literalDiscriminantValue(lit: ts.TypeLiteralNode, name: string): string | null {\n for (const member of lit.members) {\n if (!ts.isPropertySignature(member) || !member.name || !ts.isIdentifier(member.name)) continue\n if (member.name.text !== name) continue\n if (!member.type) return null\n if (ts.isLiteralTypeNode(member.type) && ts.isStringLiteral(member.type.literal)) {\n return member.type.literal.text\n }\n return null\n }\n return null\n}\n\nexport function resolveFieldType(\n type: ts.TypeNode,\n typeIndex: TypeIndex = new Map(),\n depth = MAX_FIELD_DEPTH,\n): MsgFieldType {\n // Primitive keywords\n if (type.kind === ts.SyntaxKind.StringKeyword) return 'string'\n if (type.kind === ts.SyntaxKind.NumberKeyword) return 'number'\n if (type.kind === ts.SyntaxKind.BooleanKeyword) return 'boolean'\n\n // Standalone literal type — `flag: true` or `value: 5`. Single-value\n // enum so the schema records the constant rather than collapsing it\n // to 'unknown'. Useful for sentinel discriminants outside discriminated\n // unions (e.g. `kind: 'always-this-one'` on a non-union type).\n if (ts.isLiteralTypeNode(type)) {\n const lit = type.literal\n if (ts.isStringLiteral(lit)) return { enum: [lit.text] }\n if (ts.isNumericLiteral(lit)) {\n const n = Number(lit.text)\n return Number.isFinite(n) ? { enum: [n] } : 'unknown'\n }\n if (lit.kind === ts.SyntaxKind.TrueKeyword) return { enum: [true] }\n if (lit.kind === ts.SyntaxKind.FalseKeyword) return { enum: [false] }\n }\n\n // Union of literals — 'a' | 'b' (strings), 1 | 2 | 3 (numbers), or\n // true / false (booleans). Mixed-type unions ('a' | 1) bail to\n // 'unknown' — the LLM can't reason about that shape from the schema\n // alone, so we'd rather not emit a misleading enum than enumerate\n // the values without their types.\n if (ts.isUnionTypeNode(type)) {\n const enumResult = tryExtractLiteralUnion(type)\n if (enumResult !== null) return enumResult\n\n // Discriminated union of object literals. Inline structural move\n // — depth budget unchanged. Only named-type lookups decrement.\n const discResult = tryExtractDiscriminatedUnion(type, typeIndex, depth)\n if (discResult !== null) return discResult\n }\n\n // Branded primitive intersection — `string & {__brand: B}`,\n // `number & {__brand: 'UID'}`, etc. The brand tag is a TS-only\n // distinction that doesn't survive into runtime; from the\n // validator's POV the value is just the underlying primitive. We\n // unwrap to the primitive so the schema records the right runtime\n // shape rather than collapsing to `'unknown'`.\n //\n // Heuristic: any IntersectionTypeNode where exactly one member is\n // a primitive keyword and every other member is a TypeLiteralNode\n // (the brand tag, conventionally `{__brand: …}` or\n // `{readonly __brand: …}`). Real-world brands also use the form\n // `Opaque<string, 'UID'>` from libraries like type-fest — those\n // resolve via the typeIndex and are handled in the named-reference\n // branch below.\n if (ts.isIntersectionTypeNode(type)) {\n const brandResult = tryExtractBrandedPrimitive(type)\n if (brandResult !== null) return brandResult\n }\n\n // Inline object literal — `{a: number; b: string}` directly.\n // Inline structural move; depth unchanged.\n if (ts.isTypeLiteralNode(type)) {\n return { kind: 'object', shape: collectInlineShape(type, typeIndex, depth) }\n }\n\n // Array type — `T[]` and `readonly T[]`. Inline structural move.\n if (ts.isArrayTypeNode(type)) {\n return { kind: 'array', element: resolveFieldType(type.elementType, typeIndex, depth) }\n }\n // Generic Array<T> (less common in app code but compiler may produce it).\n if (\n ts.isTypeReferenceNode(type) &&\n ts.isIdentifier(type.typeName) &&\n type.typeName.text === 'Array' &&\n type.typeArguments?.length === 1 &&\n type.typeArguments[0]\n ) {\n return {\n kind: 'array',\n element: resolveFieldType(type.typeArguments[0], typeIndex, depth),\n }\n }\n // ReadonlyArray<T> → same shape; the readonly modifier is purely a\n // TypeScript-side concern that the agent never observes at runtime.\n if (\n ts.isTypeReferenceNode(type) &&\n ts.isIdentifier(type.typeName) &&\n type.typeName.text === 'ReadonlyArray' &&\n type.typeArguments?.length === 1 &&\n type.typeArguments[0]\n ) {\n return {\n kind: 'array',\n element: resolveFieldType(type.typeArguments[0], typeIndex, depth),\n }\n }\n // `readonly T[]` parses as TypeOperator(readonly) wrapping ArrayType.\n if (ts.isTypeOperatorNode(type) && type.operator === ts.SyntaxKind.ReadonlyKeyword) {\n return resolveFieldType(type.type, typeIndex, depth)\n }\n\n // Named type reference — chase it through the local index. This is\n // the ONLY recursive step that consumes depth budget. Inline moves\n // (array element, inline object/DU/union) traverse for free; the\n // budget exists to break cycles in mutually-recursive named types\n // (`Tree.children: Tree[]`), which can only re-enter resolution via\n // a named lookup.\n if (ts.isTypeReferenceNode(type) && ts.isIdentifier(type.typeName)) {\n if (depth <= 0) return 'unknown'\n const target = typeIndex.get(type.typeName.text)\n if (target) {\n if (ts.isInterfaceDeclaration(target)) {\n return {\n kind: 'object',\n shape: collectInterfaceShape(target, typeIndex, depth - 1),\n }\n }\n // Type alias — recurse on its body. `type Foo = …` could resolve\n // to anything (object literal, array, union, primitive); each\n // already has its own branch above.\n return resolveFieldType(target, typeIndex, depth - 1)\n }\n // Reference to a type the index doesn't know about — typically\n // imported from another module. Cross-file resolution is the\n // separate cross-file-resolver pipeline's job; leave this as\n // unknown rather than fabricating a misleading shape.\n return 'unknown'\n }\n\n return 'unknown'\n}\n\nfunction collectInlineShape(\n lit: ts.TypeLiteralNode,\n typeIndex: TypeIndex,\n depth: number,\n): Record<string, MsgField> {\n const shape: Record<string, MsgField> = {}\n for (const member of lit.members) {\n if (!ts.isPropertySignature(member) || !member.name || !ts.isIdentifier(member.name)) continue\n const name = member.name.text\n const peeled = member.type ? peelOptionalUnion(member.type) : null\n const innerType = peeled?.type ?? member.type\n const baseType: MsgFieldType = innerType\n ? resolveFieldType(innerType, typeIndex, depth)\n : 'unknown'\n const optional = member.questionToken !== undefined || peeled?.isImplicitOptional === true\n if (!optional) {\n shape[name] = baseType\n } else {\n shape[name] = { type: baseType, optional: true }\n }\n }\n return shape\n}\n\nfunction collectInterfaceShape(\n iface: ts.InterfaceDeclaration,\n typeIndex: TypeIndex,\n depth: number,\n): Record<string, MsgField> {\n const shape: Record<string, MsgField> = {}\n for (const member of iface.members) {\n if (!ts.isPropertySignature(member) || !member.name || !ts.isIdentifier(member.name)) continue\n const name = member.name.text\n const peeled = member.type ? peelOptionalUnion(member.type) : null\n const innerType = peeled?.type ?? member.type\n const baseType: MsgFieldType = innerType\n ? resolveFieldType(innerType, typeIndex, depth)\n : 'unknown'\n const optional = member.questionToken !== undefined || peeled?.isImplicitOptional === true\n if (!optional) {\n shape[name] = baseType\n } else {\n shape[name] = { type: baseType, optional: true }\n }\n }\n return shape\n}\n\n/**\n * Read the leading JSDoc block immediately above `member`. The\n * TypeScript parser doesn't attach JSDoc to interior property\n * signatures, so we re-scan the source between the previous member's\n * end (or the type-literal's `{`) and this member's start, and return\n * the last `/** … *\\/` block found there. Returns `''` when none.\n */\nfunction readMemberJSDoc(source: string, member: ts.PropertySignature): string {\n const ranges = ts.getLeadingCommentRanges(source, member.pos) ?? []\n // Walk in order, keeping only `/** */` blocks. Multiple back-to-back\n // JSDocs concatenate (matches msg-annotations.ts's existing behavior).\n const docs = ranges\n .filter((r) => r.kind === ts.SyntaxKind.MultiLineCommentTrivia)\n .map((r) => source.slice(r.pos, r.end))\n .filter((txt) => txt.startsWith('/**'))\n return docs.join('\\n')\n}\n\n/**\n * Match `@should(\"…\")` (and curly-quote variant) anywhere in the\n * JSDoc. Mirrors msg-annotations.ts's `@intent` parser — same grammar,\n * same tolerance for either ASCII or curly quotes.\n *\n * Returns the unescaped string content, or null when the tag is\n * absent or malformed.\n */\nfunction readShouldHint(comment: string): string | null {\n if (!comment) return null\n const match = comment.match(/@should\\s*\\(\\s*[\"“]([^\"”]*)[\"”]\\s*\\)/)\n return match?.[1] ?? null\n}\n\n/**\n * Match `@validates(\"predicate-expression\")` (and curly-quote variant)\n * anywhere in the JSDoc. Returns the verbatim predicate string —\n * runtime validator compiles it with `new Function('v', 'return (' +\n * src + ')')`. Quote characters inside the predicate must be escaped\n * as the predicate runs through a regex match; for predicates that\n * need embedded quotes, use a regex literal or a named character class.\n */\nfunction readValidatesTag(comment: string): string | null {\n if (!comment) return null\n const match = comment.match(/@validates\\s*\\(\\s*[\"“]([^\"”]*)[\"”]\\s*\\)/)\n return match?.[1] ?? null\n}\n"]}
1
+ {"version":3,"file":"msg-schema.js","sourceRoot":"","sources":["../src/msg-schema.ts"],"names":[],"mappings":"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","sourcesContent":["import ts from 'typescript'\n\n/**\n * The \"bare type\" of a field. Covers five cases:\n * - primitive keyword as a string: `'string'`, `'number'`, `'boolean'`, `'unknown'`\n * - literal union: `{enum: ['a', 'b']}` for strings, `{enum: [1, 2, 3]}`\n * for numbers, `{enum: [true]}` for booleans. Mixed-type literal\n * unions stay `'unknown'`.\n * - nested object shape: `{kind: 'object', shape: {...}}` — emitted when\n * a field's type is a local interface/type alias the extractor could\n * follow (depth-limited; cross-file references stay `'unknown'`).\n * - array of element type: `{kind: 'array', element: <bare type>}`.\n * - discriminated union of objects: `{kind: 'discriminated-union',\n * discriminant: 'kind', variants: {a: {...}, b: {...}}}`. Emitted\n * when every member of a union is an object literal sharing one\n * literal-string property name with distinct values. Symmetric with\n * how the top-level Msg union itself is encoded — same shape,\n * recursed.\n *\n * The synthesizer in `@llui/agent`'s `list_actions` walks these to build\n * copy-paste-ready payload examples; the validator in `send_message`\n * walks them too (treating object/array as \"any\" since deep validation\n * is the reducer's job).\n */\nexport type MsgFieldType =\n | string\n | { enum: ReadonlyArray<string | number | boolean> }\n | { kind: 'object'; shape: Record<string, MsgField> }\n | { kind: 'array'; element: MsgFieldType }\n | {\n kind: 'discriminated-union'\n discriminant: string\n variants: Record<string, Record<string, MsgField>>\n }\n\n/**\n * Rich per-field descriptor. Emitted only when there's something\n * beyond the bare type to communicate — optionality, an explicit\n * priority hint, a freeform agent hint, or a runtime validation\n * predicate. When everything but `type` is unset, the producer emits\n * the bare `MsgFieldType` instead so variants without annotations\n * stay byte-cheap in the bundle.\n */\nexport interface MsgFieldRich {\n type: MsgFieldType\n /** Mirrors TypeScript's `?:` optional marker. Required fields omit this. */\n optional?: boolean\n /**\n * Strength signal for optional fields. Borrows RFC 2119's `SHOULD`:\n * the LLM ought to fill it in unless it has a specific reason not\n * to. Required fields don't carry a priority — TS already conveys\n * \"must\" via the type system. Currently the only level; future\n * extensions could add `'recommended'` or similar.\n */\n priority?: 'should'\n /** Freeform consequence-shaped explanation. Surfaced verbatim to\n * the LLM at affordance time. */\n hint?: string\n /**\n * Boolean JS expression that must hold for the field's value to be\n * accepted. The expression has `v` bound to the field's runtime\n * value; everything else is global (Math, JSON, RegExp, etc.).\n * Authored as `@validates(\"expr\")` JSDoc — the compiler captures\n * the source string verbatim and the validator compiles it lazily\n * with `new Function`, caching across calls.\n *\n * Examples:\n * @validates(\"v >= 0 && v <= 100\") // weight 0–100\n * @validates(\"v.length > 0\") // non-empty string\n * @validates(\"/^[a-z0-9-]+$/.test(v)\") // slug format\n *\n * The predicate runs ONLY at the agent boundary. Human-driven\n * dispatches bypass it because TypeScript already validated the\n * call site. Use for invariants the type system can't express\n * (numeric ranges, format predicates, length bounds).\n */\n validates?: string\n}\n\nexport type MsgField = MsgFieldType | MsgFieldRich\n\nexport interface MsgSchema {\n discriminant: string\n variants: Record<string, Record<string, MsgField>>\n}\n\n/** True when `f` is a rich descriptor (object with `type` key). */\nexport function isRichField(f: MsgField): f is MsgFieldRich {\n return typeof f === 'object' && f !== null && !Array.isArray(f) && 'type' in f\n}\n\n/** Extracts the bare type from either descriptor form. */\nexport function fieldType(f: MsgField): MsgFieldType {\n return isRichField(f) ? f.type : f\n}\n\nexport function extractMsgSchema(source: string, typeName: string = 'Msg'): MsgSchema | null {\n return extractDiscriminatedUnionSchema(source, typeName)\n}\n\nexport function extractEffectSchema(source: string, typeName: string = 'Effect'): MsgSchema | null {\n return extractDiscriminatedUnionSchema(source, typeName)\n}\n\nfunction extractDiscriminatedUnionSchema(source: string, typeName: string): MsgSchema | null {\n const sf = ts.createSourceFile('input.ts', source, ts.ScriptTarget.Latest, true)\n const typeIndex = buildTypeIndex(sf)\n\n for (const stmt of sf.statements) {\n if (!ts.isTypeAliasDeclaration(stmt)) continue\n if (stmt.name.text !== typeName) continue\n\n const variants: MsgSchema['variants'] = {}\n collectVariants(stmt.type, variants, source, typeIndex)\n\n if (Object.keys(variants).length === 0) return null\n\n return { discriminant: 'type', variants }\n }\n\n return null\n}\n\n/**\n * Index of type aliases and interfaces visible from a source file,\n * keyed by name. Lets the field-type resolver follow `Criterion[]` →\n * `interface Criterion { … }` and emit a nested object shape rather\n * than `'unknown'`.\n *\n * The cross-file resolver pipeline (`cross-file-resolver.ts`) builds\n * an enriched index that includes types imported from sibling files —\n * follow `GridSorting` → `'rank' | 'crit-X' | 'crit-Y'` → `{enum: […]}`\n * even when the alias lives in `./state.ts` not the Msg-defining file.\n */\nexport type TypeIndex = Map<string, ts.TypeNode | ts.InterfaceDeclaration>\n\nfunction buildTypeIndex(sf: ts.SourceFile): TypeIndex {\n const index: TypeIndex = new Map()\n for (const stmt of sf.statements) {\n if (ts.isTypeAliasDeclaration(stmt)) {\n index.set(stmt.name.text, stmt.type)\n } else if (ts.isInterfaceDeclaration(stmt)) {\n index.set(stmt.name.text, stmt)\n }\n }\n return index\n}\n\nfunction collectVariants(\n type: ts.TypeNode,\n variants: MsgSchema['variants'],\n source: string,\n typeIndex: TypeIndex,\n): void {\n if (ts.isUnionTypeNode(type)) {\n for (const member of type.types) {\n collectVariants(member, variants, source, typeIndex)\n }\n return\n }\n\n if (ts.isTypeLiteralNode(type)) {\n let discriminantValue: string | null = null\n const fields: Record<string, MsgField> = {}\n\n for (const member of type.members) {\n if (!ts.isPropertySignature(member) || !member.name || !ts.isIdentifier(member.name)) continue\n\n const name = member.name.text\n const memberType = member.type\n\n if (name === 'type' && memberType) {\n // Extract the discriminant value\n if (ts.isLiteralTypeNode(memberType) && ts.isStringLiteral(memberType.literal)) {\n discriminantValue = memberType.literal.text\n }\n continue\n }\n\n fields[name] = buildFieldDescriptor(member, source, typeIndex)\n }\n\n if (discriminantValue) {\n variants[discriminantValue] = fields\n }\n }\n}\n\n/**\n * Build a single field descriptor from a property signature: type,\n * optionality, and any `@should(\"…\")` JSDoc hint. Emits the compact\n * bare form when there's nothing extra to communicate; otherwise the\n * rich `{type, optional?, priority?, hint?}` shape.\n *\n * Exported so the cross-file resolver (which walks the same property\n * signatures when the Msg type lives in a different file from the\n * `component()` call) can produce identical descriptors. Without\n * sharing this helper, JSDoc hints would silently disappear whenever\n * a Msg union got resolved across module boundaries.\n */\nexport function buildFieldDescriptor(\n member: ts.PropertySignature,\n source: string,\n typeIndex: TypeIndex = new Map(),\n): MsgField {\n const peeled = member.type ? peelOptionalUnion(member.type) : null\n const innerType = peeled?.type ?? member.type\n const baseType: MsgFieldType = innerType\n ? resolveFieldType(innerType, typeIndex, MAX_FIELD_DEPTH)\n : 'unknown'\n const optional = member.questionToken !== undefined || peeled?.isImplicitOptional === true\n const jsdoc = readMemberJSDoc(source, member)\n const hint = readShouldHint(jsdoc)\n const validates = readValidatesTag(jsdoc)\n\n if (!optional && hint === null && validates === null) {\n return baseType\n }\n const rich: MsgFieldRich = { type: baseType }\n if (optional) rich.optional = true\n if (hint !== null) {\n rich.priority = 'should'\n rich.hint = hint\n }\n if (validates !== null) {\n rich.validates = validates\n }\n return rich\n}\n\n/**\n * Detect `T | undefined` (or `undefined | T`, or `T1 | T2 | undefined`)\n * and return the union without the `undefined` branch plus a flag\n * marking the field as implicitly optional. Mirrors the runtime\n * semantics: `field: T | undefined` is exactly equivalent to\n * `field?: T` — the agent should be able to omit the field entirely.\n *\n * Pre-strict-null codebases (decisive among them) declare optional\n * fields as `field: T | undefined` rather than `field?: T`. Without\n * this peel, the union doesn't match `tryExtractLiteralUnion` (one\n * branch isn't a literal) or `tryExtractDiscriminatedUnion` (the\n * `undefined` branch isn't an object literal), so the whole thing\n * collapses to `'unknown'` and the agent has to spell out\n * `field: undefined` literally on every payload.\n *\n * Returns the original node and `isImplicitOptional: false` when the\n * union has no `undefined` branch — caller then resolves it via the\n * normal pipeline. Returns the original node and `false` when ALL\n * branches are `undefined` (pathological — let it fall through to\n * unknown rather than fabricating a shape).\n */\nfunction peelOptionalUnion(type: ts.TypeNode): {\n type: ts.TypeNode\n isImplicitOptional: boolean\n} {\n if (!ts.isUnionTypeNode(type)) return { type, isImplicitOptional: false }\n const isUndefined = (t: ts.TypeNode): boolean => t.kind === ts.SyntaxKind.UndefinedKeyword\n const nonUndefined = type.types.filter((t) => !isUndefined(t))\n if (nonUndefined.length === type.types.length) return { type, isImplicitOptional: false }\n if (nonUndefined.length === 0) return { type, isImplicitOptional: false }\n if (nonUndefined.length === 1 && nonUndefined[0]) {\n return { type: nonUndefined[0], isImplicitOptional: true }\n }\n // 'a' | 'b' | undefined → rebuild as 'a' | 'b' so it can run through\n // tryExtractLiteralUnion / tryExtractDiscriminatedUnion as if the\n // undefined branch had never been there.\n return {\n type: ts.factory.createUnionTypeNode(nonUndefined),\n isImplicitOptional: true,\n }\n}\n\n/**\n * Recursion bound for nested type resolution. Stops the extractor\n * before it spirals on self-referential or mutually-recursive types\n * (`type Tree = { children: Tree[] }`).\n *\n * Only NAMED-TYPE LOOKUPS decrement this budget — chasing\n * `type Foo = …` through the typeIndex, or expanding an\n * `interface X` reference. Inline structural traversal (array\n * elements, inline object literals, inline discriminated unions) is\n * free, since cycles can only re-enter resolution via a named\n * reference. This means a deeply-nested but finite type tree like\n * `Matrix/AddCriteria.criteria[].type(quantity).clamp` (5+ inline\n * hops, 3 named-type hops: Criterion → CriterionType → Clamp) fully\n * resolves rather than collapsing to `'unknown'` half-way through.\n *\n * 5 named-type hops is plenty for production Msg payloads. Cyclic\n * named types still terminate via the decrement-and-bail rule.\n */\nconst MAX_FIELD_DEPTH = 5\n\n/**\n * Detect literal-only unions whose members all share one primitive\n * type — `'a' | 'b' | 'c'`, `1 | 2 | 3`, or `true | false`. Returns\n * the enum descriptor on success; null if any member isn't a literal\n * of the same type as the others.\n *\n * Mixed-type unions (`'a' | 1`) and unions that include non-literal\n * members fall through. The agent gets `'unknown'` for those rather\n * than an enum that loses the type information mid-list.\n */\nfunction tryExtractLiteralUnion(\n union: ts.UnionTypeNode,\n): { enum: Array<string | number | boolean> } | null {\n const values: Array<string | number | boolean> = []\n let kind: 'string' | 'number' | 'boolean' | null = null\n\n for (const member of union.types) {\n if (!ts.isLiteralTypeNode(member)) return null\n const lit = member.literal\n if (ts.isStringLiteral(lit)) {\n if (kind === null) kind = 'string'\n else if (kind !== 'string') return null\n values.push(lit.text)\n } else if (ts.isNumericLiteral(lit)) {\n if (kind === null) kind = 'number'\n else if (kind !== 'number') return null\n const n = Number(lit.text)\n if (!Number.isFinite(n)) return null\n values.push(n)\n } else if (lit.kind === ts.SyntaxKind.TrueKeyword) {\n if (kind === null) kind = 'boolean'\n else if (kind !== 'boolean') return null\n values.push(true)\n } else if (lit.kind === ts.SyntaxKind.FalseKeyword) {\n if (kind === null) kind = 'boolean'\n else if (kind !== 'boolean') return null\n values.push(false)\n } else {\n return null\n }\n }\n\n if (values.length === 0) return null\n return { enum: values }\n}\n\n/**\n * Detect a discriminated union of object types — every member is an\n * object literal (or named type alias resolving to one) and every\n * member declares the same property as a string-literal type with a\n * value distinct from every other member's. Examples:\n *\n * {kind:'a'} | {kind:'b', x:number} → discriminant 'kind'\n * {tag:'x',v:1} | {tag:'y',v:'s'} → discriminant 'tag'\n *\n * Returns the union descriptor on success; null on any failure\n * (different shape per branch, no shared discriminant key, non-literal\n * discriminant value, primitive member, etc.). Bailing to null lets\n * the caller emit `'unknown'` rather than a partially-valid descriptor.\n *\n * `depth` is the budget for resolving each branch's payload. The\n * caller subtracts one before calling, since detecting the union\n * itself doesn't consume budget — recursing into branches does.\n */\nfunction tryExtractDiscriminatedUnion(\n union: ts.UnionTypeNode,\n typeIndex: TypeIndex,\n depth: number,\n): {\n kind: 'discriminated-union'\n discriminant: string\n variants: Record<string, Record<string, MsgField>>\n} | null {\n // Resolve each branch to its underlying object literal node, chasing\n // through type-alias references in the local index. Returns null if\n // any branch isn't an object-literal-shaped type.\n const branches: ts.TypeLiteralNode[] = []\n for (const member of union.types) {\n const lit = resolveToTypeLiteral(member, typeIndex)\n if (lit === null) return null\n branches.push(lit)\n }\n if (branches.length === 0) return null\n\n // Find a property name that EVERY branch declares with a string-\n // literal value, and where the values are pairwise distinct.\n // Iterate over the first branch's properties; for each candidate\n // name, check the rest.\n const first = branches[0]\n if (!first) return null\n let discriminant: string | null = null\n let firstBranchValue: string | null = null\n for (const member of first.members) {\n if (!ts.isPropertySignature(member) || !member.name || !ts.isIdentifier(member.name)) continue\n if (!member.type) continue\n if (!ts.isLiteralTypeNode(member.type) || !ts.isStringLiteral(member.type.literal)) continue\n const candidate = member.name.text\n\n const valuesByBranch: string[] = [member.type.literal.text]\n let ok = true\n for (let i = 1; i < branches.length; i++) {\n const branch = branches[i]\n if (!branch) {\n ok = false\n break\n }\n const otherValue = literalDiscriminantValue(branch, candidate)\n if (otherValue === null) {\n ok = false\n break\n }\n valuesByBranch.push(otherValue)\n }\n if (!ok) continue\n\n // All distinct?\n const uniq = new Set(valuesByBranch)\n if (uniq.size !== valuesByBranch.length) continue\n\n discriminant = candidate\n firstBranchValue = member.type.literal.text\n break\n }\n\n if (discriminant === null || firstBranchValue === null) return null\n\n // Build the variant payload map. Each variant's payload is the\n // branch's properties EXCEPT the discriminant itself (which the\n // synthesizer re-adds at example time, like the top-level Msg `type`).\n const variants: Record<string, Record<string, MsgField>> = {}\n for (const branch of branches) {\n const value = literalDiscriminantValue(branch, discriminant)\n if (value === null) return null\n const fields: Record<string, MsgField> = {}\n for (const member of branch.members) {\n if (!ts.isPropertySignature(member) || !member.name || !ts.isIdentifier(member.name)) continue\n const name = member.name.text\n if (name === discriminant) continue\n fields[name] = resolveMember(member, typeIndex, depth)\n }\n variants[value] = fields\n }\n\n return { kind: 'discriminated-union', discriminant, variants }\n}\n\n/**\n * Resolve a type node down to an inline object-literal type node,\n * following one level of named-reference indirection through the local\n * index. Returns null when the type isn't (or can't be reduced to) an\n * object literal. We only chase one hop because every additional hop\n * needs a depth budget to terminate, and discriminated-union detection\n * is bounded by the outer caller's budget already.\n */\nfunction resolveToTypeLiteral(t: ts.TypeNode, typeIndex: TypeIndex): ts.TypeLiteralNode | null {\n if (ts.isTypeLiteralNode(t)) return t\n if (ts.isTypeReferenceNode(t) && ts.isIdentifier(t.typeName)) {\n const target = typeIndex.get(t.typeName.text)\n if (!target) return null\n if (ts.isInterfaceDeclaration(target)) {\n // Synthesize a TypeLiteralNode-like shape from the interface\n // members. Cheaper than reconstructing the AST: we only need\n // the members to drive collectInlineShape semantics, but the\n // discriminated-union detector reads property signatures, which\n // interfaces have directly. We shim via a property-list view.\n return interfaceToTypeLiteralLike(target)\n }\n if (ts.isTypeNode(target)) {\n // Type alias: recurse one level.\n return resolveToTypeLiteral(target, typeIndex)\n }\n }\n return null\n}\n\n/**\n * Adapter for interface declarations: discriminated-union detection\n * and field iteration only need the members list, which both\n * `TypeLiteralNode` and `InterfaceDeclaration` expose. We return the\n * interface cast as a TypeLiteralNode-shaped object so the rest of\n * this file's helpers (which check `ts.isPropertySignature(member)`)\n * work uniformly across both node kinds.\n */\nfunction interfaceToTypeLiteralLike(iface: ts.InterfaceDeclaration): ts.TypeLiteralNode {\n return { members: iface.members } as unknown as ts.TypeLiteralNode\n}\n\n/**\n * Detect a branded-primitive intersection — `string & {__brand: B}`,\n * `number & {readonly __brand: 'UID'}`, etc. Returns the underlying\n * primitive keyword on success; null when the intersection isn't this\n * shape.\n *\n * Conventional encodings recognised:\n * string & {__brand: T} // type-fest's basic brand\n * string & { __brand: 'UID' } // hand-rolled\n * number & { readonly __brand } // readonly form\n *\n * Branches:\n * - Exactly one primitive-keyword member (StringKeyword, NumberKeyword,\n * BooleanKeyword) — the runtime base type.\n * - One or more TypeLiteralNode members whose every property is a\n * `__brand`-prefixed marker. Other property names disqualify (the\n * intersection is mixing in real fields, not a brand).\n */\nfunction tryExtractBrandedPrimitive(intersection: ts.IntersectionTypeNode): MsgFieldType | null {\n let primitive: 'string' | 'number' | 'boolean' | null = null\n let sawBrandTag = false\n\n for (const member of intersection.types) {\n if (member.kind === ts.SyntaxKind.StringKeyword) {\n if (primitive !== null) return null\n primitive = 'string'\n continue\n }\n if (member.kind === ts.SyntaxKind.NumberKeyword) {\n if (primitive !== null) return null\n primitive = 'number'\n continue\n }\n if (member.kind === ts.SyntaxKind.BooleanKeyword) {\n if (primitive !== null) return null\n primitive = 'boolean'\n continue\n }\n if (ts.isTypeLiteralNode(member)) {\n // Every property in this literal must look like a brand marker\n // (`__brand`, `__type`, etc. — anything starting with `__`). If\n // a real-named field appears, this isn't a brand intersection.\n let onlyBrandFields = true\n let hasField = false\n for (const prop of member.members) {\n if (!ts.isPropertySignature(prop) || !prop.name) continue\n hasField = true\n const propName = ts.isIdentifier(prop.name)\n ? prop.name.text\n : ts.isStringLiteral(prop.name)\n ? prop.name.text\n : ''\n if (!propName.startsWith('__')) {\n onlyBrandFields = false\n break\n }\n }\n if (!onlyBrandFields || !hasField) return null\n sawBrandTag = true\n continue\n }\n // Any other member shape (e.g. another intersection, generic\n // reference, etc.) — bail to be conservative.\n return null\n }\n\n if (primitive === null || !sawBrandTag) return null\n return primitive\n}\n\n/**\n * Read a string-literal property value from an object-literal-like\n * member list, or null if the named property isn't present, isn't a\n * property signature, or isn't typed as a string literal.\n */\nfunction literalDiscriminantValue(lit: ts.TypeLiteralNode, name: string): string | null {\n for (const member of lit.members) {\n if (!ts.isPropertySignature(member) || !member.name || !ts.isIdentifier(member.name)) continue\n if (member.name.text !== name) continue\n if (!member.type) return null\n if (ts.isLiteralTypeNode(member.type) && ts.isStringLiteral(member.type.literal)) {\n return member.type.literal.text\n }\n return null\n }\n return null\n}\n\nexport function resolveFieldType(\n type: ts.TypeNode,\n typeIndex: TypeIndex = new Map(),\n depth = MAX_FIELD_DEPTH,\n): MsgFieldType {\n // Primitive keywords\n if (type.kind === ts.SyntaxKind.StringKeyword) return 'string'\n if (type.kind === ts.SyntaxKind.NumberKeyword) return 'number'\n if (type.kind === ts.SyntaxKind.BooleanKeyword) return 'boolean'\n\n // Standalone literal type — `flag: true` or `value: 5`. Single-value\n // enum so the schema records the constant rather than collapsing it\n // to 'unknown'. Useful for sentinel discriminants outside discriminated\n // unions (e.g. `kind: 'always-this-one'` on a non-union type).\n if (ts.isLiteralTypeNode(type)) {\n const lit = type.literal\n if (ts.isStringLiteral(lit)) return { enum: [lit.text] }\n if (ts.isNumericLiteral(lit)) {\n const n = Number(lit.text)\n return Number.isFinite(n) ? { enum: [n] } : 'unknown'\n }\n if (lit.kind === ts.SyntaxKind.TrueKeyword) return { enum: [true] }\n if (lit.kind === ts.SyntaxKind.FalseKeyword) return { enum: [false] }\n }\n\n // Union of literals — 'a' | 'b' (strings), 1 | 2 | 3 (numbers), or\n // true / false (booleans). Mixed-type unions ('a' | 1) bail to\n // 'unknown' — the LLM can't reason about that shape from the schema\n // alone, so we'd rather not emit a misleading enum than enumerate\n // the values without their types.\n if (ts.isUnionTypeNode(type)) {\n const enumResult = tryExtractLiteralUnion(type)\n if (enumResult !== null) return enumResult\n\n // Discriminated union of object literals. Inline structural move\n // — depth budget unchanged. Only named-type lookups decrement.\n const discResult = tryExtractDiscriminatedUnion(type, typeIndex, depth)\n if (discResult !== null) return discResult\n }\n\n // Branded primitive intersection — `string & {__brand: B}`,\n // `number & {__brand: 'UID'}`, etc. The brand tag is a TS-only\n // distinction that doesn't survive into runtime; from the\n // validator's POV the value is just the underlying primitive. We\n // unwrap to the primitive so the schema records the right runtime\n // shape rather than collapsing to `'unknown'`.\n //\n // Heuristic: any IntersectionTypeNode where exactly one member is\n // a primitive keyword and every other member is a TypeLiteralNode\n // (the brand tag, conventionally `{__brand: …}` or\n // `{readonly __brand: …}`). Real-world brands also use the form\n // `Opaque<string, 'UID'>` from libraries like type-fest — those\n // resolve via the typeIndex and are handled in the named-reference\n // branch below.\n if (ts.isIntersectionTypeNode(type)) {\n const brandResult = tryExtractBrandedPrimitive(type)\n if (brandResult !== null) return brandResult\n }\n\n // Inline object literal — `{a: number; b: string}` directly.\n // Inline structural move; depth unchanged.\n if (ts.isTypeLiteralNode(type)) {\n return { kind: 'object', shape: collectInlineShape(type, typeIndex, depth) }\n }\n\n // Array type — `T[]` and `readonly T[]`. Inline structural move.\n if (ts.isArrayTypeNode(type)) {\n return { kind: 'array', element: resolveFieldType(type.elementType, typeIndex, depth) }\n }\n // Generic Array<T> (less common in app code but compiler may produce it).\n if (\n ts.isTypeReferenceNode(type) &&\n ts.isIdentifier(type.typeName) &&\n type.typeName.text === 'Array' &&\n type.typeArguments?.length === 1 &&\n type.typeArguments[0]\n ) {\n return {\n kind: 'array',\n element: resolveFieldType(type.typeArguments[0], typeIndex, depth),\n }\n }\n // ReadonlyArray<T> → same shape; the readonly modifier is purely a\n // TypeScript-side concern that the agent never observes at runtime.\n if (\n ts.isTypeReferenceNode(type) &&\n ts.isIdentifier(type.typeName) &&\n type.typeName.text === 'ReadonlyArray' &&\n type.typeArguments?.length === 1 &&\n type.typeArguments[0]\n ) {\n return {\n kind: 'array',\n element: resolveFieldType(type.typeArguments[0], typeIndex, depth),\n }\n }\n // `readonly T[]` parses as TypeOperator(readonly) wrapping ArrayType.\n if (ts.isTypeOperatorNode(type) && type.operator === ts.SyntaxKind.ReadonlyKeyword) {\n return resolveFieldType(type.type, typeIndex, depth)\n }\n\n // Named type reference — chase it through the local index. This is\n // the ONLY recursive step that consumes depth budget. Inline moves\n // (array element, inline object/DU/union) traverse for free; the\n // budget exists to break cycles in mutually-recursive named types\n // (`Tree.children: Tree[]`), which can only re-enter resolution via\n // a named lookup.\n if (ts.isTypeReferenceNode(type) && ts.isIdentifier(type.typeName)) {\n if (depth <= 0) return 'unknown'\n const target = typeIndex.get(type.typeName.text)\n if (target) {\n if (ts.isInterfaceDeclaration(target)) {\n return {\n kind: 'object',\n shape: collectInterfaceShape(target, typeIndex, depth - 1),\n }\n }\n // Type alias — recurse on its body. `type Foo = …` could resolve\n // to anything (object literal, array, union, primitive); each\n // already has its own branch above.\n return resolveFieldType(target, typeIndex, depth - 1)\n }\n // Reference to a type the index doesn't know about — typically\n // imported from another module. Cross-file resolution is the\n // separate cross-file-resolver pipeline's job; leave this as\n // unknown rather than fabricating a misleading shape.\n return 'unknown'\n }\n\n return 'unknown'\n}\n\n/**\n * Resolve a single property signature to a MsgField. Centralised\n * here so every nested call site (interface members, inline-object\n * members, DU variant fields) picks up the same `T | undefined` peel\n * rules AND reads `@should` / `@validates` JSDoc. Before this helper\n * existed, JSDoc was only honored on top-level Msg variant fields\n * via `buildFieldDescriptor` — annotations on `interface\n * Alternative.image` etc. were silently dropped, so domain types\n * couldn't carry guidance for the agent.\n *\n * Source for the JSDoc reader is recovered from the member's own\n * SourceFile, which means cross-file types (interfaces imported from\n * another package) carry their JSDoc through transparently.\n */\nfunction resolveMember(\n member: ts.PropertySignature,\n typeIndex: TypeIndex,\n depth: number,\n): MsgField {\n const peeled = member.type ? peelOptionalUnion(member.type) : null\n const innerType = peeled?.type ?? member.type\n const baseType: MsgFieldType = innerType\n ? resolveFieldType(innerType, typeIndex, depth)\n : 'unknown'\n const optional = member.questionToken !== undefined || peeled?.isImplicitOptional === true\n const sourceText = member.getSourceFile().text\n const jsdoc = readMemberJSDoc(sourceText, member)\n const hint = readShouldHint(jsdoc)\n const validates = readValidatesTag(jsdoc)\n if (!optional && hint === null && validates === null) return baseType\n const rich: MsgFieldRich = { type: baseType }\n if (optional) rich.optional = true\n if (hint !== null) {\n rich.priority = 'should'\n rich.hint = hint\n }\n if (validates !== null) rich.validates = validates\n return rich\n}\n\nfunction collectInlineShape(\n lit: ts.TypeLiteralNode,\n typeIndex: TypeIndex,\n depth: number,\n): Record<string, MsgField> {\n const shape: Record<string, MsgField> = {}\n for (const member of lit.members) {\n if (!ts.isPropertySignature(member) || !member.name || !ts.isIdentifier(member.name)) continue\n shape[member.name.text] = resolveMember(member, typeIndex, depth)\n }\n return shape\n}\n\nfunction collectInterfaceShape(\n iface: ts.InterfaceDeclaration,\n typeIndex: TypeIndex,\n depth: number,\n): Record<string, MsgField> {\n const shape: Record<string, MsgField> = {}\n for (const member of iface.members) {\n if (!ts.isPropertySignature(member) || !member.name || !ts.isIdentifier(member.name)) continue\n shape[member.name.text] = resolveMember(member, typeIndex, depth)\n }\n return shape\n}\n\n/**\n * Read the leading JSDoc block immediately above `member`. The\n * TypeScript parser doesn't attach JSDoc to interior property\n * signatures, so we re-scan the source between the previous member's\n * end (or the type-literal's `{`) and this member's start, and return\n * the last `/** … *\\/` block found there. Returns `''` when none.\n */\nfunction readMemberJSDoc(source: string, member: ts.PropertySignature): string {\n const ranges = ts.getLeadingCommentRanges(source, member.pos) ?? []\n // Walk in order, keeping only `/** */` blocks. Multiple back-to-back\n // JSDocs concatenate (matches msg-annotations.ts's existing behavior).\n const docs = ranges\n .filter((r) => r.kind === ts.SyntaxKind.MultiLineCommentTrivia)\n .map((r) => source.slice(r.pos, r.end))\n .filter((txt) => txt.startsWith('/**'))\n return docs.join('\\n')\n}\n\n/**\n * Match `@should(\"…\")` (and curly-quote variant) anywhere in the\n * JSDoc. Mirrors msg-annotations.ts's `@intent` parser — same grammar,\n * same tolerance for either ASCII or curly quotes.\n *\n * Returns the unescaped string content, or null when the tag is\n * absent or malformed.\n */\nfunction readShouldHint(comment: string): string | null {\n if (!comment) return null\n const match = comment.match(/@should\\s*\\(\\s*[\"“]([^\"”]*)[\"”]\\s*\\)/)\n return match?.[1] ?? null\n}\n\n/**\n * Match `@validates(\"predicate-expression\")` (and curly-quote variant)\n * anywhere in the JSDoc. Returns the verbatim predicate string —\n * runtime validator compiles it with `new Function('v', 'return (' +\n * src + ')')`. Quote characters inside the predicate must be escaped\n * as the predicate runs through a regex match; for predicates that\n * need embedded quotes, use a regex literal or a named character class.\n */\nfunction readValidatesTag(comment: string): string | null {\n if (!comment) return null\n const match = comment.match(/@validates\\s*\\(\\s*[\"“]([^\"”]*)[\"”]\\s*\\)/)\n return match?.[1] ?? null\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAA;AAE3B,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EAIpB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,qBAAqB,EAA2B,MAAM,sBAAsB,CAAA;AACrF,OAAO,EAAE,kBAAkB,EAAkB,MAAM,mBAAmB,CAAA;AA6KtE;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5C,GAAG,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1C,MAAM,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CAC9C;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAA;IAC/C,cAAc,CAAC,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAA;IACzD,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAA;IACnD,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAA;CACtD;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,UAAQ,EACf,iBAAiB,UAAQ,EACzB,OAAO,GAAE,MAAM,GAAG,IAAW,EAC7B,OAAO,UAAQ,EACf,WAAW,CAAC,EAAE,mBAAmB,EACjC,YAAY,CAAC,EAAE,mBAAmB,GACjC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,aAAa,EAAE,CAAA;CAAE,GAAG,IAAI,CAqYnD;AA2tID,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,wBAAwB,GAAG,IAAI,CAoGjC;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CA4B7D;AAID;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI3D;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,GAAG,MAAM,GAAG,IAAI,CAcrF;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CASzF;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,GAChE,MAAM,CAYR"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAA;AAE3B,OAAO,EACL,gBAAgB,EAChB,mBAAmB,EAIpB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,qBAAqB,EAA2B,MAAM,sBAAsB,CAAA;AACrF,OAAO,EAAE,kBAAkB,EAAkB,MAAM,mBAAmB,CAAA;AA6KtE;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,mBAAmB;IAClC,KAAK,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;IAC5C,GAAG,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;IAC1C,MAAM,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CAC9C;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,mBAAmB;IAClC,SAAS,CAAC,EAAE,UAAU,CAAC,OAAO,gBAAgB,CAAC,CAAA;IAC/C,cAAc,CAAC,EAAE,UAAU,CAAC,OAAO,qBAAqB,CAAC,CAAA;IACzD,WAAW,CAAC,EAAE,UAAU,CAAC,OAAO,kBAAkB,CAAC,CAAA;IACnD,YAAY,CAAC,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAA;CACtD;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,UAAQ,EACf,iBAAiB,UAAQ,EACzB,OAAO,GAAE,MAAM,GAAG,IAAW,EAC7B,OAAO,UAAQ,EACf,WAAW,CAAC,EAAE,mBAAmB,EACjC,YAAY,CAAC,EAAE,mBAAmB,GACjC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,aAAa,EAAE,CAAA;CAAE,GAAG,IAAI,CAqYnD;AAuvID,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,GAChB,wBAAwB,GAAG,IAAI,CAoGjC;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CA4B7D;AAID;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAI3D;AAED;;;GAGG;AACH,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,EAAE,CAAC,cAAc,GAAG,MAAM,GAAG,IAAI,CAcrF;AAED;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CASzF;AAED;;;;GAIG;AACH,wBAAgB,wBAAwB,CACtC,MAAM,EAAE,MAAM,EACd,cAAc,EAAE,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAAC,GAChE,MAAM,CAYR"}
package/dist/transform.js CHANGED
@@ -1247,6 +1247,33 @@ function detectArrayOp(clause, stateName, modifiedFields, _structuralMask, _case
1247
1247
  // tautology: every binding mask ANDed with zero is zero.
1248
1248
  if (modifiedFields.length === 0)
1249
1249
  return 'none';
1250
+ // The specialized methods (`reconcileClear`, `reconcileItems`,
1251
+ // `reconcileRemove`, `reconcileChanged`) only exist on `each` blocks.
1252
+ // Non-each blocks (`show`, `branch`, `scope`) leave them undefined,
1253
+ // so a method other than 0 (general reconcile) silently no-ops on
1254
+ // those blocks at runtime. If the case modifies fields BEYOND the
1255
+ // array op (e.g. `{ ...state, open: true, name: '', tags: [] }`),
1256
+ // any show/branch block whose mask intersects the case's dirty bits
1257
+ // would be selected for reconcile but then skipped by the no-op
1258
+ // method invocation — its `when`/`on` accessor never re-evaluates,
1259
+ // and the component appears structurally inert after mount.
1260
+ //
1261
+ // Conservative correctness: only emit a non-general method when the
1262
+ // array op is the SOLE field modification. With one modified field,
1263
+ // the only blocks selected by mask gating are ones that read that
1264
+ // single field — and the optimization is well-defined for that
1265
+ // narrow case (each blocks operating on the array). Multi-field
1266
+ // cases fall through to `'general'` (method=0), so every selected
1267
+ // block runs the standard `reconcile` path. We trade a niche
1268
+ // optimization (small benefit even when applicable) for guaranteed
1269
+ // structural reconciliation across the framework's primitive set.
1270
+ //
1271
+ // Sister of show-helper-reconcile.test.ts, which fixed the same
1272
+ // class of bug on the method=-1 path. Same architectural principle:
1273
+ // the compiler can't see every block in the view, so optimizations
1274
+ // that route around `reconcile` must be ironclad. When in doubt,
1275
+ // emit method=0 and let `_handleMsg`'s per-block mask gate filter.
1276
+ //
1250
1277
  // Previously: if `(structuralMask & caseDirty) === 0`, return 'none'
1251
1278
  // on the theory that no structural block's mask could intersect this
1252
1279
  // case's dirty bits. That optimization was UNSAFE: `computeStructuralMask`
@@ -1266,13 +1293,9 @@ function detectArrayOp(clause, stateName, modifiedFields, _structuralMask, _case
1266
1293
  // when `errors` changes — but the compiler was emitting `method = -1`
1267
1294
  // (skip blocks entirely) for cases that only touch `errors`, and the
1268
1295
  // error paragraphs would never mount.
1269
- //
1270
- // The fix is to remove this short-circuit. Phase 1 runs unconditionally
1271
- // when any field is modified; `_handleMsg`'s per-block check
1272
- // `if (!(block.mask & dirty)) continue` filters out uninterested
1273
- // blocks at near-zero cost. We lose a micro-optimization but gain
1274
- // correctness for every component that factors view helpers into
1275
- // functions — which is the idiomatic pattern.
1296
+ if (modifiedFields.length !== 1)
1297
+ return 'general';
1298
+ const onlyField = modifiedFields[0];
1276
1299
  // Look at the return expression's array field values
1277
1300
  for (const stmt of clause.statements) {
1278
1301
  const returnExpr = findReturnArray(stmt);
@@ -1289,6 +1312,13 @@ function detectArrayOp(clause, stateName, modifiedFields, _structuralMask, _case
1289
1312
  : null;
1290
1313
  if (!name)
1291
1314
  continue;
1315
+ // The optimization only applies when the array op is on the
1316
+ // single tracked field. A `field: []` on a different field
1317
+ // (one not in modifiedFields, e.g. an untracked field) would
1318
+ // still no-op safely on each blocks via the mask gate, but to
1319
+ // keep the analysis tight we require an exact match.
1320
+ if (name !== onlyField)
1321
+ continue;
1292
1322
  // Check for empty array literal: `field: []`
1293
1323
  if (ts.isPropertyAssignment(prop) &&
1294
1324
  ts.isArrayLiteralExpression(prop.initializer) &&