@llui/agent 0.0.41 → 0.0.42

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.
@@ -202,7 +202,6 @@ function compileRouteGate(src) {
202
202
  if (fn)
203
203
  return fn;
204
204
  try {
205
- // eslint-disable-next-line @typescript-eslint/no-implied-eval
206
205
  fn = new Function('state', `return (${src})`);
207
206
  }
208
207
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"list-actions.js","sourceRoot":"","sources":["../../../src/client/rpc/list-actions.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MessageAnnotations } from '../../protocol.js'\nimport type { MsgSchemaShape, MsgSchemaField } from '../factory.js'\n\ntype Binding = { variant: string }\ntype Annotations = Record<string, MessageAnnotations>\n\nexport type ListActionsHost = {\n getState(): unknown\n getBindingDescriptors(): Binding[] | null\n getMsgAnnotations(): Annotations | null\n getMsgSchema(): MsgSchemaShape | null\n getAgentAffordances(): ((state: unknown) => Array<{ type: string; [k: string]: unknown }>) | null\n}\n\n/**\n * `dispatchMode` on each action is `'shared'` (human can also click via\n * a UI affordance) or `'agent-only'` (no UI binding — agent is the only\n * dispatcher). `'human-only'` variants are filtered out before this\n * point — they never reach the LLM.\n *\n * `source` distinguishes WHERE the affordance came from:\n * - `'binding'` — a tagged event handler is currently mounted in a\n * live scope (refcount > 0). Variants inside dead branches —\n * `show({when: false})`, unmounted `branch()` cases, removed `each`\n * items — auto-vanish from this set as their lifetimes dispose.\n * This is the framework's \"what can the user click right now\"\n * answer, and it's the default surface for the agent.\n * - `'always-affordable'` — either the app's `agentAffordances(state)`\n * hook listed the variant, or the variant carries the\n * `@alwaysAffordable` JSDoc tag. Both are the explicit \"agent can\n * reach this even when no live UI binding maps to it\" knob — bulk\n * seed ops (`Matrix/AddAlternatives`) and similar agent-driven\n * paths typically land here.\n * - `'schema'` — variant is annotated `@agentOnly` (the canonical\n * \"no UI button maps to this; the agent is the only dispatcher\")\n * and isn't already covered above. The payload is schema-synthesized\n * and the agent fills it in.\n *\n * `'shared'` variants WITHOUT a live binding, without\n * `agentAffordances` mention, and without `@alwaysAffordable` are\n * **deliberately hidden**. They're reachable through UI navigation —\n * the human user can't click them right now, and dispatching them\n * blindly would mutate state that drives `show()`/`branch()` gates,\n * popping hidden UI subtrees into view in places the user didn't\n * navigate to.\n */\nexport type ListActionsResult = {\n actions: Array<{\n variant: string\n /**\n * Human-readable phrase from `@intent(\"…\")`, or `null` when the\n * variant is unannotated. Mirror of LapActionsResponse.intent —\n * callers should treat `null` as a documentation gap and not as\n * \"missing label, fall back to variant name\".\n */\n intent: string | null\n requiresConfirm: boolean\n dispatchMode: 'shared' | 'agent-only'\n source: 'binding' | 'always-affordable' | 'schema'\n selectorHint: string | null\n payloadHint: object | null\n /** Cautionary text from `@warning` JSDoc, or null. */\n warning: string | null\n /** Concrete examples from `@example` JSDoc, in source order. */\n examples: string[]\n /**\n * Effect kinds this variant emits, from `@emits(\"k1\", \"k2\")`.\n * Empty when not annotated. Lets the agent know what side\n * effects fire — useful for batching (\"100 dispatches × cloud-\n * save = bad\") and for confirming destructive flows.\n */\n emits: string[]\n /**\n * Per-field guidance lifted from `@should(\"…\")` JSDoc on payload\n * fields. Path is dot/bracket notation rooted at the payload\n * (e.g. `\"cells\"` for a top-level field, `\"cells[].meta\"` for an\n * array element's nested field). Useful when the field is typed\n * as `unknown` or as a polymorphic shape — the hint says \"type\n * matches the criterion's kind: number for quantity, …\" so the\n * agent doesn't have to guess from the bare schema.\n *\n * Empty when no field on this variant carries an `@should` hint.\n */\n fieldHints: Array<{ path: string; hint: string }>\n }>\n}\n\nexport function handleListActions(host: ListActionsHost): ListActionsResult {\n const annotations = host.getMsgAnnotations() ?? {}\n const state = host.getState()\n const descriptors = host.getBindingDescriptors() ?? []\n const affordancesFn = host.getAgentAffordances()\n const affordances = affordancesFn ? affordancesFn(state) : []\n // When the app provides `agentAffordances(state)`, it's opted into\n // explicit affordance control: only state-relevant Msgs are listed.\n // `@agentOnly` schema-source variants are then filtered to those the\n // hook returned — so a bulk-edit Msg like `Matrix/AddCriteria`\n // doesn't surface on the home page just because it's tagged\n // `@agentOnly`. Apps without `agentAffordances` keep the previous\n // permissive default (\"everything's available unless you say\n // otherwise\") since flipping that without explicit opt-in would\n // break consumers who rely on schema-source surfacing of\n // bulk Msgs.\n const explicitAffordances = affordancesFn !== null\n const affordanceVariants = new Set(affordances.map((m) => m.type))\n const schema = host.getMsgSchema()\n\n const out: ListActionsResult['actions'] = []\n const seen = new Set<string>()\n\n // From bindings — these have UI affordances by definition, so they're\n // either 'shared' (default) or, in the malformed case where someone\n // bound an `@agentOnly` Msg in a view, 'agent-only'. Either way the\n // agent can dispatch them.\n //\n // Filtered against the Msg schema: a binding whose variant isn't in\n // the user's Msg union is a library-internal Msg leaking through\n // `tagSend` translator wiring (the sortable component's `move`,\n // `drop`, `cancel`, etc. — they're routed into the user's update.ts\n // via a different shape but their lib names slip into the binding\n // registry). The agent has no use for those names — `would_dispatch`\n // / `send_message` would reject them as `unknown-variant` anyway —\n // so they pollute the affordance list. When a schema is available,\n // the schema's variant set is the source of truth.\n for (const d of descriptors) {\n if (schema && !(d.variant in schema.variants)) continue\n const ann = annotations[d.variant]\n if (ann?.dispatchMode === 'human-only') continue\n if (!passesRouteGate(ann, state)) continue\n seen.add(d.variant)\n const variantSchema = schema?.variants[d.variant]\n out.push({\n variant: d.variant,\n intent: ann?.intent ?? null,\n requiresConfirm: ann?.requiresConfirm ?? false,\n dispatchMode: ann?.dispatchMode === 'agent-only' ? 'agent-only' : 'shared',\n source: 'binding',\n selectorHint: null,\n payloadHint: null,\n warning: ann?.warning ?? null,\n examples: ann?.examples ?? [],\n emits: ann?.emits ?? [],\n fieldHints: variantSchema ? collectFieldHints(variantSchema) : [],\n })\n }\n\n // From `agentAffordances(state)` — the integrator's explicit list of\n // currently-reachable Msgs, with concrete payloads they author.\n for (const msg of affordances) {\n const ann = annotations[msg.type]\n if (ann?.dispatchMode === 'human-only') continue\n if (!passesRouteGate(ann, state)) continue\n seen.add(msg.type)\n const { type, ...rest } = msg\n const variantSchema = schema?.variants[type]\n out.push({\n variant: type,\n intent: ann?.intent ?? null,\n requiresConfirm: ann?.requiresConfirm ?? false,\n dispatchMode: ann?.dispatchMode === 'agent-only' ? 'agent-only' : 'shared',\n source: 'always-affordable',\n selectorHint: null,\n payloadHint: Object.keys(rest).length > 0 ? rest : null,\n warning: ann?.warning ?? null,\n examples: ann?.examples ?? [],\n emits: ann?.emits ?? [],\n fieldHints: variantSchema ? collectFieldHints(variantSchema) : [],\n })\n }\n\n // From `@alwaysAffordable` annotations — the per-variant equivalent\n // of `agentAffordances`. Variants tagged this way surface regardless\n // of whether a live binding maps to them, so bulk seed ops\n // (`Matrix/AddAlternatives`) and similar agent-driven paths are\n // available even when their UI counterparts (if any) aren't mounted.\n // The payload is schema-synthesized — `agentAffordances` is the way\n // to ship a concrete pre-filled payload alongside the affordance.\n for (const [variant, ann] of Object.entries(annotations)) {\n if (seen.has(variant)) continue\n if (ann.dispatchMode === 'human-only') continue\n if (!ann.alwaysAffordable) continue\n if (!passesRouteGate(ann, state)) continue\n seen.add(variant)\n const fields = schema?.variants[variant]\n out.push({\n variant,\n intent: ann.intent,\n requiresConfirm: ann.requiresConfirm,\n dispatchMode: ann.dispatchMode === 'agent-only' ? 'agent-only' : 'shared',\n source: 'always-affordable',\n selectorHint: null,\n payloadHint: fields ? synthesizePayload(variant, fields) : null,\n warning: ann.warning,\n examples: ann.examples,\n emits: ann.emits,\n fieldHints: fields ? collectFieldHints(fields) : [],\n })\n }\n\n // From schema — variants that aren't already surfaced above and that\n // the author marked `@agentOnly`. The canonical \"no UI button maps\n // to this; the agent is the only dispatcher.\" Bulk edits, imports,\n // admin operations that have no human-facing affordance at all.\n //\n // `'shared'` variants WITHOUT a live binding stay hidden here — they\n // are reachable through UI navigation, and dispatching them while\n // their UI subtree is unmounted would pop hidden state in places the\n // user didn't navigate to. The explicit knobs are `@alwaysAffordable`\n // (handled above) or `agentAffordances(state)`.\n //\n // When the app provides `agentAffordances`, this pass is filtered:\n // an `@agentOnly` variant only surfaces if the hook returned it.\n // That makes route-gated bulk Msgs (`Matrix/AddCriteria` available\n // only when a matrix is loaded) work as expected — they stop\n // appearing on the home page just because they're tagged\n // `@agentOnly`. Apps without `agentAffordances` keep the previous\n // permissive default.\n if (schema) {\n for (const [variant, fields] of Object.entries(schema.variants)) {\n if (seen.has(variant)) continue\n const ann = annotations[variant]\n if (ann?.dispatchMode !== 'agent-only') continue\n if (explicitAffordances && !affordanceVariants.has(variant)) continue\n if (!passesRouteGate(ann, state)) continue\n out.push({\n variant,\n intent: ann.intent,\n requiresConfirm: ann.requiresConfirm,\n dispatchMode: 'agent-only',\n source: 'schema',\n selectorHint: null,\n payloadHint: synthesizePayload(variant, fields),\n warning: ann.warning,\n examples: ann.examples,\n emits: ann.emits,\n fieldHints: collectFieldHints(fields),\n })\n }\n }\n\n return { actions: out }\n}\n\n/**\n * Build an example payload object the LLM can fill in. Required\n * fields always appear; optional fields appear only when annotated\n * `@should` (LLM is encouraged to fill them in). Fields without a\n * concrete primitive type (`'unknown'`) emit `null` placeholders the\n * LLM is expected to replace.\n *\n * The first key is `type` so the payload reads as a complete Msg\n * shape — copy-paste-ready into `send_message`.\n */\n/**\n * Evaluate `@routeGated(\"predicate\")` against the current state.\n * Returns true (variant passes) when:\n * - the variant has no `@routeGated` annotation, OR\n * - the predicate evaluates truthy with `state` bound.\n *\n * Predicate is compiled lazily via `new Function('state', 'return (' +\n * src + ')')` and cached in a module-level Map. Compile failures\n * (syntactically broken predicates) degrade to \"true\" so a single\n * malformed annotation doesn't paralyze the affordance pass — the\n * build-time linter is the right place to catch syntactic issues.\n * Evaluation throws fail-closed (return false) since a predicate that\n * crashes on the current state shouldn't surface the variant.\n */\nfunction passesRouteGate(ann: MessageAnnotations | undefined, state: unknown): boolean {\n const src = ann?.routeGate\n if (!src) return true\n const predicate = compileRouteGate(src)\n try {\n return Boolean(predicate(state))\n } catch {\n return false\n }\n}\n\nconst routeGateCache = new Map<string, (state: unknown) => boolean>()\nfunction compileRouteGate(src: string): (state: unknown) => boolean {\n let fn = routeGateCache.get(src)\n if (fn) return fn\n try {\n // eslint-disable-next-line @typescript-eslint/no-implied-eval\n fn = new Function('state', `return (${src})`) as (state: unknown) => boolean\n } catch {\n fn = () => true\n }\n routeGateCache.set(src, fn)\n return fn\n}\n\nfunction synthesizePayload(variant: string, fields: Record<string, MsgSchemaField>): object {\n const out: Record<string, unknown> = { type: variant }\n for (const [name, descriptor] of Object.entries(fields)) {\n const optional = isOptional(descriptor)\n const priority = isShould(descriptor)\n // Skip optional fields unless they're @should-flagged. Required\n // fields always appear.\n if (optional && priority !== 'should') continue\n out[name] = exampleValue(descriptor)\n }\n return out\n}\n\n/**\n * Walk a variant's field tree and collect every `@should` hint into a\n * flat list keyed by field path. Path conventions:\n * - top-level field: `\"cells\"`\n * - nested object property: `\"cells.value\"`\n * - array element: `\"cells[]\"` for the element itself; descendants\n * use `\"cells[].meta\"` and so on.\n *\n * Surfaces the same hints that show up nested inside\n * `description.messages.variants[X].field.hint` so callers don't have\n * to dig through the schema tree to find them.\n */\nfunction collectFieldHints(\n fields: Record<string, MsgSchemaField>,\n): Array<{ path: string; hint: string }> {\n const out: Array<{ path: string; hint: string }> = []\n for (const [name, descriptor] of Object.entries(fields)) {\n walkHint(name, descriptor, out)\n }\n return out\n}\n\nfunction walkHint(\n path: string,\n d: MsgSchemaField,\n out: Array<{ path: string; hint: string }>,\n): void {\n // Rich descriptor with a hint at this position.\n if (typeof d === 'object' && d !== null && 'type' in d) {\n if (typeof d.hint === 'string' && d.hint.length > 0) {\n out.push({ path, hint: d.hint })\n }\n // `@validates(...)` predicates surface alongside `@should` hints\n // so the agent sees the constraint at affordance time rather than\n // only as a post-dispatch rejection. The verbatim predicate text\n // is what the runtime evaluates; agents trained on JS read it\n // directly. Prefix `validates: ` to disambiguate from freeform\n // `@should` text.\n if (typeof d.validates === 'string' && d.validates.length > 0) {\n out.push({ path, hint: `validates: ${d.validates}` })\n }\n walkHintBare(path, d.type, out)\n return\n }\n walkHintBare(path, d, out)\n}\n\nfunction walkHintBare(path: string, t: unknown, out: Array<{ path: string; hint: string }>): void {\n if (t === null || typeof t !== 'object') return\n const obj = t as Record<string, unknown>\n if (obj.kind === 'object' && obj.shape !== null && typeof obj.shape === 'object') {\n for (const [name, descriptor] of Object.entries(obj.shape as Record<string, MsgSchemaField>)) {\n walkHint(`${path}.${name}`, descriptor, out)\n }\n return\n }\n if (obj.kind === 'array') {\n walkHint(`${path}[]`, obj.element as MsgSchemaField, out)\n }\n if (obj.kind === 'discriminated-union') {\n // Synthetic hint at the union's path summarizing the legal\n // discriminant values. Lets the agent see \"format expects one of:\n // exact, range, compound\" without walking the full schema. Then\n // walk each branch's per-field hints with a path-suffix that\n // disambiguates which branch the hint applies to.\n const variants = obj.variants as Record<string, Record<string, MsgSchemaField>>\n const discriminant = String(obj.discriminant)\n const legalValues = Object.keys(variants)\n if (legalValues.length > 0) {\n out.push({\n path,\n hint: `Discriminated union — set \\`${discriminant}\\` to one of: ${legalValues\n .map((v) => `'${v}'`)\n .join(', ')}.`,\n })\n }\n for (const [discValue, fields] of Object.entries(variants)) {\n for (const [fieldName, fieldDesc] of Object.entries(fields)) {\n walkHint(`${path}(${discriminant}=${discValue}).${fieldName}`, fieldDesc, out)\n }\n }\n }\n}\n\nfunction isOptional(d: MsgSchemaField): boolean {\n return typeof d === 'object' && 'type' in d && d.optional === true\n}\n\nfunction isShould(d: MsgSchemaField): 'should' | undefined {\n return typeof d === 'object' && 'type' in d ? d.priority : undefined\n}\n\nfunction exampleValue(d: MsgSchemaField): unknown {\n // Unwrap rich descriptor to get the bare type for synthesis.\n const t =\n typeof d === 'object' && 'type' in d\n ? d.type\n : (d as\n | Exclude<MsgSchemaField, object>\n | Extract<MsgSchemaField, { kind?: string; enum?: string[] }>)\n return synthesizeBare(t as never)\n}\n\nfunction synthesizeBare(t: unknown): unknown {\n if (typeof t === 'string') {\n if (t === 'string') return ''\n if (t === 'number') return 0\n if (t === 'boolean') return false\n return null // 'unknown' or unrecognized keyword → placeholder\n }\n if (t === null || typeof t !== 'object') return null\n const obj = t as Record<string, unknown>\n if ('enum' in obj && Array.isArray(obj.enum)) {\n // First option doubles as the canonical example. Native value type\n // round-trips (string/number/boolean) since the compiler preserved\n // the literal kind on emit.\n return obj.enum[0] ?? null\n }\n if (obj.kind === 'object' && obj.shape !== null && typeof obj.shape === 'object') {\n // Recurse into the nested shape. Same optional-skip rule as the\n // top-level synthesizer: required fields appear, optional ones\n // appear only when @should-flagged.\n const out: Record<string, unknown> = {}\n for (const [name, descriptor] of Object.entries(obj.shape as Record<string, MsgSchemaField>)) {\n const isOpt = isOptional(descriptor)\n const pri = isShould(descriptor)\n if (isOpt && pri !== 'should') continue\n out[name] = exampleValue(descriptor)\n }\n return out\n }\n if (obj.kind === 'array') {\n // Wrap the synthesized element in a one-item array. Lets the LLM\n // see the per-entry shape without us guessing at array length.\n return [synthesizeBare(obj.element)]\n }\n if (obj.kind === 'discriminated-union') {\n // Synthesize the FIRST branch as the concrete example. The full\n // shape (every legal branch + its payload) is preserved in\n // `description.messages.variants[X]` from `describe_app`, so the\n // agent that needs another branch reads the schema directly.\n // `collectFieldHints` adds a synthetic enumeration of the legal\n // `<discriminant>` values onto the hint surface so the agent\n // doesn't have to dig into the schema for the simple case.\n const variants = obj.variants as Record<string, Record<string, MsgSchemaField>>\n const discriminant = String(obj.discriminant)\n const firstEntry = Object.entries(variants).at(0)\n if (!firstEntry) return null\n const [firstValue, firstFields] = firstEntry\n const branch: Record<string, unknown> = { [discriminant]: firstValue }\n for (const [name, descriptor] of Object.entries(firstFields)) {\n const isOpt = isOptional(descriptor)\n const pri = isShould(descriptor)\n if (isOpt && pri !== 'should') continue\n branch[name] = exampleValue(descriptor)\n }\n return branch\n }\n return null\n}\n"]}
1
+ {"version":3,"file":"list-actions.js","sourceRoot":"","sources":["../../../src/client/rpc/list-actions.ts"],"names":[],"mappings":"AAuFA,MAAM,UAAU,iBAAiB,CAAC,IAAqB;IACrD,MAAM,WAAW,GAAG,IAAI,CAAC,iBAAiB,EAAE,IAAI,EAAE,CAAA;IAClD,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAA;IAC7B,MAAM,WAAW,GAAG,IAAI,CAAC,qBAAqB,EAAE,IAAI,EAAE,CAAA;IACtD,MAAM,aAAa,GAAG,IAAI,CAAC,mBAAmB,EAAE,CAAA;IAChD,MAAM,WAAW,GAAG,aAAa,CAAC,CAAC,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IAC7D,mEAAmE;IACnE,oEAAoE;IACpE,qEAAqE;IACrE,+DAA+D;IAC/D,4DAA4D;IAC5D,kEAAkE;IAClE,6DAA6D;IAC7D,gEAAgE;IAChE,yDAAyD;IACzD,aAAa;IACb,MAAM,mBAAmB,GAAG,aAAa,KAAK,IAAI,CAAA;IAClD,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAA;IAClE,MAAM,MAAM,GAAG,IAAI,CAAC,YAAY,EAAE,CAAA;IAElC,MAAM,GAAG,GAAiC,EAAE,CAAA;IAC5C,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAE9B,sEAAsE;IACtE,oEAAoE;IACpE,oEAAoE;IACpE,2BAA2B;IAC3B,EAAE;IACF,oEAAoE;IACpE,iEAAiE;IACjE,gEAAgE;IAChE,oEAAoE;IACpE,kEAAkE;IAClE,qEAAqE;IACrE,mEAAmE;IACnE,mEAAmE;IACnE,mDAAmD;IACnD,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC;YAAE,SAAQ;QACvD,MAAM,GAAG,GAAG,WAAW,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;QAClC,IAAI,GAAG,EAAE,YAAY,KAAK,YAAY;YAAE,SAAQ;QAChD,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC;YAAE,SAAQ;QAC1C,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;QACnB,MAAM,aAAa,GAAG,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAA;QACjD,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,CAAC,CAAC,OAAO;YAClB,MAAM,EAAE,GAAG,EAAE,MAAM,IAAI,IAAI;YAC3B,eAAe,EAAE,GAAG,EAAE,eAAe,IAAI,KAAK;YAC9C,YAAY,EAAE,GAAG,EAAE,YAAY,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ;YAC1E,MAAM,EAAE,SAAS;YACjB,YAAY,EAAE,IAAI;YAClB,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,IAAI;YAC7B,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,EAAE;YAC7B,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE;YACvB,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE;SAClE,CAAC,CAAA;IACJ,CAAC;IAED,qEAAqE;IACrE,gEAAgE;IAChE,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,GAAG,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACjC,IAAI,GAAG,EAAE,YAAY,KAAK,YAAY;YAAE,SAAQ;QAChD,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC;YAAE,SAAQ;QAC1C,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QAClB,MAAM,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,GAAG,CAAA;QAC7B,MAAM,aAAa,GAAG,MAAM,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAA;QAC5C,GAAG,CAAC,IAAI,CAAC;YACP,OAAO,EAAE,IAAI;YACb,MAAM,EAAE,GAAG,EAAE,MAAM,IAAI,IAAI;YAC3B,eAAe,EAAE,GAAG,EAAE,eAAe,IAAI,KAAK;YAC9C,YAAY,EAAE,GAAG,EAAE,YAAY,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ;YAC1E,MAAM,EAAE,mBAAmB;YAC3B,YAAY,EAAE,IAAI;YAClB,WAAW,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI;YACvD,OAAO,EAAE,GAAG,EAAE,OAAO,IAAI,IAAI;YAC7B,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,EAAE;YAC7B,KAAK,EAAE,GAAG,EAAE,KAAK,IAAI,EAAE;YACvB,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC,iBAAiB,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,EAAE;SAClE,CAAC,CAAA;IACJ,CAAC;IAED,oEAAoE;IACpE,qEAAqE;IACrE,2DAA2D;IAC3D,gEAAgE;IAChE,qEAAqE;IACrE,oEAAoE;IACpE,kEAAkE;IAClE,KAAK,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;QACzD,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,SAAQ;QAC/B,IAAI,GAAG,CAAC,YAAY,KAAK,YAAY;YAAE,SAAQ;QAC/C,IAAI,CAAC,GAAG,CAAC,gBAAgB;YAAE,SAAQ;QACnC,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC;YAAE,SAAQ;QAC1C,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAA;QACjB,MAAM,MAAM,GAAG,MAAM,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAA;QACxC,GAAG,CAAC,IAAI,CAAC;YACP,OAAO;YACP,MAAM,EAAE,GAAG,CAAC,MAAM;YAClB,eAAe,EAAE,GAAG,CAAC,eAAe;YACpC,YAAY,EAAE,GAAG,CAAC,YAAY,KAAK,YAAY,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,QAAQ;YACzE,MAAM,EAAE,mBAAmB;YAC3B,YAAY,EAAE,IAAI;YAClB,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;YAC/D,OAAO,EAAE,GAAG,CAAC,OAAO;YACpB,QAAQ,EAAE,GAAG,CAAC,QAAQ;YACtB,KAAK,EAAE,GAAG,CAAC,KAAK;YAChB,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE;SACpD,CAAC,CAAA;IACJ,CAAC;IAED,qEAAqE;IACrE,mEAAmE;IACnE,mEAAmE;IACnE,gEAAgE;IAChE,EAAE;IACF,qEAAqE;IACrE,kEAAkE;IAClE,qEAAqE;IACrE,sEAAsE;IACtE,gDAAgD;IAChD,EAAE;IACF,mEAAmE;IACnE,iEAAiE;IACjE,mEAAmE;IACnE,6DAA6D;IAC7D,yDAAyD;IACzD,kEAAkE;IAClE,sBAAsB;IACtB,IAAI,MAAM,EAAE,CAAC;QACX,KAAK,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChE,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,SAAQ;YAC/B,MAAM,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC,CAAA;YAChC,IAAI,GAAG,EAAE,YAAY,KAAK,YAAY;gBAAE,SAAQ;YAChD,IAAI,mBAAmB,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,OAAO,CAAC;gBAAE,SAAQ;YACrE,IAAI,CAAC,eAAe,CAAC,GAAG,EAAE,KAAK,CAAC;gBAAE,SAAQ;YAC1C,GAAG,CAAC,IAAI,CAAC;gBACP,OAAO;gBACP,MAAM,EAAE,GAAG,CAAC,MAAM;gBAClB,eAAe,EAAE,GAAG,CAAC,eAAe;gBACpC,YAAY,EAAE,YAAY;gBAC1B,MAAM,EAAE,QAAQ;gBAChB,YAAY,EAAE,IAAI;gBAClB,WAAW,EAAE,iBAAiB,CAAC,OAAO,EAAE,MAAM,CAAC;gBAC/C,OAAO,EAAE,GAAG,CAAC,OAAO;gBACpB,QAAQ,EAAE,GAAG,CAAC,QAAQ;gBACtB,KAAK,EAAE,GAAG,CAAC,KAAK;gBAChB,UAAU,EAAE,iBAAiB,CAAC,MAAM,CAAC;aACtC,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,CAAA;AACzB,CAAC;AAED;;;;;;;;;GASG;AACH;;;;;;;;;;;;;GAaG;AACH,SAAS,eAAe,CAAC,GAAmC,EAAE,KAAc;IAC1E,MAAM,GAAG,GAAG,GAAG,EAAE,SAAS,CAAA;IAC1B,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAA;IACrB,MAAM,SAAS,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAA;IACvC,IAAI,CAAC;QACH,OAAO,OAAO,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAA;IAClC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAED,MAAM,cAAc,GAAG,IAAI,GAAG,EAAuC,CAAA;AACrE,SAAS,gBAAgB,CAAC,GAAW;IACnC,IAAI,EAAE,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAChC,IAAI,EAAE;QAAE,OAAO,EAAE,CAAA;IACjB,IAAI,CAAC;QACH,EAAE,GAAG,IAAI,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,GAAG,CAAgC,CAAA;IAC9E,CAAC;IAAC,MAAM,CAAC;QACP,EAAE,GAAG,GAAG,EAAE,CAAC,IAAI,CAAA;IACjB,CAAC;IACD,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;IAC3B,OAAO,EAAE,CAAA;AACX,CAAC;AAED,SAAS,iBAAiB,CAAC,OAAe,EAAE,MAAsC;IAChF,MAAM,GAAG,GAA4B,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;IACtD,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACxD,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,CAAA;QACvC,MAAM,QAAQ,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAA;QACrC,gEAAgE;QAChE,wBAAwB;QACxB,IAAI,QAAQ,IAAI,QAAQ,KAAK,QAAQ;YAAE,SAAQ;QAC/C,GAAG,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC,CAAA;IACtC,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED;;;;;;;;;;;GAWG;AACH,SAAS,iBAAiB,CACxB,MAAsC;IAEtC,MAAM,GAAG,GAA0C,EAAE,CAAA;IACrD,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QACxD,QAAQ,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,CAAC,CAAA;IACjC,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAED,SAAS,QAAQ,CACf,IAAY,EACZ,CAAiB,EACjB,GAA0C;IAE1C,gDAAgD;IAChD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QACvD,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACpD,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,CAAA;QAClC,CAAC;QACD,iEAAiE;QACjE,kEAAkE;QAClE,iEAAiE;QACjE,8DAA8D;QAC9D,+DAA+D;QAC/D,kBAAkB;QAClB,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC9D,GAAG,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAAA;QACvD,CAAC;QACD,YAAY,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,GAAG,CAAC,CAAA;QAC/B,OAAM;IACR,CAAC;IACD,YAAY,CAAC,IAAI,EAAE,CAAC,EAAE,GAAG,CAAC,CAAA;AAC5B,CAAC;AAED,SAAS,YAAY,CAAC,IAAY,EAAE,CAAU,EAAE,GAA0C;IACxF,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAM;IAC/C,MAAM,GAAG,GAAG,CAA4B,CAAA;IACxC,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACjF,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAuC,CAAC,EAAE,CAAC;YAC7F,QAAQ,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,EAAE,UAAU,EAAE,GAAG,CAAC,CAAA;QAC9C,CAAC;QACD,OAAM;IACR,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACzB,QAAQ,CAAC,GAAG,IAAI,IAAI,EAAE,GAAG,CAAC,OAAyB,EAAE,GAAG,CAAC,CAAA;IAC3D,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;QACvC,2DAA2D;QAC3D,kEAAkE;QAClE,gEAAgE;QAChE,6DAA6D;QAC7D,kDAAkD;QAClD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAA0D,CAAA;QAC/E,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QAC7C,MAAM,WAAW,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;QACzC,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,GAAG,CAAC,IAAI,CAAC;gBACP,IAAI;gBACJ,IAAI,EAAE,+BAA+B,YAAY,iBAAiB,WAAW;qBAC1E,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;qBACpB,IAAI,CAAC,IAAI,CAAC,GAAG;aACjB,CAAC,CAAA;QACJ,CAAC;QACD,KAAK,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3D,KAAK,MAAM,CAAC,SAAS,EAAE,SAAS,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5D,QAAQ,CAAC,GAAG,IAAI,IAAI,YAAY,IAAI,SAAS,KAAK,SAAS,EAAE,EAAE,SAAS,EAAE,GAAG,CAAC,CAAA;YAChF,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,CAAiB;IACnC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAA;AACpE,CAAC;AAED,SAAS,QAAQ,CAAC,CAAiB;IACjC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAA;AACtE,CAAC;AAED,SAAS,YAAY,CAAC,CAAiB;IACrC,6DAA6D;IAC7D,MAAM,CAAC,GACL,OAAO,CAAC,KAAK,QAAQ,IAAI,MAAM,IAAI,CAAC;QAClC,CAAC,CAAC,CAAC,CAAC,IAAI;QACR,CAAC,CAAE,CAE+D,CAAA;IACtE,OAAO,cAAc,CAAC,CAAU,CAAC,CAAA;AACnC,CAAC;AAED,SAAS,cAAc,CAAC,CAAU;IAChC,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAA;QAC7B,IAAI,CAAC,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAA;QAC5B,IAAI,CAAC,KAAK,SAAS;YAAE,OAAO,KAAK,CAAA;QACjC,OAAO,IAAI,CAAA,CAAC,kDAAkD;IAChE,CAAC;IACD,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAA;IACpD,MAAM,GAAG,GAAG,CAA4B,CAAA;IACxC,IAAI,MAAM,IAAI,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAC7C,mEAAmE;QACnE,mEAAmE;QACnE,4BAA4B;QAC5B,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,IAAI,CAAA;IAC5B,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,QAAQ,IAAI,GAAG,CAAC,KAAK,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;QACjF,gEAAgE;QAChE,+DAA+D;QAC/D,oCAAoC;QACpC,MAAM,GAAG,GAA4B,EAAE,CAAA;QACvC,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,KAAuC,CAAC,EAAE,CAAC;YAC7F,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,CAAA;YACpC,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAA;YAChC,IAAI,KAAK,IAAI,GAAG,KAAK,QAAQ;gBAAE,SAAQ;YACvC,GAAG,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC,CAAA;QACtC,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QACzB,iEAAiE;QACjE,+DAA+D;QAC/D,OAAO,CAAC,cAAc,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAA;IACtC,CAAC;IACD,IAAI,GAAG,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;QACvC,gEAAgE;QAChE,2DAA2D;QAC3D,iEAAiE;QACjE,6DAA6D;QAC7D,gEAAgE;QAChE,6DAA6D;QAC7D,2DAA2D;QAC3D,MAAM,QAAQ,GAAG,GAAG,CAAC,QAA0D,CAAA;QAC/E,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;QAC7C,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;QACjD,IAAI,CAAC,UAAU;YAAE,OAAO,IAAI,CAAA;QAC5B,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,GAAG,UAAU,CAAA;QAC5C,MAAM,MAAM,GAA4B,EAAE,CAAC,YAAY,CAAC,EAAE,UAAU,EAAE,CAAA;QACtE,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;YAC7D,MAAM,KAAK,GAAG,UAAU,CAAC,UAAU,CAAC,CAAA;YACpC,MAAM,GAAG,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAA;YAChC,IAAI,KAAK,IAAI,GAAG,KAAK,QAAQ;gBAAE,SAAQ;YACvC,MAAM,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,UAAU,CAAC,CAAA;QACzC,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["import type { MessageAnnotations } from '../../protocol.js'\nimport type { MsgSchemaShape, MsgSchemaField } from '../factory.js'\n\ntype Binding = { variant: string }\ntype Annotations = Record<string, MessageAnnotations>\n\nexport type ListActionsHost = {\n getState(): unknown\n getBindingDescriptors(): Binding[] | null\n getMsgAnnotations(): Annotations | null\n getMsgSchema(): MsgSchemaShape | null\n getAgentAffordances(): ((state: unknown) => Array<{ type: string; [k: string]: unknown }>) | null\n}\n\n/**\n * `dispatchMode` on each action is `'shared'` (human can also click via\n * a UI affordance) or `'agent-only'` (no UI binding — agent is the only\n * dispatcher). `'human-only'` variants are filtered out before this\n * point — they never reach the LLM.\n *\n * `source` distinguishes WHERE the affordance came from:\n * - `'binding'` — a tagged event handler is currently mounted in a\n * live scope (refcount > 0). Variants inside dead branches —\n * `show({when: false})`, unmounted `branch()` cases, removed `each`\n * items — auto-vanish from this set as their lifetimes dispose.\n * This is the framework's \"what can the user click right now\"\n * answer, and it's the default surface for the agent.\n * - `'always-affordable'` — either the app's `agentAffordances(state)`\n * hook listed the variant, or the variant carries the\n * `@alwaysAffordable` JSDoc tag. Both are the explicit \"agent can\n * reach this even when no live UI binding maps to it\" knob — bulk\n * seed ops (`Matrix/AddAlternatives`) and similar agent-driven\n * paths typically land here.\n * - `'schema'` — variant is annotated `@agentOnly` (the canonical\n * \"no UI button maps to this; the agent is the only dispatcher\")\n * and isn't already covered above. The payload is schema-synthesized\n * and the agent fills it in.\n *\n * `'shared'` variants WITHOUT a live binding, without\n * `agentAffordances` mention, and without `@alwaysAffordable` are\n * **deliberately hidden**. They're reachable through UI navigation —\n * the human user can't click them right now, and dispatching them\n * blindly would mutate state that drives `show()`/`branch()` gates,\n * popping hidden UI subtrees into view in places the user didn't\n * navigate to.\n */\nexport type ListActionsResult = {\n actions: Array<{\n variant: string\n /**\n * Human-readable phrase from `@intent(\"…\")`, or `null` when the\n * variant is unannotated. Mirror of LapActionsResponse.intent —\n * callers should treat `null` as a documentation gap and not as\n * \"missing label, fall back to variant name\".\n */\n intent: string | null\n requiresConfirm: boolean\n dispatchMode: 'shared' | 'agent-only'\n source: 'binding' | 'always-affordable' | 'schema'\n selectorHint: string | null\n payloadHint: object | null\n /** Cautionary text from `@warning` JSDoc, or null. */\n warning: string | null\n /** Concrete examples from `@example` JSDoc, in source order. */\n examples: string[]\n /**\n * Effect kinds this variant emits, from `@emits(\"k1\", \"k2\")`.\n * Empty when not annotated. Lets the agent know what side\n * effects fire — useful for batching (\"100 dispatches × cloud-\n * save = bad\") and for confirming destructive flows.\n */\n emits: string[]\n /**\n * Per-field guidance lifted from `@should(\"…\")` JSDoc on payload\n * fields. Path is dot/bracket notation rooted at the payload\n * (e.g. `\"cells\"` for a top-level field, `\"cells[].meta\"` for an\n * array element's nested field). Useful when the field is typed\n * as `unknown` or as a polymorphic shape — the hint says \"type\n * matches the criterion's kind: number for quantity, …\" so the\n * agent doesn't have to guess from the bare schema.\n *\n * Empty when no field on this variant carries an `@should` hint.\n */\n fieldHints: Array<{ path: string; hint: string }>\n }>\n}\n\nexport function handleListActions(host: ListActionsHost): ListActionsResult {\n const annotations = host.getMsgAnnotations() ?? {}\n const state = host.getState()\n const descriptors = host.getBindingDescriptors() ?? []\n const affordancesFn = host.getAgentAffordances()\n const affordances = affordancesFn ? affordancesFn(state) : []\n // When the app provides `agentAffordances(state)`, it's opted into\n // explicit affordance control: only state-relevant Msgs are listed.\n // `@agentOnly` schema-source variants are then filtered to those the\n // hook returned — so a bulk-edit Msg like `Matrix/AddCriteria`\n // doesn't surface on the home page just because it's tagged\n // `@agentOnly`. Apps without `agentAffordances` keep the previous\n // permissive default (\"everything's available unless you say\n // otherwise\") since flipping that without explicit opt-in would\n // break consumers who rely on schema-source surfacing of\n // bulk Msgs.\n const explicitAffordances = affordancesFn !== null\n const affordanceVariants = new Set(affordances.map((m) => m.type))\n const schema = host.getMsgSchema()\n\n const out: ListActionsResult['actions'] = []\n const seen = new Set<string>()\n\n // From bindings — these have UI affordances by definition, so they're\n // either 'shared' (default) or, in the malformed case where someone\n // bound an `@agentOnly` Msg in a view, 'agent-only'. Either way the\n // agent can dispatch them.\n //\n // Filtered against the Msg schema: a binding whose variant isn't in\n // the user's Msg union is a library-internal Msg leaking through\n // `tagSend` translator wiring (the sortable component's `move`,\n // `drop`, `cancel`, etc. — they're routed into the user's update.ts\n // via a different shape but their lib names slip into the binding\n // registry). The agent has no use for those names — `would_dispatch`\n // / `send_message` would reject them as `unknown-variant` anyway —\n // so they pollute the affordance list. When a schema is available,\n // the schema's variant set is the source of truth.\n for (const d of descriptors) {\n if (schema && !(d.variant in schema.variants)) continue\n const ann = annotations[d.variant]\n if (ann?.dispatchMode === 'human-only') continue\n if (!passesRouteGate(ann, state)) continue\n seen.add(d.variant)\n const variantSchema = schema?.variants[d.variant]\n out.push({\n variant: d.variant,\n intent: ann?.intent ?? null,\n requiresConfirm: ann?.requiresConfirm ?? false,\n dispatchMode: ann?.dispatchMode === 'agent-only' ? 'agent-only' : 'shared',\n source: 'binding',\n selectorHint: null,\n payloadHint: null,\n warning: ann?.warning ?? null,\n examples: ann?.examples ?? [],\n emits: ann?.emits ?? [],\n fieldHints: variantSchema ? collectFieldHints(variantSchema) : [],\n })\n }\n\n // From `agentAffordances(state)` — the integrator's explicit list of\n // currently-reachable Msgs, with concrete payloads they author.\n for (const msg of affordances) {\n const ann = annotations[msg.type]\n if (ann?.dispatchMode === 'human-only') continue\n if (!passesRouteGate(ann, state)) continue\n seen.add(msg.type)\n const { type, ...rest } = msg\n const variantSchema = schema?.variants[type]\n out.push({\n variant: type,\n intent: ann?.intent ?? null,\n requiresConfirm: ann?.requiresConfirm ?? false,\n dispatchMode: ann?.dispatchMode === 'agent-only' ? 'agent-only' : 'shared',\n source: 'always-affordable',\n selectorHint: null,\n payloadHint: Object.keys(rest).length > 0 ? rest : null,\n warning: ann?.warning ?? null,\n examples: ann?.examples ?? [],\n emits: ann?.emits ?? [],\n fieldHints: variantSchema ? collectFieldHints(variantSchema) : [],\n })\n }\n\n // From `@alwaysAffordable` annotations — the per-variant equivalent\n // of `agentAffordances`. Variants tagged this way surface regardless\n // of whether a live binding maps to them, so bulk seed ops\n // (`Matrix/AddAlternatives`) and similar agent-driven paths are\n // available even when their UI counterparts (if any) aren't mounted.\n // The payload is schema-synthesized — `agentAffordances` is the way\n // to ship a concrete pre-filled payload alongside the affordance.\n for (const [variant, ann] of Object.entries(annotations)) {\n if (seen.has(variant)) continue\n if (ann.dispatchMode === 'human-only') continue\n if (!ann.alwaysAffordable) continue\n if (!passesRouteGate(ann, state)) continue\n seen.add(variant)\n const fields = schema?.variants[variant]\n out.push({\n variant,\n intent: ann.intent,\n requiresConfirm: ann.requiresConfirm,\n dispatchMode: ann.dispatchMode === 'agent-only' ? 'agent-only' : 'shared',\n source: 'always-affordable',\n selectorHint: null,\n payloadHint: fields ? synthesizePayload(variant, fields) : null,\n warning: ann.warning,\n examples: ann.examples,\n emits: ann.emits,\n fieldHints: fields ? collectFieldHints(fields) : [],\n })\n }\n\n // From schema — variants that aren't already surfaced above and that\n // the author marked `@agentOnly`. The canonical \"no UI button maps\n // to this; the agent is the only dispatcher.\" Bulk edits, imports,\n // admin operations that have no human-facing affordance at all.\n //\n // `'shared'` variants WITHOUT a live binding stay hidden here — they\n // are reachable through UI navigation, and dispatching them while\n // their UI subtree is unmounted would pop hidden state in places the\n // user didn't navigate to. The explicit knobs are `@alwaysAffordable`\n // (handled above) or `agentAffordances(state)`.\n //\n // When the app provides `agentAffordances`, this pass is filtered:\n // an `@agentOnly` variant only surfaces if the hook returned it.\n // That makes route-gated bulk Msgs (`Matrix/AddCriteria` available\n // only when a matrix is loaded) work as expected — they stop\n // appearing on the home page just because they're tagged\n // `@agentOnly`. Apps without `agentAffordances` keep the previous\n // permissive default.\n if (schema) {\n for (const [variant, fields] of Object.entries(schema.variants)) {\n if (seen.has(variant)) continue\n const ann = annotations[variant]\n if (ann?.dispatchMode !== 'agent-only') continue\n if (explicitAffordances && !affordanceVariants.has(variant)) continue\n if (!passesRouteGate(ann, state)) continue\n out.push({\n variant,\n intent: ann.intent,\n requiresConfirm: ann.requiresConfirm,\n dispatchMode: 'agent-only',\n source: 'schema',\n selectorHint: null,\n payloadHint: synthesizePayload(variant, fields),\n warning: ann.warning,\n examples: ann.examples,\n emits: ann.emits,\n fieldHints: collectFieldHints(fields),\n })\n }\n }\n\n return { actions: out }\n}\n\n/**\n * Build an example payload object the LLM can fill in. Required\n * fields always appear; optional fields appear only when annotated\n * `@should` (LLM is encouraged to fill them in). Fields without a\n * concrete primitive type (`'unknown'`) emit `null` placeholders the\n * LLM is expected to replace.\n *\n * The first key is `type` so the payload reads as a complete Msg\n * shape — copy-paste-ready into `send_message`.\n */\n/**\n * Evaluate `@routeGated(\"predicate\")` against the current state.\n * Returns true (variant passes) when:\n * - the variant has no `@routeGated` annotation, OR\n * - the predicate evaluates truthy with `state` bound.\n *\n * Predicate is compiled lazily via `new Function('state', 'return (' +\n * src + ')')` and cached in a module-level Map. Compile failures\n * (syntactically broken predicates) degrade to \"true\" so a single\n * malformed annotation doesn't paralyze the affordance pass — the\n * build-time linter is the right place to catch syntactic issues.\n * Evaluation throws fail-closed (return false) since a predicate that\n * crashes on the current state shouldn't surface the variant.\n */\nfunction passesRouteGate(ann: MessageAnnotations | undefined, state: unknown): boolean {\n const src = ann?.routeGate\n if (!src) return true\n const predicate = compileRouteGate(src)\n try {\n return Boolean(predicate(state))\n } catch {\n return false\n }\n}\n\nconst routeGateCache = new Map<string, (state: unknown) => boolean>()\nfunction compileRouteGate(src: string): (state: unknown) => boolean {\n let fn = routeGateCache.get(src)\n if (fn) return fn\n try {\n fn = new Function('state', `return (${src})`) as (state: unknown) => boolean\n } catch {\n fn = () => true\n }\n routeGateCache.set(src, fn)\n return fn\n}\n\nfunction synthesizePayload(variant: string, fields: Record<string, MsgSchemaField>): object {\n const out: Record<string, unknown> = { type: variant }\n for (const [name, descriptor] of Object.entries(fields)) {\n const optional = isOptional(descriptor)\n const priority = isShould(descriptor)\n // Skip optional fields unless they're @should-flagged. Required\n // fields always appear.\n if (optional && priority !== 'should') continue\n out[name] = exampleValue(descriptor)\n }\n return out\n}\n\n/**\n * Walk a variant's field tree and collect every `@should` hint into a\n * flat list keyed by field path. Path conventions:\n * - top-level field: `\"cells\"`\n * - nested object property: `\"cells.value\"`\n * - array element: `\"cells[]\"` for the element itself; descendants\n * use `\"cells[].meta\"` and so on.\n *\n * Surfaces the same hints that show up nested inside\n * `description.messages.variants[X].field.hint` so callers don't have\n * to dig through the schema tree to find them.\n */\nfunction collectFieldHints(\n fields: Record<string, MsgSchemaField>,\n): Array<{ path: string; hint: string }> {\n const out: Array<{ path: string; hint: string }> = []\n for (const [name, descriptor] of Object.entries(fields)) {\n walkHint(name, descriptor, out)\n }\n return out\n}\n\nfunction walkHint(\n path: string,\n d: MsgSchemaField,\n out: Array<{ path: string; hint: string }>,\n): void {\n // Rich descriptor with a hint at this position.\n if (typeof d === 'object' && d !== null && 'type' in d) {\n if (typeof d.hint === 'string' && d.hint.length > 0) {\n out.push({ path, hint: d.hint })\n }\n // `@validates(...)` predicates surface alongside `@should` hints\n // so the agent sees the constraint at affordance time rather than\n // only as a post-dispatch rejection. The verbatim predicate text\n // is what the runtime evaluates; agents trained on JS read it\n // directly. Prefix `validates: ` to disambiguate from freeform\n // `@should` text.\n if (typeof d.validates === 'string' && d.validates.length > 0) {\n out.push({ path, hint: `validates: ${d.validates}` })\n }\n walkHintBare(path, d.type, out)\n return\n }\n walkHintBare(path, d, out)\n}\n\nfunction walkHintBare(path: string, t: unknown, out: Array<{ path: string; hint: string }>): void {\n if (t === null || typeof t !== 'object') return\n const obj = t as Record<string, unknown>\n if (obj.kind === 'object' && obj.shape !== null && typeof obj.shape === 'object') {\n for (const [name, descriptor] of Object.entries(obj.shape as Record<string, MsgSchemaField>)) {\n walkHint(`${path}.${name}`, descriptor, out)\n }\n return\n }\n if (obj.kind === 'array') {\n walkHint(`${path}[]`, obj.element as MsgSchemaField, out)\n }\n if (obj.kind === 'discriminated-union') {\n // Synthetic hint at the union's path summarizing the legal\n // discriminant values. Lets the agent see \"format expects one of:\n // exact, range, compound\" without walking the full schema. Then\n // walk each branch's per-field hints with a path-suffix that\n // disambiguates which branch the hint applies to.\n const variants = obj.variants as Record<string, Record<string, MsgSchemaField>>\n const discriminant = String(obj.discriminant)\n const legalValues = Object.keys(variants)\n if (legalValues.length > 0) {\n out.push({\n path,\n hint: `Discriminated union — set \\`${discriminant}\\` to one of: ${legalValues\n .map((v) => `'${v}'`)\n .join(', ')}.`,\n })\n }\n for (const [discValue, fields] of Object.entries(variants)) {\n for (const [fieldName, fieldDesc] of Object.entries(fields)) {\n walkHint(`${path}(${discriminant}=${discValue}).${fieldName}`, fieldDesc, out)\n }\n }\n }\n}\n\nfunction isOptional(d: MsgSchemaField): boolean {\n return typeof d === 'object' && 'type' in d && d.optional === true\n}\n\nfunction isShould(d: MsgSchemaField): 'should' | undefined {\n return typeof d === 'object' && 'type' in d ? d.priority : undefined\n}\n\nfunction exampleValue(d: MsgSchemaField): unknown {\n // Unwrap rich descriptor to get the bare type for synthesis.\n const t =\n typeof d === 'object' && 'type' in d\n ? d.type\n : (d as\n | Exclude<MsgSchemaField, object>\n | Extract<MsgSchemaField, { kind?: string; enum?: string[] }>)\n return synthesizeBare(t as never)\n}\n\nfunction synthesizeBare(t: unknown): unknown {\n if (typeof t === 'string') {\n if (t === 'string') return ''\n if (t === 'number') return 0\n if (t === 'boolean') return false\n return null // 'unknown' or unrecognized keyword → placeholder\n }\n if (t === null || typeof t !== 'object') return null\n const obj = t as Record<string, unknown>\n if ('enum' in obj && Array.isArray(obj.enum)) {\n // First option doubles as the canonical example. Native value type\n // round-trips (string/number/boolean) since the compiler preserved\n // the literal kind on emit.\n return obj.enum[0] ?? null\n }\n if (obj.kind === 'object' && obj.shape !== null && typeof obj.shape === 'object') {\n // Recurse into the nested shape. Same optional-skip rule as the\n // top-level synthesizer: required fields appear, optional ones\n // appear only when @should-flagged.\n const out: Record<string, unknown> = {}\n for (const [name, descriptor] of Object.entries(obj.shape as Record<string, MsgSchemaField>)) {\n const isOpt = isOptional(descriptor)\n const pri = isShould(descriptor)\n if (isOpt && pri !== 'should') continue\n out[name] = exampleValue(descriptor)\n }\n return out\n }\n if (obj.kind === 'array') {\n // Wrap the synthesized element in a one-item array. Lets the LLM\n // see the per-entry shape without us guessing at array length.\n return [synthesizeBare(obj.element)]\n }\n if (obj.kind === 'discriminated-union') {\n // Synthesize the FIRST branch as the concrete example. The full\n // shape (every legal branch + its payload) is preserved in\n // `description.messages.variants[X]` from `describe_app`, so the\n // agent that needs another branch reads the schema directly.\n // `collectFieldHints` adds a synthetic enumeration of the legal\n // `<discriminant>` values onto the hint surface so the agent\n // doesn't have to dig into the schema for the simple case.\n const variants = obj.variants as Record<string, Record<string, MsgSchemaField>>\n const discriminant = String(obj.discriminant)\n const firstEntry = Object.entries(variants).at(0)\n if (!firstEntry) return null\n const [firstValue, firstFields] = firstEntry\n const branch: Record<string, unknown> = { [discriminant]: firstValue }\n for (const [name, descriptor] of Object.entries(firstFields)) {\n const isOpt = isOptional(descriptor)\n const pri = isShould(descriptor)\n if (isOpt && pri !== 'should') continue\n branch[name] = exampleValue(descriptor)\n }\n return branch\n }\n return null\n}\n"]}
@@ -60,7 +60,17 @@ function validateObjectShape(value, shape, pathPrefix, errors, warnings, policy)
60
60
  const optional = isOptional(descriptor);
61
61
  const fieldValue = present ? value[name] : undefined;
62
62
  if (!present || fieldValue === undefined) {
63
- if (!optional) {
63
+ // Treat `unknown`-typed fields as implicitly optional. The
64
+ // schema extractor emits `field: string | undefined` as a
65
+ // required field of type 'unknown' (the union isn't a branded
66
+ // primitive), but semantically the field accepts undefined —
67
+ // and the validator's stated philosophy is "treat 'unknown' as
68
+ // any goes; don't report errors against fields whose schema we
69
+ // don't know." Without this, agents are forced to spell out
70
+ // `details: undefined`, `url: undefined`, … on every Criterion
71
+ // they author, which is exactly the kind of fumble we built the
72
+ // payload hints to prevent.
73
+ if (!optional && fieldType(descriptor) !== 'unknown') {
64
74
  errors.push({
65
75
  path: fieldPath,
66
76
  code: 'missing',
@@ -257,7 +267,6 @@ function compilePredicate(src) {
257
267
  if (fn)
258
268
  return fn;
259
269
  try {
260
- // eslint-disable-next-line @typescript-eslint/no-implied-eval
261
270
  fn = new Function('v', `return (${src})`);
262
271
  }
263
272
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"validate-payload.js","sourceRoot":"","sources":["../../../src/client/rpc/validate-payload.ts"],"names":[],"mappings":"AA4EA,MAAM,UAAU,eAAe,CAC7B,GAAY,EACZ,MAA6B,EAC7B,OAA0B,EAAE;IAE5B,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QAClE,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,4BAA4B,EAAE,CAAC;SAClF,CAAA;IACH,CAAC;IACD,MAAM,CAAC,GAAG,GAA8B,CAAA;IACxC,MAAM,UAAU,GAAG,CAAC,CAAC,MAAM,EAAE,YAAY,IAAI,MAAM,CAAC,CAAA;IACpD,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QACnC,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE;gBACN;oBACE,IAAI,EAAE,MAAM,EAAE,YAAY,IAAI,MAAM;oBACpC,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE,OAAO,MAAM,EAAE,YAAY,IAAI,MAAM,+BAA+B;iBAC9E;aACF;SACF,CAAA;IACH,CAAC;IAED,oEAAoE;IACpE,mEAAmE;IACnE,wDAAwD;IACxD,IAAI,CAAC,MAAM;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAA;IAEhC,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;IACjD,IAAI,CAAC,aAAa,EAAE,CAAC;QACnB,OAAO;YACL,EAAE,EAAE,KAAK;YACT,MAAM,EAAE;gBACN;oBACE,IAAI,EAAE,MAAM,CAAC,YAAY;oBACzB,IAAI,EAAE,iBAAiB;oBACvB,OAAO,EAAE,IAAI,UAAU,2CAA2C,MAAM,CAAC,IAAI,CAC3E,MAAM,CAAC,QAAQ,CAChB;yBACE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;yBACpB,IAAI,CAAC,IAAI,CAAC,GAAG;iBACjB;aACF;SACF,CAAA;IACH,CAAC;IAED,MAAM,MAAM,GAAsB,EAAE,CAAA;IACpC,MAAM,QAAQ,GAAwB,EAAE,CAAA;IACxC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,SAAS,CAAA;IACvC,MAAM,OAAO,GAA4B,EAAE,CAAA;IAC3C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QACvC,IAAI,CAAC,KAAK,MAAM,CAAC,YAAY;YAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;IAC/C,CAAC;IACD,mBAAmB,CAAC,OAAO,EAAE,aAAa,EAAE,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;IACzE,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACxB,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAA;IACtE,CAAC;IACD,OAAO,QAAQ,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAA;AACxF,CAAC;AAED,SAAS,mBAAmB,CAC1B,KAA8B,EAC9B,KAAqC,EACrC,UAAkB,EAClB,MAAyB,EACzB,QAA6B,EAC7B,MAA4B;IAE5B,KAAK,MAAM,CAAC,IAAI,EAAE,UAAU,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACvD,MAAM,SAAS,GAAG,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,IAAI,EAAE,CAAA;QACpE,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QACjE,MAAM,QAAQ,GAAG,UAAU,CAAC,UAAU,CAAC,CAAA;QACvC,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;QAEpD,IAAI,CAAC,OAAO,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACd,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,SAAS;oBACf,IAAI,EAAE,SAAS;oBACf,OAAO,EAAE,2BAA2B;iBACrC,CAAC,CAAA;YACJ,CAAC;YACD,SAAQ;QACV,CAAC;QAED,MAAM,EAAE,GAAG,SAAS,CAAC,UAAU,CAAC,CAAA;QAChC,IAAI,EAAE,KAAK,SAAS,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YAC5C,QAAQ,CAAC,IAAI,CAAC;gBACZ,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,eAAe;gBACrB,OAAO,EAAE,qMAAqM;aAC/M,CAAC,CAAA;QACJ,CAAC;QAED,MAAM,cAAc,GAAG,MAAM,CAAC,MAAM,CAAA;QACpC,aAAa,CAAC,UAAU,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;QAClE,MAAM,iBAAiB,GAAG,MAAM,CAAC,MAAM,KAAK,cAAc,CAAA;QAE1D,+DAA+D;QAC/D,iEAAiE;QACjE,kEAAkE;QAClE,mEAAmE;QACnE,kEAAkE;QAClE,8DAA8D;QAC9D,gBAAgB;QAChB,IAAI,iBAAiB,EAAE,CAAC;YACtB,MAAM,SAAS,GAAG,uBAAuB,CAAC,UAAU,CAAC,CAAA;YACrD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBACvB,MAAM,SAAS,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAA;gBAC7C,IAAI,MAAe,CAAA;gBACnB,IAAI,CAAC;oBACH,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAA;gBACzC,CAAC;gBAAC,MAAM,CAAC;oBACP,MAAM,GAAG,KAAK,CAAA;gBAChB,CAAC;gBACD,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,MAAM,CAAC,IAAI,CAAC;wBACV,IAAI,EAAE,SAAS;wBACf,IAAI,EAAE,kBAAkB;wBACxB,OAAO,EAAE,gCAAgC,SAAS,MAAM;qBACzD,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,iEAAiE;IACjE,gEAAgE;IAChE,gEAAgE;IAChE,oEAAoE;IACpE,sCAAsC;IACtC,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;QACxB,KAAK,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC;YACrC,IAAI,GAAG,IAAI,KAAK;gBAAE,SAAQ;YAC1B,MAAM,SAAS,GAAG,UAAU,KAAK,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,GAAG,EAAE,CAAA;YAClE,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,SAAS;gBACf,IAAI,EAAE,kBAAkB;gBACxB,OAAO,EAAE,UAAU,GAAG,yCAAyC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC;qBAC9E,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;qBACpB,IAAI,CAAC,IAAI,CAAC,GAAG;aACjB,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CACpB,KAAc,EACd,IAAuB,EACvB,IAAY,EACZ,MAAyB,EACzB,QAA6B,EAC7B,MAA4B;IAE5B,IAAI,IAAI,KAAK,SAAS;QAAE,OAAM,CAAC,8BAA8B;IAC7D,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,oDAAoD;QACpD,IAAI,OAAO,KAAK,KAAK,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,YAAY,IAAI,SAAS,YAAY,CAAC,KAAK,CAAC,EAAE;aACxD,CAAC,CAAA;QACJ,CAAC;QACD,OAAM;IACR,CAAC;IACD,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACnB,iEAAiE;QACjE,iCAAiC;QACjC,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,KAAK,KAAK,KAAK,CAAC,CAAA;QAChF,IAAI,CAAC,EAAE,EAAE,CAAC;YACR,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,aAAa;gBACnB,OAAO,EAAE,IAAI,MAAM,CAAC,KAAK,CAAC,uCAAuC,IAAI,CAAC,IAAI;qBACvE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;qBAC9B,IAAI,CAAC,IAAI,CAAC,GAAG;aACjB,CAAC,CAAA;QACJ,CAAC;QACD,OAAM;IACR,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACxE,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,wBAAwB,YAAY,CAAC,KAAK,CAAC,EAAE;aACvD,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QACD,mBAAmB,CACjB,KAAgC,EAChC,IAAI,CAAC,KAAK,EACV,IAAI,EACJ,MAAM,EACN,QAAQ,EACR,MAAM,CACP,CAAA;QACD,OAAM;IACR,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAC1B,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,uBAAuB,YAAY,CAAC,KAAK,CAAC,EAAE;aACtD,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;QAClF,CAAC;QACD,OAAM;IACR,CAAC;IACD,IAAI,IAAI,CAAC,IAAI,KAAK,qBAAqB,EAAE,CAAC;QACxC,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;YACxE,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI;gBACJ,IAAI,EAAE,YAAY;gBAClB,OAAO,EAAE,4CAA4C,YAAY,CAAC,KAAK,CAAC,EAAE;aAC3E,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QACD,MAAM,GAAG,GAAG,KAAgC,CAAA;QAC5C,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,YAAY,CAAC,CAAA;QACxC,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;YAClC,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,GAAG,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE;gBACpC,IAAI,EAAE,sBAAsB;gBAC5B,OAAO,EAAE,iBAAiB,IAAI,CAAC,YAAY,qBAAqB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC;qBACvF,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;qBACpB,IAAI,CAAC,IAAI,CAAC,EAAE;aAChB,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QACD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAA;QAC7C,IAAI,CAAC,YAAY,EAAE,CAAC;YAClB,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,GAAG,IAAI,IAAI,IAAI,CAAC,YAAY,EAAE;gBACpC,IAAI,EAAE,4BAA4B;gBAClC,OAAO,EAAE,IAAI,SAAS,qBAAqB,IAAI,CAAC,YAAY,oBAAoB,MAAM,CAAC,IAAI,CACzF,IAAI,CAAC,QAAQ,CACd;qBACE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC;qBACpB,IAAI,CAAC,IAAI,CAAC,GAAG;aACjB,CAAC,CAAA;YACF,OAAM;QACR,CAAC;QACD,2DAA2D;QAC3D,0DAA0D;QAC1D,MAAM,aAAa,GAA4B,EAAE,CAAA;QACjD,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACzC,IAAI,CAAC,KAAK,IAAI,CAAC,YAAY;gBAAE,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAA;QACnD,CAAC;QACD,MAAM,UAAU,GAAG,GAAG,IAAI,IAAI,IAAI,CAAC,YAAY,IAAI,SAAS,GAAG,CAAA;QAC/D,mBAAmB,CAAC,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAA;IACxF,CAAC;AACH,CAAC;AAED,SAAS,UAAU,CAAC,CAAiB;IACnC,OAAO,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,IAAI,CAAA;AAClF,CAAC;AAED,SAAS,SAAS,CAAC,CAAiB;IAClC,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,MAAM,IAAI,CAAC;QAAE,OAAO,CAAC,CAAC,IAAI,CAAA;IACrE,OAAO,CAAC,CAAA;AACV,CAAC;AAED,SAAS,uBAAuB,CAAC,CAAiB;IAChD,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,IAAI,MAAM,IAAI,CAAC,IAAI,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,EAAE,CAAC;QAC1F,OAAO,CAAC,CAAC,SAAS,CAAA;IACpB,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED,MAAM,cAAc,GAAG,IAAI,GAAG,EAAmC,CAAA;AAEjE;;;;;;;;;;GAUG;AACH,SAAS,gBAAgB,CAAC,GAAW;IACnC,IAAI,EAAE,GAAG,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IAChC,IAAI,EAAE;QAAE,OAAO,EAAE,CAAA;IACjB,IAAI,CAAC;QACH,8DAA8D;QAC9D,EAAE,GAAG,IAAI,QAAQ,CAAC,GAAG,EAAE,WAAW,GAAG,GAAG,CAA4B,CAAA;IACtE,CAAC;IAAC,MAAM,CAAC;QACP,EAAE,GAAG,GAAG,EAAE,CAAC,IAAI,CAAA;IACjB,CAAC;IACD,cAAc,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,CAAA;IAC3B,OAAO,EAAE,CAAA;AACX,CAAC;AAED,SAAS,YAAY,CAAC,CAAU;IAC9B,IAAI,CAAC,KAAK,IAAI;QAAE,OAAO,MAAM,CAAA;IAC7B,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAAE,OAAO,OAAO,CAAA;IACpC,OAAO,OAAO,CAAC,CAAA;AACjB,CAAC;AAED,SAAS,eAAe,CAAC,CAA4B;IACnD,OAAO,OAAO,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;AACrD,CAAC","sourcesContent":["import type { MsgSchemaShape, MsgSchemaField, MsgSchemaBareType } from '../factory.js'\n\n/**\n * Schema-driven payload validation for agent-dispatched Msgs. Walks\n * the compiler-emitted schema against a candidate Msg and reports\n * structural errors with a path-keyed list — the kind of feedback an\n * LLM can act on in a single round trip (\"set kind to one of: 'exact',\n * 'range', 'compound'\") instead of probing one field at a time.\n *\n * **What this is not.** This is not a TS type-checker. The schema is\n * best-effort: cross-file types, generics, complex unions, and\n * conditional types still surface as `'unknown'` and the validator\n * accepts anything for those. The validator's job is to catch the\n * mistakes a schema-aware LLM makes — wrong enum values, missing\n * discriminants, primitive type mismatches — not to mirror the entire\n * TypeScript surface area.\n *\n * **Tolerance for `'unknown'`.** Treat `'unknown'` as \"any goes.\" Don't\n * report errors against fields whose schema we don't know — those are\n * the schema's gaps, not the agent's.\n */\n\nexport type ValidationError = {\n /**\n * Dot-bracket path rooted at the Msg payload (NOT including `type`).\n * - top-level field: `'cells'`\n * - nested object property: `'cells.value'`\n * - array element: `'cells[0]'` (concrete index from the input)\n * - discriminated-union branch: `'format(kind=range).max'` — the\n * parenthesised `<discriminant>=<value>` segment names which branch\n * the error applies to, distinguishing the same field name across\n * branches.\n */\n path: string\n code:\n | 'unknown-variant'\n | 'missing'\n | 'wrong-type'\n | 'not-in-enum'\n | 'not-array'\n | 'not-object'\n | 'missing-discriminant'\n | 'unknown-discriminant-value'\n | 'unexpected-field'\n | 'validates-failed'\n message: string\n}\n\nexport type ValidationWarning = {\n path: string\n code: 'untyped-field'\n message: string\n}\n\nexport type ValidationResult =\n | { ok: true; warnings?: ValidationWarning[] }\n | { ok: false; errors: ValidationError[]; warnings?: ValidationWarning[] }\n\nexport type ValidationOptions = {\n /**\n * `'strict'` rejects fields that aren't declared in the schema (typos,\n * extra keys, fields the LLM hallucinated). Also emits warnings when\n * the agent provides a value for a field whose schema is `'unknown'`\n * — the validator can't structurally check the value, so the warning\n * surfaces the gap to the LLM (\"we accepted this but didn't validate\n * it\"). `'lenient'` (default) accepts extras silently and treats\n * `'unknown'` as a passthrough.\n *\n * Strict mode pairs with the cross-file schema fidelity in\n * `@llui/vite-plugin`@0.0.36+: with most fields fully resolved, strict\n * is rarely surprising. Apps that haven't migrated yet may find\n * strict overzealous and should stay on lenient.\n */\n policy?: 'strict' | 'lenient'\n}\n\nexport function validatePayload(\n msg: unknown,\n schema: MsgSchemaShape | null,\n opts: ValidationOptions = {},\n): ValidationResult {\n if (msg === null || typeof msg !== 'object' || Array.isArray(msg)) {\n return {\n ok: false,\n errors: [{ path: '', code: 'not-object', message: 'msg must be a plain object' }],\n }\n }\n const m = msg as Record<string, unknown>\n const variantKey = m[schema?.discriminant ?? 'type']\n if (typeof variantKey !== 'string') {\n return {\n ok: false,\n errors: [\n {\n path: schema?.discriminant ?? 'type',\n code: 'missing',\n message: `msg.${schema?.discriminant ?? 'type'} must be a string variant tag`,\n },\n ],\n }\n }\n\n // No schema available — the compiler didn't emit one, or the LLM is\n // talking to a build that predates schema emission. Accept the msg\n // structurally; the reducer will validate semantically.\n if (!schema) return { ok: true }\n\n const variantSchema = schema.variants[variantKey]\n if (!variantSchema) {\n return {\n ok: false,\n errors: [\n {\n path: schema.discriminant,\n code: 'unknown-variant',\n message: `'${variantKey}' is not a known variant. Legal values: ${Object.keys(\n schema.variants,\n )\n .map((v) => `'${v}'`)\n .join(', ')}.`,\n },\n ],\n }\n }\n\n const errors: ValidationError[] = []\n const warnings: ValidationWarning[] = []\n const policy = opts.policy ?? 'lenient'\n const payload: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(m)) {\n if (k !== schema.discriminant) payload[k] = v\n }\n validateObjectShape(payload, variantSchema, '', errors, warnings, policy)\n if (errors.length === 0) {\n return warnings.length === 0 ? { ok: true } : { ok: true, warnings }\n }\n return warnings.length === 0 ? { ok: false, errors } : { ok: false, errors, warnings }\n}\n\nfunction validateObjectShape(\n value: Record<string, unknown>,\n shape: Record<string, MsgSchemaField>,\n pathPrefix: string,\n errors: ValidationError[],\n warnings: ValidationWarning[],\n policy: 'strict' | 'lenient',\n): void {\n for (const [name, descriptor] of Object.entries(shape)) {\n const fieldPath = pathPrefix === '' ? name : `${pathPrefix}.${name}`\n const present = Object.prototype.hasOwnProperty.call(value, name)\n const optional = isOptional(descriptor)\n const fieldValue = present ? value[name] : undefined\n\n if (!present || fieldValue === undefined) {\n if (!optional) {\n errors.push({\n path: fieldPath,\n code: 'missing',\n message: `required field is missing`,\n })\n }\n continue\n }\n\n const ft = fieldType(descriptor)\n if (ft === 'unknown' && policy === 'strict') {\n warnings.push({\n path: fieldPath,\n code: 'untyped-field',\n message: `value accepted but field schema is 'unknown' — the validator could not structurally check it. If this field is reachable across file boundaries, consider whether @llui/vite-plugin can resolve it.`,\n })\n }\n\n const errCountBefore = errors.length\n validateField(fieldValue, ft, fieldPath, errors, warnings, policy)\n const structurallyValid = errors.length === errCountBefore\n\n // Domain-invariant predicate (`@validates(\"expr\")`). Runs only\n // when structural validation passed for this field — without the\n // right shape, the predicate would either throw (and we'd have to\n // double-report) or accidentally pass (e.g. `v.length` on a string\n // when we expected a number array). Predicate failures are errors\n // regardless of policy — the author opted into the constraint\n // deliberately.\n if (structurallyValid) {\n const validates = fieldValidatesPredicate(descriptor)\n if (validates !== null) {\n const predicate = compilePredicate(validates)\n let passed: boolean\n try {\n passed = Boolean(predicate(fieldValue))\n } catch {\n passed = false\n }\n if (!passed) {\n errors.push({\n path: fieldPath,\n code: 'validates-failed',\n message: `value violates \\`@validates(\"${validates}\")\\``,\n })\n }\n }\n }\n }\n\n // Strict mode: reject fields the schema doesn't declare. Catches\n // typos (`{tile: 'X'}` instead of `{title: 'X'}`), hallucinated\n // fields, and stale field names from before a refactor. Lenient\n // mode accepts extras silently — same shape TypeScript's structural\n // subtyping accepts at the call site.\n if (policy === 'strict') {\n for (const key of Object.keys(value)) {\n if (key in shape) continue\n const fieldPath = pathPrefix === '' ? key : `${pathPrefix}.${key}`\n errors.push({\n path: fieldPath,\n code: 'unexpected-field',\n message: `field '${key}' is not in the schema. Legal fields: ${Object.keys(shape)\n .map((k) => `'${k}'`)\n .join(', ')}.`,\n })\n }\n }\n}\n\nfunction validateField(\n value: unknown,\n type: MsgSchemaBareType,\n path: string,\n errors: ValidationError[],\n warnings: ValidationWarning[],\n policy: 'strict' | 'lenient',\n): void {\n if (type === 'unknown') return // schema gap; accept anything\n if (typeof type === 'string') {\n // Primitive keyword: 'string', 'number', 'boolean'.\n if (typeof value !== type) {\n errors.push({\n path,\n code: 'wrong-type',\n message: `expected ${type}, got ${describeType(value)}`,\n })\n }\n return\n }\n if ('enum' in type) {\n // Use Object.is so NaN and -0 match correctly; falls back to ===\n // semantics for ordinary values.\n const ok = type.enum.some((legal) => Object.is(legal, value) || legal === value)\n if (!ok) {\n errors.push({\n path,\n code: 'not-in-enum',\n message: `'${String(value)}' is not in the enum. Legal values: ${type.enum\n .map((v) => formatEnumValue(v))\n .join(', ')}.`,\n })\n }\n return\n }\n if (type.kind === 'object') {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n errors.push({\n path,\n code: 'not-object',\n message: `expected object, got ${describeType(value)}`,\n })\n return\n }\n validateObjectShape(\n value as Record<string, unknown>,\n type.shape,\n path,\n errors,\n warnings,\n policy,\n )\n return\n }\n if (type.kind === 'array') {\n if (!Array.isArray(value)) {\n errors.push({\n path,\n code: 'not-array',\n message: `expected array, got ${describeType(value)}`,\n })\n return\n }\n for (let i = 0; i < value.length; i++) {\n validateField(value[i], type.element, `${path}[${i}]`, errors, warnings, policy)\n }\n return\n }\n if (type.kind === 'discriminated-union') {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n errors.push({\n path,\n code: 'not-object',\n message: `expected discriminated-union object, got ${describeType(value)}`,\n })\n return\n }\n const obj = value as Record<string, unknown>\n const discValue = obj[type.discriminant]\n if (typeof discValue !== 'string') {\n errors.push({\n path: `${path}.${type.discriminant}`,\n code: 'missing-discriminant',\n message: `discriminant '${type.discriminant}' must be one of: ${Object.keys(type.variants)\n .map((v) => `'${v}'`)\n .join(', ')}`,\n })\n return\n }\n const branchSchema = type.variants[discValue]\n if (!branchSchema) {\n errors.push({\n path: `${path}.${type.discriminant}`,\n code: 'unknown-discriminant-value',\n message: `'${discValue}' is not a legal '${type.discriminant}'. Legal values: ${Object.keys(\n type.variants,\n )\n .map((v) => `'${v}'`)\n .join(', ')}.`,\n })\n return\n }\n // Recurse into the matched branch's payload (excluding the\n // discriminant itself, which is already validated above).\n const branchPayload: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(obj)) {\n if (k !== type.discriminant) branchPayload[k] = v\n }\n const branchPath = `${path}(${type.discriminant}=${discValue})`\n validateObjectShape(branchPayload, branchSchema, branchPath, errors, warnings, policy)\n }\n}\n\nfunction isOptional(d: MsgSchemaField): boolean {\n return typeof d === 'object' && d !== null && 'type' in d && d.optional === true\n}\n\nfunction fieldType(d: MsgSchemaField): MsgSchemaBareType {\n if (typeof d === 'object' && d !== null && 'type' in d) return d.type\n return d\n}\n\nfunction fieldValidatesPredicate(d: MsgSchemaField): string | null {\n if (typeof d === 'object' && d !== null && 'type' in d && typeof d.validates === 'string') {\n return d.validates\n }\n return null\n}\n\nconst predicateCache = new Map<string, (v: unknown) => boolean>()\n\n/**\n * Compile a `@validates(...)` predicate string into a runtime function.\n * Caches across calls — the schema is static at runtime, so each\n * predicate is compiled at most once.\n *\n * The predicate sees `v` as the field's value and inherits the host\n * environment's globals (Math, JSON, RegExp, etc.). On any compile\n * error, returns a no-op `() => true` so a malformed predicate doesn't\n * break dispatch — the build-time linter (`agent-validates-syntax`,\n * future) is the right place to catch syntactic issues.\n */\nfunction compilePredicate(src: string): (v: unknown) => boolean {\n let fn = predicateCache.get(src)\n if (fn) return fn\n try {\n // eslint-disable-next-line @typescript-eslint/no-implied-eval\n fn = new Function('v', `return (${src})`) as (v: unknown) => boolean\n } catch {\n fn = () => true\n }\n predicateCache.set(src, fn)\n return fn\n}\n\nfunction describeType(v: unknown): string {\n if (v === null) return 'null'\n if (Array.isArray(v)) return 'array'\n return typeof v\n}\n\nfunction formatEnumValue(v: string | number | boolean): string {\n return typeof v === 'string' ? `'${v}'` : String(v)\n}\n"]}
1
+ {"version":3,"file":"validate-payload.js","sourceRoot":"","sources":["../../../src/client/rpc/validate-payload.ts"],"names":[],"mappings":"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","sourcesContent":["import type { MsgSchemaShape, MsgSchemaField, MsgSchemaBareType } from '../factory.js'\n\n/**\n * Schema-driven payload validation for agent-dispatched Msgs. Walks\n * the compiler-emitted schema against a candidate Msg and reports\n * structural errors with a path-keyed list — the kind of feedback an\n * LLM can act on in a single round trip (\"set kind to one of: 'exact',\n * 'range', 'compound'\") instead of probing one field at a time.\n *\n * **What this is not.** This is not a TS type-checker. The schema is\n * best-effort: cross-file types, generics, complex unions, and\n * conditional types still surface as `'unknown'` and the validator\n * accepts anything for those. The validator's job is to catch the\n * mistakes a schema-aware LLM makes — wrong enum values, missing\n * discriminants, primitive type mismatches — not to mirror the entire\n * TypeScript surface area.\n *\n * **Tolerance for `'unknown'`.** Treat `'unknown'` as \"any goes.\" Don't\n * report errors against fields whose schema we don't know — those are\n * the schema's gaps, not the agent's.\n */\n\nexport type ValidationError = {\n /**\n * Dot-bracket path rooted at the Msg payload (NOT including `type`).\n * - top-level field: `'cells'`\n * - nested object property: `'cells.value'`\n * - array element: `'cells[0]'` (concrete index from the input)\n * - discriminated-union branch: `'format(kind=range).max'` — the\n * parenthesised `<discriminant>=<value>` segment names which branch\n * the error applies to, distinguishing the same field name across\n * branches.\n */\n path: string\n code:\n | 'unknown-variant'\n | 'missing'\n | 'wrong-type'\n | 'not-in-enum'\n | 'not-array'\n | 'not-object'\n | 'missing-discriminant'\n | 'unknown-discriminant-value'\n | 'unexpected-field'\n | 'validates-failed'\n message: string\n}\n\nexport type ValidationWarning = {\n path: string\n code: 'untyped-field'\n message: string\n}\n\nexport type ValidationResult =\n | { ok: true; warnings?: ValidationWarning[] }\n | { ok: false; errors: ValidationError[]; warnings?: ValidationWarning[] }\n\nexport type ValidationOptions = {\n /**\n * `'strict'` rejects fields that aren't declared in the schema (typos,\n * extra keys, fields the LLM hallucinated). Also emits warnings when\n * the agent provides a value for a field whose schema is `'unknown'`\n * — the validator can't structurally check the value, so the warning\n * surfaces the gap to the LLM (\"we accepted this but didn't validate\n * it\"). `'lenient'` (default) accepts extras silently and treats\n * `'unknown'` as a passthrough.\n *\n * Strict mode pairs with the cross-file schema fidelity in\n * `@llui/vite-plugin`@0.0.36+: with most fields fully resolved, strict\n * is rarely surprising. Apps that haven't migrated yet may find\n * strict overzealous and should stay on lenient.\n */\n policy?: 'strict' | 'lenient'\n}\n\nexport function validatePayload(\n msg: unknown,\n schema: MsgSchemaShape | null,\n opts: ValidationOptions = {},\n): ValidationResult {\n if (msg === null || typeof msg !== 'object' || Array.isArray(msg)) {\n return {\n ok: false,\n errors: [{ path: '', code: 'not-object', message: 'msg must be a plain object' }],\n }\n }\n const m = msg as Record<string, unknown>\n const variantKey = m[schema?.discriminant ?? 'type']\n if (typeof variantKey !== 'string') {\n return {\n ok: false,\n errors: [\n {\n path: schema?.discriminant ?? 'type',\n code: 'missing',\n message: `msg.${schema?.discriminant ?? 'type'} must be a string variant tag`,\n },\n ],\n }\n }\n\n // No schema available — the compiler didn't emit one, or the LLM is\n // talking to a build that predates schema emission. Accept the msg\n // structurally; the reducer will validate semantically.\n if (!schema) return { ok: true }\n\n const variantSchema = schema.variants[variantKey]\n if (!variantSchema) {\n return {\n ok: false,\n errors: [\n {\n path: schema.discriminant,\n code: 'unknown-variant',\n message: `'${variantKey}' is not a known variant. Legal values: ${Object.keys(\n schema.variants,\n )\n .map((v) => `'${v}'`)\n .join(', ')}.`,\n },\n ],\n }\n }\n\n const errors: ValidationError[] = []\n const warnings: ValidationWarning[] = []\n const policy = opts.policy ?? 'lenient'\n const payload: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(m)) {\n if (k !== schema.discriminant) payload[k] = v\n }\n validateObjectShape(payload, variantSchema, '', errors, warnings, policy)\n if (errors.length === 0) {\n return warnings.length === 0 ? { ok: true } : { ok: true, warnings }\n }\n return warnings.length === 0 ? { ok: false, errors } : { ok: false, errors, warnings }\n}\n\nfunction validateObjectShape(\n value: Record<string, unknown>,\n shape: Record<string, MsgSchemaField>,\n pathPrefix: string,\n errors: ValidationError[],\n warnings: ValidationWarning[],\n policy: 'strict' | 'lenient',\n): void {\n for (const [name, descriptor] of Object.entries(shape)) {\n const fieldPath = pathPrefix === '' ? name : `${pathPrefix}.${name}`\n const present = Object.prototype.hasOwnProperty.call(value, name)\n const optional = isOptional(descriptor)\n const fieldValue = present ? value[name] : undefined\n\n if (!present || fieldValue === undefined) {\n // Treat `unknown`-typed fields as implicitly optional. The\n // schema extractor emits `field: string | undefined` as a\n // required field of type 'unknown' (the union isn't a branded\n // primitive), but semantically the field accepts undefined —\n // and the validator's stated philosophy is \"treat 'unknown' as\n // any goes; don't report errors against fields whose schema we\n // don't know.\" Without this, agents are forced to spell out\n // `details: undefined`, `url: undefined`, … on every Criterion\n // they author, which is exactly the kind of fumble we built the\n // payload hints to prevent.\n if (!optional && fieldType(descriptor) !== 'unknown') {\n errors.push({\n path: fieldPath,\n code: 'missing',\n message: `required field is missing`,\n })\n }\n continue\n }\n\n const ft = fieldType(descriptor)\n if (ft === 'unknown' && policy === 'strict') {\n warnings.push({\n path: fieldPath,\n code: 'untyped-field',\n message: `value accepted but field schema is 'unknown' — the validator could not structurally check it. If this field is reachable across file boundaries, consider whether @llui/vite-plugin can resolve it.`,\n })\n }\n\n const errCountBefore = errors.length\n validateField(fieldValue, ft, fieldPath, errors, warnings, policy)\n const structurallyValid = errors.length === errCountBefore\n\n // Domain-invariant predicate (`@validates(\"expr\")`). Runs only\n // when structural validation passed for this field — without the\n // right shape, the predicate would either throw (and we'd have to\n // double-report) or accidentally pass (e.g. `v.length` on a string\n // when we expected a number array). Predicate failures are errors\n // regardless of policy — the author opted into the constraint\n // deliberately.\n if (structurallyValid) {\n const validates = fieldValidatesPredicate(descriptor)\n if (validates !== null) {\n const predicate = compilePredicate(validates)\n let passed: boolean\n try {\n passed = Boolean(predicate(fieldValue))\n } catch {\n passed = false\n }\n if (!passed) {\n errors.push({\n path: fieldPath,\n code: 'validates-failed',\n message: `value violates \\`@validates(\"${validates}\")\\``,\n })\n }\n }\n }\n }\n\n // Strict mode: reject fields the schema doesn't declare. Catches\n // typos (`{tile: 'X'}` instead of `{title: 'X'}`), hallucinated\n // fields, and stale field names from before a refactor. Lenient\n // mode accepts extras silently — same shape TypeScript's structural\n // subtyping accepts at the call site.\n if (policy === 'strict') {\n for (const key of Object.keys(value)) {\n if (key in shape) continue\n const fieldPath = pathPrefix === '' ? key : `${pathPrefix}.${key}`\n errors.push({\n path: fieldPath,\n code: 'unexpected-field',\n message: `field '${key}' is not in the schema. Legal fields: ${Object.keys(shape)\n .map((k) => `'${k}'`)\n .join(', ')}.`,\n })\n }\n }\n}\n\nfunction validateField(\n value: unknown,\n type: MsgSchemaBareType,\n path: string,\n errors: ValidationError[],\n warnings: ValidationWarning[],\n policy: 'strict' | 'lenient',\n): void {\n if (type === 'unknown') return // schema gap; accept anything\n if (typeof type === 'string') {\n // Primitive keyword: 'string', 'number', 'boolean'.\n if (typeof value !== type) {\n errors.push({\n path,\n code: 'wrong-type',\n message: `expected ${type}, got ${describeType(value)}`,\n })\n }\n return\n }\n if ('enum' in type) {\n // Use Object.is so NaN and -0 match correctly; falls back to ===\n // semantics for ordinary values.\n const ok = type.enum.some((legal) => Object.is(legal, value) || legal === value)\n if (!ok) {\n errors.push({\n path,\n code: 'not-in-enum',\n message: `'${String(value)}' is not in the enum. Legal values: ${type.enum\n .map((v) => formatEnumValue(v))\n .join(', ')}.`,\n })\n }\n return\n }\n if (type.kind === 'object') {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n errors.push({\n path,\n code: 'not-object',\n message: `expected object, got ${describeType(value)}`,\n })\n return\n }\n validateObjectShape(\n value as Record<string, unknown>,\n type.shape,\n path,\n errors,\n warnings,\n policy,\n )\n return\n }\n if (type.kind === 'array') {\n if (!Array.isArray(value)) {\n errors.push({\n path,\n code: 'not-array',\n message: `expected array, got ${describeType(value)}`,\n })\n return\n }\n for (let i = 0; i < value.length; i++) {\n validateField(value[i], type.element, `${path}[${i}]`, errors, warnings, policy)\n }\n return\n }\n if (type.kind === 'discriminated-union') {\n if (value === null || typeof value !== 'object' || Array.isArray(value)) {\n errors.push({\n path,\n code: 'not-object',\n message: `expected discriminated-union object, got ${describeType(value)}`,\n })\n return\n }\n const obj = value as Record<string, unknown>\n const discValue = obj[type.discriminant]\n if (typeof discValue !== 'string') {\n errors.push({\n path: `${path}.${type.discriminant}`,\n code: 'missing-discriminant',\n message: `discriminant '${type.discriminant}' must be one of: ${Object.keys(type.variants)\n .map((v) => `'${v}'`)\n .join(', ')}`,\n })\n return\n }\n const branchSchema = type.variants[discValue]\n if (!branchSchema) {\n errors.push({\n path: `${path}.${type.discriminant}`,\n code: 'unknown-discriminant-value',\n message: `'${discValue}' is not a legal '${type.discriminant}'. Legal values: ${Object.keys(\n type.variants,\n )\n .map((v) => `'${v}'`)\n .join(', ')}.`,\n })\n return\n }\n // Recurse into the matched branch's payload (excluding the\n // discriminant itself, which is already validated above).\n const branchPayload: Record<string, unknown> = {}\n for (const [k, v] of Object.entries(obj)) {\n if (k !== type.discriminant) branchPayload[k] = v\n }\n const branchPath = `${path}(${type.discriminant}=${discValue})`\n validateObjectShape(branchPayload, branchSchema, branchPath, errors, warnings, policy)\n }\n}\n\nfunction isOptional(d: MsgSchemaField): boolean {\n return typeof d === 'object' && d !== null && 'type' in d && d.optional === true\n}\n\nfunction fieldType(d: MsgSchemaField): MsgSchemaBareType {\n if (typeof d === 'object' && d !== null && 'type' in d) return d.type\n return d\n}\n\nfunction fieldValidatesPredicate(d: MsgSchemaField): string | null {\n if (typeof d === 'object' && d !== null && 'type' in d && typeof d.validates === 'string') {\n return d.validates\n }\n return null\n}\n\nconst predicateCache = new Map<string, (v: unknown) => boolean>()\n\n/**\n * Compile a `@validates(...)` predicate string into a runtime function.\n * Caches across calls — the schema is static at runtime, so each\n * predicate is compiled at most once.\n *\n * The predicate sees `v` as the field's value and inherits the host\n * environment's globals (Math, JSON, RegExp, etc.). On any compile\n * error, returns a no-op `() => true` so a malformed predicate doesn't\n * break dispatch — the build-time linter (`agent-validates-syntax`,\n * future) is the right place to catch syntactic issues.\n */\nfunction compilePredicate(src: string): (v: unknown) => boolean {\n let fn = predicateCache.get(src)\n if (fn) return fn\n try {\n fn = new Function('v', `return (${src})`) as (v: unknown) => boolean\n } catch {\n fn = () => true\n }\n predicateCache.set(src, fn)\n return fn\n}\n\nfunction describeType(v: unknown): string {\n if (v === null) return 'null'\n if (Array.isArray(v)) return 'array'\n return typeof v\n}\n\nfunction formatEnumValue(v: string | number | boolean): string {\n return typeof v === 'string' ? `'${v}'` : String(v)\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llui/agent",
3
- "version": "0.0.41",
3
+ "version": "0.0.42",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "exports": {