@llui/vite-plugin 0.0.20 → 0.0.22

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":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"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","sourcesContent":["import ts from 'typescript'\n\nexport interface Diagnostic {\n message: string\n line: number\n column: number\n}\n\nconst INTERACTIVE_ELEMENTS = new Set([\n 'button',\n 'a',\n 'input',\n 'select',\n 'textarea',\n 'details',\n 'summary',\n])\n\nconst ELEMENT_HELPERS = new Set([\n 'a',\n 'abbr',\n 'article',\n 'aside',\n 'b',\n 'blockquote',\n 'br',\n 'button',\n 'canvas',\n 'code',\n 'dd',\n 'details',\n 'dialog',\n 'div',\n 'dl',\n 'dt',\n 'em',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hr',\n 'i',\n 'iframe',\n 'img',\n 'input',\n 'label',\n 'legend',\n 'li',\n 'main',\n 'mark',\n 'nav',\n 'ol',\n 'optgroup',\n 'option',\n 'output',\n 'p',\n 'pre',\n 'progress',\n 'section',\n 'select',\n 'small',\n 'span',\n 'strong',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'ul',\n 'video',\n])\n\nexport function diagnose(source: string): Diagnostic[] {\n const sf = ts.createSourceFile('input.ts', source, ts.ScriptTarget.Latest, true)\n const diagnostics: Diagnostic[] = []\n\n // Collect Msg type variants for exhaustive update() check\n const msgVariants = collectMsgVariants(sf)\n\n // Collect state access paths for bitmask warning\n const statePaths = collectStatePaths(sf)\n\n function visit(node: ts.Node): void {\n checkMapOnState(node, sf, diagnostics)\n checkExhaustiveUpdate(node, sf, diagnostics, msgVariants)\n checkAccessibility(node, sf, diagnostics)\n checkControlledInput(node, sf, diagnostics)\n checkChildStaticProps(node, sf, diagnostics)\n checkBitmaskOverflow(node, sf, diagnostics, statePaths)\n checkNamespaceImport(node, sf, diagnostics)\n checkSpreadChildren(node, sf, diagnostics)\n checkEmptyProps(node, sf, diagnostics)\n\n ts.forEachChild(node, visit)\n }\n\n visit(sf)\n return diagnostics\n}\n\n// ── \"Almost-optimized\" diagnostics ───────────────────────────────\n\n// Warns when a user writes `import * as L from '@llui/dom'` — the compiler\n// can only recognize named-import helpers, so namespace imports disable\n// template cloning/elSplit for every element call in the file.\nfunction checkNamespaceImport(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isImportDeclaration(node)) return\n if (!ts.isStringLiteral(node.moduleSpecifier)) return\n if (node.moduleSpecifier.text !== '@llui/dom') return\n const clause = node.importClause\n if (!clause?.namedBindings) return\n if (!ts.isNamespaceImport(clause.namedBindings)) return\n const name = clause.namedBindings.name.text\n const { line, column } = pos(clause.namedBindings, sf)\n diagnostics.push({\n message: `Namespace import '${name}' from '@llui/dom' at line ${line} disables compiler optimizations. Use named imports instead: import { div, text, ... } from '@llui/dom'.`,\n line,\n column,\n })\n}\n\n// Warns when a children array contains a spread — the compiler can't\n// analyze variable-length children, so it bails on template cloning and\n// falls back to runtime elSplit. Not fatal, but silent.\nfunction checkSpreadChildren(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isCallExpression(node)) return\n if (!ts.isIdentifier(node.expression)) return\n if (!ELEMENT_HELPERS.has(node.expression.text)) return\n // Children could be at arguments[0] (children-only overload) or arguments[1]\n for (const arg of node.arguments) {\n if (!ts.isArrayLiteralExpression(arg)) continue\n // Look for \"suspicious\" spreads — ones that aren't obviously returning\n // Node[] from a structural primitive or user-defined view helper.\n for (const el of arg.elements) {\n if (!ts.isSpreadElement(el)) continue\n if (isStructuralSpread(el.expression)) continue\n const { line, column } = pos(arg, sf)\n diagnostics.push({\n message: `Spread in children array of '${node.expression.text}()' at line ${line} disables template-clone compilation. For dynamic child counts, use each() instead.`,\n line,\n column,\n })\n return\n }\n }\n}\n\n// Array iteration methods whose result spreads are the red flag we want\n// to catch — users should use each() instead. Function calls generally\n// return Node[] from structural primitives or user view helpers and are\n// the legitimate way to compose output.\nconst ARRAY_ITERATION_METHODS = new Set([\n 'map',\n 'filter',\n 'flatMap',\n 'slice',\n 'concat',\n 'reverse',\n 'sort',\n])\n\nfunction isStructuralSpread(expr: ts.Expression): boolean {\n // Only keep the warning for suspect patterns: identifier spreads and\n // array-iteration method calls. Everything else is presumed to be a\n // structural primitive or user helper returning Node[].\n if (ts.isCallExpression(expr)) {\n const callee = expr.expression\n if (ts.isPropertyAccessExpression(callee) && ts.isIdentifier(callee.name)) {\n // `...arr.map(...)`, `...arr.filter(...)` — suspect\n return !ARRAY_ITERATION_METHODS.has(callee.name.text)\n }\n // Plain function call `...fn()` — presume structural/helper\n return true\n }\n // Identifier spread (`...arr`) — suspect\n return false\n}\n\n// Warns when an element helper is called with an empty props object — the\n// attrs argument is optional, so `h1({}, [...])` should be `h1([...])`.\nfunction checkEmptyProps(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isCallExpression(node)) return\n if (!ts.isIdentifier(node.expression)) return\n if (!ELEMENT_HELPERS.has(node.expression.text)) return\n const firstArg = node.arguments[0]\n if (!firstArg || !ts.isObjectLiteralExpression(firstArg)) return\n if (firstArg.properties.length !== 0) return\n const { line, column } = pos(firstArg, sf)\n diagnostics.push({\n message: `Empty props object passed to '${node.expression.text}()' at line ${line}. The attrs argument is optional — omit it: ${node.expression.text}([...]).`,\n line,\n column,\n })\n}\n\nfunction pos(node: ts.Node, sf: ts.SourceFile): { line: number; column: number } {\n const { line, character } = sf.getLineAndCharacterOfPosition(node.getStart(sf))\n return { line: line + 1, column: character + 1 }\n}\n\nfunction _isInsideEachRender(node: ts.Node): boolean {\n let current = node.parent\n while (current) {\n if (\n (ts.isArrowFunction(current) || ts.isFunctionExpression(current)) &&\n current.parameters.length >= 1\n ) {\n const param = current.parameters[0]!\n // Options bag: ({ item, ... }) => ...\n const hasItemParam =\n ts.isObjectBindingPattern(param.name) &&\n param.name.elements.some(\n (el) => ts.isBindingElement(el) && ts.isIdentifier(el.name) && el.name.text === 'item',\n )\n if (hasItemParam) {\n const propAssign = current.parent\n if (\n ts.isPropertyAssignment(propAssign) &&\n ts.isIdentifier(propAssign.name) &&\n propAssign.name.text === 'render'\n ) {\n return true\n }\n }\n }\n current = current.parent\n }\n return false\n}\n\n// ── .map() on state arrays ───────────────────────────────────────\n\nfunction checkMapOnState(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isCallExpression(node)) return\n if (!ts.isPropertyAccessExpression(node.expression)) return\n if (node.expression.name.text !== 'map') return\n\n // Check if receiver involves a state parameter reference\n if (!referencesStateParam(node.expression.expression)) return\n\n // Check if we're inside a view function\n if (!isInsideViewFunction(node)) return\n\n const { line, column } = pos(node, sf)\n diagnostics.push({\n message: `Array .map() on state-derived value at line ${line}. Use each() for reactive lists that update when the array changes.`,\n line,\n column,\n })\n}\n\nfunction referencesStateParam(node: ts.Node): boolean {\n if (ts.isPropertyAccessExpression(node)) {\n return referencesStateParam(node.expression)\n }\n if (ts.isIdentifier(node)) {\n // Check if the identifier is a parameter named 'state' or 's' or matches common patterns\n // Simple heuristic: check if it's a parameter of the view function\n const name = node.text\n return name === 'state' || name === 's' || name === '_state'\n }\n return false\n}\n\nfunction isInsideViewFunction(node: ts.Node): boolean {\n let current = node.parent\n while (current) {\n if (ts.isPropertyAssignment(current)) {\n if (ts.isIdentifier(current.name) && current.name.text === 'view') {\n return true\n }\n }\n current = current.parent\n }\n return false\n}\n\n// ── Exhaustive update() ──────────────────────────────────────────\n\nfunction collectMsgVariants(sf: ts.SourceFile): Set<string> {\n const variants = new Set<string>()\n\n for (const stmt of sf.statements) {\n if (!ts.isTypeAliasDeclaration(stmt)) continue\n if (stmt.name.text !== 'Msg') continue\n\n // Walk the union to find { type: 'literal' } members\n collectUnionVariants(stmt.type, variants)\n }\n\n return variants\n}\n\nfunction collectUnionVariants(type: ts.TypeNode, variants: Set<string>): void {\n if (ts.isUnionTypeNode(type)) {\n for (const member of type.types) {\n collectUnionVariants(member, variants)\n }\n return\n }\n\n if (ts.isTypeLiteralNode(type)) {\n for (const member of type.members) {\n if (!ts.isPropertySignature(member)) continue\n if (!ts.isIdentifier(member.name!) || member.name.text !== 'type') continue\n if (member.type && ts.isLiteralTypeNode(member.type)) {\n if (ts.isStringLiteral(member.type.literal)) {\n variants.add(member.type.literal.text)\n }\n }\n }\n }\n}\n\nfunction checkExhaustiveUpdate(\n node: ts.Node,\n sf: ts.SourceFile,\n diagnostics: Diagnostic[],\n msgVariants: Set<string>,\n): void {\n if (msgVariants.size === 0) return\n if (!ts.isPropertyAssignment(node)) return\n if (!ts.isIdentifier(node.name) || node.name.text !== 'update') return\n\n // Find the switch statement in the update body\n const fn = node.initializer\n if (!ts.isArrowFunction(fn) && !ts.isFunctionExpression(fn)) return\n\n const body = ts.isBlock(fn.body) ? fn.body : null\n if (!body) return\n\n const handledCases = new Set<string>()\n let hasDefault = false\n\n function findSwitch(n: ts.Node): void {\n if (ts.isSwitchStatement(n)) {\n for (const clause of n.caseBlock.clauses) {\n if (ts.isDefaultClause(clause)) {\n hasDefault = true\n } else if (ts.isCaseClause(clause) && ts.isStringLiteral(clause.expression)) {\n handledCases.add(clause.expression.text)\n }\n }\n }\n ts.forEachChild(n, findSwitch)\n }\n\n findSwitch(body)\n\n if (hasDefault) return\n\n const missing = [...msgVariants].filter((v) => !handledCases.has(v))\n if (missing.length === 0) return\n\n const { line, column } = pos(node, sf)\n diagnostics.push({\n message: `update() does not handle message type${missing.length > 1 ? 's' : ''} ${missing.map((m) => `'${m}'`).join(', ')} at line ${line}.`,\n line,\n column,\n })\n}\n\n// ── Accessibility ────────────────────────────────────────────────\n\nfunction checkAccessibility(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isCallExpression(node)) return\n if (!ts.isIdentifier(node.expression)) return\n\n const tag = node.expression.text\n if (!ELEMENT_HELPERS.has(tag)) return\n\n const propsArg = node.arguments[0]\n if (!propsArg || !ts.isObjectLiteralExpression(propsArg)) return\n\n const props = getStaticPropKeys(propsArg)\n\n // img without alt\n if (tag === 'img' && !props.has('alt')) {\n const { line, column } = pos(node, sf)\n diagnostics.push({\n message: `<img> at line ${line} has no 'alt' attribute. Add alt text for screen readers, or alt='' for decorative images.`,\n line,\n column,\n })\n }\n\n // onClick on non-interactive element without role\n if (props.has('onClick') && !INTERACTIVE_ELEMENTS.has(tag) && !props.has('role')) {\n const { line, column } = pos(node, sf)\n diagnostics.push({\n message: `onClick on <${tag}> at line ${line} without role and tabIndex. Non-interactive elements with click handlers are not keyboard-accessible. Add role='button' and tabIndex={0}, or use <button>.`,\n line,\n column,\n })\n }\n}\n\n// ── Controlled input ─────────────────────────────────────────────\n\nfunction checkControlledInput(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isCallExpression(node)) return\n if (!ts.isIdentifier(node.expression)) return\n\n const tag = node.expression.text\n if (tag !== 'input' && tag !== 'textarea') return\n\n const propsArg = node.arguments[0]\n if (!propsArg || !ts.isObjectLiteralExpression(propsArg)) return\n\n const props = getProps(propsArg)\n\n // Check if value is a reactive binding (arrow function)\n const valueProp = props.get('value')\n if (!valueProp) return\n if (!ts.isArrowFunction(valueProp) && !ts.isFunctionExpression(valueProp)) return\n\n // Must have onInput\n if (!props.has('onInput') && !props.has('onChange')) {\n const { line, column } = pos(node, sf)\n diagnostics.push({\n message: `Controlled input at line ${line}: reactive 'value' binding without 'onInput' handler. The binding will overwrite user input on every state update.`,\n line,\n column,\n })\n }\n}\n\nfunction getStaticPropKeys(obj: ts.ObjectLiteralExpression): Set<string> {\n const keys = new Set<string>()\n for (const prop of obj.properties) {\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {\n keys.add(prop.name.text)\n }\n }\n return keys\n}\n\nfunction getProps(obj: ts.ObjectLiteralExpression): Map<string, ts.Expression> {\n const map = new Map<string, ts.Expression>()\n for (const prop of obj.properties) {\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {\n map.set(prop.name.text, prop.initializer)\n }\n }\n return map\n}\n\n// ── child() static props ────────────────────────────────────────\n\nfunction checkChildStaticProps(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isCallExpression(node)) return\n if (!ts.isIdentifier(node.expression) || node.expression.text !== 'child') return\n\n const arg = node.arguments[0]\n if (!arg || !ts.isObjectLiteralExpression(arg)) return\n\n for (const prop of arg.properties) {\n if (!ts.isPropertyAssignment(prop)) continue\n if (!ts.isIdentifier(prop.name) || prop.name.text !== 'props') continue\n\n // props must be a function, not an object literal\n if (ts.isObjectLiteralExpression(prop.initializer)) {\n const { line, column } = pos(node, sf)\n diagnostics.push({\n message: `child() at line ${line}: 'props' is a static object literal. It must be a reactive accessor function (s => ({ ... })) so props update when parent state changes.`,\n line,\n column,\n })\n continue\n }\n\n // props accessor: warn when the returned object contains fresh\n // object/array literals. The prop-diff in `child()` compares by\n // reference per top-level key (Object.is), so a freshly-constructed\n // nested value reports changed on every parent update — propsMsg\n // fires every render, which is wasted work at best and an infinite\n // loop vector when combined with a naive `onMsg` forwarder.\n if (ts.isArrowFunction(prop.initializer) || ts.isFunctionExpression(prop.initializer)) {\n const returned = getReturnedObjectLiteral(prop.initializer)\n if (!returned) continue\n for (const keyProp of returned.properties) {\n if (!ts.isPropertyAssignment(keyProp)) continue\n const init = keyProp.initializer\n if (!ts.isObjectLiteralExpression(init) && !ts.isArrayLiteralExpression(init)) continue\n const keyName = ts.isIdentifier(keyProp.name)\n ? keyProp.name.text\n : ts.isStringLiteral(keyProp.name)\n ? keyProp.name.text\n : '<?>'\n const kind = ts.isArrayLiteralExpression(init) ? 'array' : 'object'\n const { line, column } = pos(keyProp, sf)\n diagnostics.push({\n message: `child() at line ${line}: the 'props' accessor returns a fresh ${kind} literal for '${keyName}'. Prop diffing uses Object.is per key, so a freshly-constructed reference reports changed every render — propsMsg will fire on every parent update. Hoist to a module-level constant, reuse a reference from state, or return null from propsMsg when the value is unchanged.`,\n line,\n column,\n })\n }\n }\n }\n}\n\nfunction getReturnedObjectLiteral(\n fn: ts.ArrowFunction | ts.FunctionExpression,\n): ts.ObjectLiteralExpression | null {\n const body = fn.body\n if (ts.isParenthesizedExpression(body) && ts.isObjectLiteralExpression(body.expression)) {\n return body.expression\n }\n if (ts.isObjectLiteralExpression(body)) return body\n if (ts.isBlock(body)) {\n for (const stmt of body.statements) {\n if (!ts.isReturnStatement(stmt) || !stmt.expression) continue\n const expr = stmt.expression\n if (ts.isObjectLiteralExpression(expr)) return expr\n if (ts.isParenthesizedExpression(expr) && ts.isObjectLiteralExpression(expr.expression)) {\n return expr.expression\n }\n }\n }\n return null\n}\n\n// ── Bitmask overflow warning ────────────────────────────────────\n\nfunction collectStatePaths(sf: ts.SourceFile): Set<string> {\n const paths = new Set<string>()\n\n function visit(node: ts.Node): void {\n if (\n (ts.isArrowFunction(node) || ts.isFunctionExpression(node)) &&\n node.parameters.length === 1\n ) {\n const param = node.parameters[0]!.name\n if (ts.isIdentifier(param)) {\n // Check if this looks like a reactive accessor\n const parent = node.parent\n if (ts.isPropertyAssignment(parent)) {\n const key = parent.name\n if (ts.isIdentifier(key) && !/^on[A-Z]/.test(key.text)) {\n extractAccessPaths(node.body, param.text, paths)\n }\n } else if (ts.isCallExpression(parent) && parent.arguments[0] === node) {\n extractAccessPaths(node.body, param.text, paths)\n }\n }\n }\n ts.forEachChild(node, visit)\n }\n\n visit(sf)\n return paths\n}\n\nfunction extractAccessPaths(node: ts.Node, paramName: string, paths: Set<string>): void {\n if (ts.isPropertyAccessExpression(node)) {\n const chain = resolveSimpleChain(node, paramName)\n if (chain) paths.add(chain)\n }\n ts.forEachChild(node, (child) => extractAccessPaths(child, paramName, paths))\n}\n\nfunction resolveSimpleChain(node: ts.PropertyAccessExpression, paramName: string): string | null {\n const parts: string[] = []\n let current: ts.Expression = node\n while (ts.isPropertyAccessExpression(current)) {\n parts.unshift(current.name.text)\n current = current.expression\n }\n if (!ts.isIdentifier(current) || current.text !== paramName) return null\n if (parts.length > 2) return parts.slice(0, 2).join('.')\n return parts.join('.')\n}\n\nfunction checkBitmaskOverflow(\n node: ts.Node,\n sf: ts.SourceFile,\n diagnostics: Diagnostic[],\n paths: Set<string>,\n): void {\n // Only emit once, on the component() call\n if (!ts.isCallExpression(node)) return\n if (!ts.isIdentifier(node.expression) || node.expression.text !== 'component') return\n\n const pathCount = paths.size\n if (pathCount <= 31) return\n\n const overflow = pathCount - 31\n const { line, column } = pos(node, sf)\n\n // Group paths by top-level field so authors know which slice to extract.\n // `resolveSimpleChain` already truncates to depth 2 (e.g. \"user.name\"),\n // so splitting on \".\" gives us the top-level field.\n const byTopLevel = new Map<string, number>()\n for (const p of paths) {\n const top = p.split('.', 1)[0]!\n byTopLevel.set(top, (byTopLevel.get(top) ?? 0) + 1)\n }\n const sorted = [...byTopLevel.entries()].sort((a, b) => b[1] - a[1])\n\n // Pick the top fields whose combined path count would bring us under\n // the 31 limit. These are the best candidates to extract.\n const candidates: string[] = []\n let saved = 0\n for (const [field, n] of sorted) {\n if (pathCount - saved <= 31) break\n candidates.push(field)\n saved += n\n }\n const breakdown = sorted.map(([field, n]) => `${field} (${n})`).join(', ')\n const candidateList = candidates.map((f) => `\\`${f}\\``).join(', ')\n\n diagnostics.push({\n message:\n `Component at line ${line} has ${pathCount} unique state access paths ` +\n `(${overflow} past the 31-path limit). Paths 32..${pathCount} fall back to ` +\n `FULL_MASK — their changes re-evaluate every binding in the component, ` +\n `negating the bitmask optimization for those updates.\\n\\n` +\n `Top-level fields by path count: ${breakdown}.\\n\\n` +\n `Recommended fix: extract ${candidateList} into ${candidates.length === 1 ? 'a' : ''} ` +\n `child component${candidates.length === 1 ? '' : 's'} via \\`child()\\` ` +\n `(see /api/dom#child). Each child gets its own 31-path bitmask, so the ` +\n `extracted paths no longer count against the parent's limit. ` +\n `Alternative: use \\`sliceHandler\\` to embed a state machine that owns ` +\n `the field's reducer.`,\n line,\n column,\n })\n}\n"]}
1
+ {"version":3,"file":"diagnostics.js","sourceRoot":"","sources":["../src/diagnostics.ts"],"names":[],"mappings":"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","sourcesContent":["import ts from 'typescript'\nimport { collectStatePathsFromSource, collectAccessorPathSets } from './collect-deps.js'\n\nexport interface Diagnostic {\n /** Short identifier — passed to `disabledWarnings` in LluiPluginOptions to silence. */\n rule: DiagnosticRule\n message: string\n line: number\n column: number\n}\n\n/**\n * Every diagnostic the plugin can emit. Exported so consumers can pass\n * `disabledWarnings: [...]` with compile-time type safety.\n */\nexport type DiagnosticRule =\n | 'map-on-state'\n | 'exhaustive-update'\n | 'accessibility'\n | 'controlled-input'\n | 'child-static-props'\n | 'bitmask-overflow'\n | 'namespace-import'\n | 'spread-in-children'\n | 'empty-props'\n | 'static-on'\n\nconst INTERACTIVE_ELEMENTS = new Set([\n 'button',\n 'a',\n 'input',\n 'select',\n 'textarea',\n 'details',\n 'summary',\n])\n\nconst ELEMENT_HELPERS = new Set([\n 'a',\n 'abbr',\n 'article',\n 'aside',\n 'b',\n 'blockquote',\n 'br',\n 'button',\n 'canvas',\n 'code',\n 'dd',\n 'details',\n 'dialog',\n 'div',\n 'dl',\n 'dt',\n 'em',\n 'fieldset',\n 'figcaption',\n 'figure',\n 'footer',\n 'form',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'header',\n 'hr',\n 'i',\n 'iframe',\n 'img',\n 'input',\n 'label',\n 'legend',\n 'li',\n 'main',\n 'mark',\n 'nav',\n 'ol',\n 'optgroup',\n 'option',\n 'output',\n 'p',\n 'pre',\n 'progress',\n 'section',\n 'select',\n 'small',\n 'span',\n 'strong',\n 'sub',\n 'summary',\n 'sup',\n 'table',\n 'tbody',\n 'td',\n 'textarea',\n 'tfoot',\n 'th',\n 'thead',\n 'time',\n 'tr',\n 'ul',\n 'video',\n])\n\nexport function diagnose(source: string): Diagnostic[] {\n const sf = ts.createSourceFile('input.ts', source, ts.ScriptTarget.Latest, true)\n const diagnostics: Diagnostic[] = []\n\n // Collect Msg type variants for exhaustive update() check\n const msgVariants = collectMsgVariants(sf)\n\n // Collect state access paths for bitmask warning (shared scanner with collect-deps.ts)\n const statePaths = collectStatePathsFromSource(sf)\n\n function visit(node: ts.Node): void {\n checkMapOnState(node, sf, diagnostics)\n checkExhaustiveUpdate(node, sf, diagnostics, msgVariants)\n checkAccessibility(node, sf, diagnostics)\n checkControlledInput(node, sf, diagnostics)\n checkChildStaticProps(node, sf, diagnostics)\n checkBitmaskOverflow(node, sf, diagnostics, statePaths)\n checkNamespaceImport(node, sf, diagnostics)\n checkSpreadChildren(node, sf, diagnostics)\n checkEmptyProps(node, sf, diagnostics)\n checkStaticOn(node, sf, diagnostics)\n\n ts.forEachChild(node, visit)\n }\n\n visit(sf)\n return diagnostics\n}\n\n// ── \"Almost-optimized\" diagnostics ───────────────────────────────\n\n// Warns when a user writes `import * as L from '@llui/dom'` — the compiler\n// can only recognize named-import helpers, so namespace imports disable\n// template cloning/elSplit for every element call in the file.\nfunction checkNamespaceImport(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isImportDeclaration(node)) return\n if (!ts.isStringLiteral(node.moduleSpecifier)) return\n if (node.moduleSpecifier.text !== '@llui/dom') return\n const clause = node.importClause\n if (!clause?.namedBindings) return\n if (!ts.isNamespaceImport(clause.namedBindings)) return\n const name = clause.namedBindings.name.text\n const { line, column } = pos(clause.namedBindings, sf)\n diagnostics.push({\n rule: 'namespace-import',\n message: `Namespace import '${name}' from '@llui/dom' at line ${line} disables compiler optimizations. Use named imports instead: import { div, text, ... } from '@llui/dom'.`,\n line,\n column,\n })\n}\n\n// Warns when a children array contains a spread — the compiler can't\n// analyze variable-length children, so it bails on template cloning and\n// falls back to runtime elSplit. Not fatal, but silent.\n//\n// Scope-aware: when the spread source (or an array-method's receiver)\n// resolves to a locally-bounded binding — `const x = [...]`, `const x =\n// fn(...)`, `const x = other.map(...)` where `other` is bounded — the\n// child count is statically known and `each()` is not a usable fix.\n// Those cases stay silent; only truly dynamic spreads warn.\nfunction checkSpreadChildren(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isCallExpression(node)) return\n if (!ts.isIdentifier(node.expression)) return\n if (!ELEMENT_HELPERS.has(node.expression.text)) return\n // Children could be at arguments[0] (children-only overload) or arguments[1]\n for (const arg of node.arguments) {\n if (!ts.isArrayLiteralExpression(arg)) continue\n for (const el of arg.elements) {\n if (!ts.isSpreadElement(el)) continue\n if (isBoundedSpreadSource(el.expression, sf)) continue\n const { line, column } = pos(arg, sf)\n diagnostics.push({\n rule: 'spread-in-children',\n message: `Spread in children array of '${node.expression.text}()' at line ${line} disables template-clone compilation. For dynamic child counts, use each() instead.`,\n line,\n column,\n })\n return\n }\n }\n}\n\n// Array iteration methods whose result spreads are the red flag we want\n// to catch — users should use each() instead. Function calls generally\n// return Node[] from structural primitives or user view helpers and are\n// the legitimate way to compose output.\nconst ARRAY_ITERATION_METHODS = new Set([\n 'map',\n 'filter',\n 'flatMap',\n 'slice',\n 'concat',\n 'reverse',\n 'sort',\n])\n\n/**\n * Classify a spread-source expression as \"bounded\" — i.e., the child\n * count is statically knowable and `each()` is not an applicable fix.\n * Returns true when the spread should stay silent, false when the\n * spread is genuinely suspect (state-derived, unresolved, inline\n * array-method call on a non-bounded receiver).\n */\nfunction isBoundedSpreadSource(expr: ts.Expression, sf: ts.SourceFile): boolean {\n // Identifier spread `...foo` — resolve the binding.\n if (ts.isIdentifier(expr)) {\n const init = resolveBindingInitializer(expr, sf)\n if (init === null) return false\n return isBoundedInitializer(init, sf)\n }\n\n // Call-expression spread.\n if (ts.isCallExpression(expr)) {\n const callee = expr.expression\n // Array-method call: `...x.map(...)`, `...arr.concat([...])`, etc.\n if (ts.isPropertyAccessExpression(callee) && ts.isIdentifier(callee.name)) {\n if (!ARRAY_ITERATION_METHODS.has(callee.name.text)) {\n // Non-array-method method call (e.g. `...my.overlay()`) — presume\n // structural/helper. Same as before.\n return true\n }\n // Array method — bounded if the receiver resolves to a bounded\n // array source. Inline literals (e.g. `...[1,2,3].map(...)`)\n // stay suspect intentionally so authors see the warning on the\n // canonical dynamic-mapping shape.\n return isBoundedArrayReceiver(callee.expression, sf)\n }\n // Plain function call `...fn()` — presume structural/helper.\n return true\n }\n\n // Anything else (array literal inline, etc.) — treat as suspect for\n // now. Inline `...[...]` at a call site is unusual and worth flagging.\n return false\n}\n\n/**\n * Is the initializer a bounded expression? Array literals and\n * function-call results both qualify; method calls recurse on their\n * receivers.\n */\nfunction isBoundedInitializer(init: ts.Expression, sf: ts.SourceFile): boolean {\n // `const foo = [...]` — bounded.\n if (ts.isArrayLiteralExpression(init)) return true\n\n // `const foo = x as const` / `x as T` — look through the assertion.\n if (ts.isAsExpression(init) || ts.isTypeAssertionExpression(init)) {\n return isBoundedInitializer(init.expression, sf)\n }\n\n // `const foo = someCall(...)` — treat plain-call results as bounded\n // structural output. Same heuristic the original syntactic rule used.\n if (ts.isCallExpression(init)) {\n const callee = init.expression\n if (ts.isIdentifier(callee)) return true\n if (ts.isPropertyAccessExpression(callee) && ts.isIdentifier(callee.name)) {\n if (!ARRAY_ITERATION_METHODS.has(callee.name.text)) return true\n // Method call is an array method — bounded iff receiver is.\n return isBoundedArrayReceiver(callee.expression, sf)\n }\n }\n\n return false\n}\n\n/**\n * A method-call receiver (the `x` in `x.map(...)`) is bounded when\n * resolved to a named array-literal binding. Inline literals are\n * intentionally NOT bounded here — callers who inline `[1,2,3].map(...)`\n * should still see the warning.\n */\nfunction isBoundedArrayReceiver(receiver: ts.Expression, sf: ts.SourceFile): boolean {\n if (!ts.isIdentifier(receiver)) return false\n const init = resolveBindingInitializer(receiver, sf)\n if (init === null) return false\n if (ts.isArrayLiteralExpression(init)) return true\n if (ts.isAsExpression(init) || ts.isTypeAssertionExpression(init)) {\n return ts.isArrayLiteralExpression(init.expression)\n }\n return false\n}\n\n/**\n * Walk the identifier's ancestor scopes looking for a matching\n * VariableDeclaration. Returns its initializer (or null if the name\n * resolves to a function parameter, import, or nothing at all).\n */\nfunction resolveBindingInitializer(ident: ts.Identifier, sf: ts.SourceFile): ts.Expression | null {\n const name = ident.text\n let scope: ts.Node | undefined = ident.parent\n while (scope) {\n const decl = findVariableDeclarationInScope(scope, name, ident)\n if (decl) return decl.initializer ?? null\n if (scope === sf) break\n scope = scope.parent\n }\n return null\n}\n\n/**\n * Scan a scope's immediate statements for a `const/let/var name = ...`\n * declaration. Does not descend into inner function bodies — those are\n * visible only from within themselves.\n */\nfunction findVariableDeclarationInScope(\n scope: ts.Node,\n name: string,\n from: ts.Node,\n): ts.VariableDeclaration | null {\n let found: ts.VariableDeclaration | null = null\n\n function visit(node: ts.Node): void {\n if (found) return\n // Don't descend into nested function bodies other than the one\n // containing `from` — that walking is handled by the outer loop.\n if (\n node !== from.parent &&\n (ts.isFunctionDeclaration(node) ||\n ts.isFunctionExpression(node) ||\n ts.isArrowFunction(node) ||\n ts.isMethodDeclaration(node) ||\n ts.isConstructorDeclaration(node))\n ) {\n // Still scan the parameters? No — parameters aren't VariableDeclarations.\n return\n }\n if (ts.isVariableDeclaration(node) && ts.isIdentifier(node.name) && node.name.text === name) {\n found = node\n return\n }\n ts.forEachChild(node, visit)\n }\n\n ts.forEachChild(scope, visit)\n return found\n}\n\n// Warns when an element helper is called with an empty props object — the\n// attrs argument is optional, so `h1({}, [...])` should be `h1([...])`.\nfunction checkEmptyProps(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isCallExpression(node)) return\n if (!ts.isIdentifier(node.expression)) return\n if (!ELEMENT_HELPERS.has(node.expression.text)) return\n const firstArg = node.arguments[0]\n if (!firstArg || !ts.isObjectLiteralExpression(firstArg)) return\n if (firstArg.properties.length !== 0) return\n const { line, column } = pos(firstArg, sf)\n diagnostics.push({\n rule: 'empty-props',\n message: `Empty props object passed to '${node.expression.text}()' at line ${line}. The attrs argument is optional — omit it: ${node.expression.text}([...]).`,\n line,\n column,\n })\n}\n\nfunction pos(node: ts.Node, sf: ts.SourceFile): { line: number; column: number } {\n const { line, character } = sf.getLineAndCharacterOfPosition(node.getStart(sf))\n return { line: line + 1, column: character + 1 }\n}\n\nfunction _isInsideEachRender(node: ts.Node): boolean {\n let current = node.parent\n while (current) {\n if (\n (ts.isArrowFunction(current) || ts.isFunctionExpression(current)) &&\n current.parameters.length >= 1\n ) {\n const param = current.parameters[0]!\n // Options bag: ({ item, ... }) => ...\n const hasItemParam =\n ts.isObjectBindingPattern(param.name) &&\n param.name.elements.some(\n (el) => ts.isBindingElement(el) && ts.isIdentifier(el.name) && el.name.text === 'item',\n )\n if (hasItemParam) {\n const propAssign = current.parent\n if (\n ts.isPropertyAssignment(propAssign) &&\n ts.isIdentifier(propAssign.name) &&\n propAssign.name.text === 'render'\n ) {\n return true\n }\n }\n }\n current = current.parent\n }\n return false\n}\n\n// ── .map() on state arrays ───────────────────────────────────────\n\nfunction checkMapOnState(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isCallExpression(node)) return\n if (!ts.isPropertyAccessExpression(node.expression)) return\n if (node.expression.name.text !== 'map') return\n\n // Check if receiver involves a state parameter reference\n if (!referencesStateParam(node.expression.expression)) return\n\n // Check if we're inside a view function\n if (!isInsideViewFunction(node)) return\n\n const { line, column } = pos(node, sf)\n diagnostics.push({\n rule: 'map-on-state',\n message: `Array .map() on state-derived value at line ${line}. Use each() for reactive lists that update when the array changes.`,\n line,\n column,\n })\n}\n\nfunction referencesStateParam(node: ts.Node): boolean {\n if (ts.isPropertyAccessExpression(node)) {\n return referencesStateParam(node.expression)\n }\n if (ts.isIdentifier(node)) {\n // Check if the identifier is a parameter named 'state' or 's' or matches common patterns\n // Simple heuristic: check if it's a parameter of the view function\n const name = node.text\n return name === 'state' || name === 's' || name === '_state'\n }\n return false\n}\n\nfunction isInsideViewFunction(node: ts.Node): boolean {\n let current = node.parent\n while (current) {\n if (ts.isPropertyAssignment(current)) {\n if (ts.isIdentifier(current.name) && current.name.text === 'view') {\n return true\n }\n }\n current = current.parent\n }\n return false\n}\n\n// ── Exhaustive update() ──────────────────────────────────────────\n\nfunction collectMsgVariants(sf: ts.SourceFile): Set<string> {\n const variants = new Set<string>()\n\n for (const stmt of sf.statements) {\n if (!ts.isTypeAliasDeclaration(stmt)) continue\n if (stmt.name.text !== 'Msg') continue\n\n // Walk the union to find { type: 'literal' } members\n collectUnionVariants(stmt.type, variants)\n }\n\n return variants\n}\n\nfunction collectUnionVariants(type: ts.TypeNode, variants: Set<string>): void {\n if (ts.isUnionTypeNode(type)) {\n for (const member of type.types) {\n collectUnionVariants(member, variants)\n }\n return\n }\n\n if (ts.isTypeLiteralNode(type)) {\n for (const member of type.members) {\n if (!ts.isPropertySignature(member)) continue\n if (!ts.isIdentifier(member.name!) || member.name.text !== 'type') continue\n if (member.type && ts.isLiteralTypeNode(member.type)) {\n if (ts.isStringLiteral(member.type.literal)) {\n variants.add(member.type.literal.text)\n }\n }\n }\n }\n}\n\nfunction checkExhaustiveUpdate(\n node: ts.Node,\n sf: ts.SourceFile,\n diagnostics: Diagnostic[],\n msgVariants: Set<string>,\n): void {\n if (msgVariants.size === 0) return\n if (!ts.isPropertyAssignment(node)) return\n if (!ts.isIdentifier(node.name) || node.name.text !== 'update') return\n\n // Find the switch statement in the update body\n const fn = node.initializer\n if (!ts.isArrowFunction(fn) && !ts.isFunctionExpression(fn)) return\n\n const body = ts.isBlock(fn.body) ? fn.body : null\n if (!body) return\n\n const handledCases = new Set<string>()\n let hasDefault = false\n\n function findSwitch(n: ts.Node): void {\n if (ts.isSwitchStatement(n)) {\n for (const clause of n.caseBlock.clauses) {\n if (ts.isDefaultClause(clause)) {\n hasDefault = true\n } else if (ts.isCaseClause(clause) && ts.isStringLiteral(clause.expression)) {\n handledCases.add(clause.expression.text)\n }\n }\n }\n ts.forEachChild(n, findSwitch)\n }\n\n findSwitch(body)\n\n if (hasDefault) return\n\n const missing = [...msgVariants].filter((v) => !handledCases.has(v))\n if (missing.length === 0) return\n\n const { line, column } = pos(node, sf)\n diagnostics.push({\n rule: 'exhaustive-update',\n message: `update() does not handle message type${missing.length > 1 ? 's' : ''} ${missing.map((m) => `'${m}'`).join(', ')} at line ${line}.`,\n line,\n column,\n })\n}\n\n// ── Accessibility ────────────────────────────────────────────────\n\nfunction checkAccessibility(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isCallExpression(node)) return\n if (!ts.isIdentifier(node.expression)) return\n\n const tag = node.expression.text\n if (!ELEMENT_HELPERS.has(tag)) return\n\n const propsArg = node.arguments[0]\n if (!propsArg || !ts.isObjectLiteralExpression(propsArg)) return\n\n const props = getStaticPropKeys(propsArg)\n\n // img without alt\n if (tag === 'img' && !props.has('alt')) {\n const { line, column } = pos(node, sf)\n diagnostics.push({\n rule: 'accessibility',\n message: `<img> at line ${line} has no 'alt' attribute. Add alt text for screen readers, or alt='' for decorative images.`,\n line,\n column,\n })\n }\n\n // onClick on non-interactive element without role\n if (props.has('onClick') && !INTERACTIVE_ELEMENTS.has(tag) && !props.has('role')) {\n const { line, column } = pos(node, sf)\n diagnostics.push({\n rule: 'accessibility',\n message: `onClick on <${tag}> at line ${line} without role and tabIndex. Non-interactive elements with click handlers are not keyboard-accessible. Add role='button' and tabIndex={0}, or use <button>.`,\n line,\n column,\n })\n }\n}\n\n// ── Controlled input ─────────────────────────────────────────────\n\nfunction checkControlledInput(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isCallExpression(node)) return\n if (!ts.isIdentifier(node.expression)) return\n\n const tag = node.expression.text\n if (tag !== 'input' && tag !== 'textarea') return\n\n const propsArg = node.arguments[0]\n if (!propsArg || !ts.isObjectLiteralExpression(propsArg)) return\n\n const props = getProps(propsArg)\n\n // Check if value is a reactive binding (arrow function)\n const valueProp = props.get('value')\n if (!valueProp) return\n if (!ts.isArrowFunction(valueProp) && !ts.isFunctionExpression(valueProp)) return\n\n // Must have onInput\n if (!props.has('onInput') && !props.has('onChange')) {\n const { line, column } = pos(node, sf)\n diagnostics.push({\n rule: 'controlled-input',\n message: `Controlled input at line ${line}: reactive 'value' binding without 'onInput' handler. The binding will overwrite user input on every state update.`,\n line,\n column,\n })\n }\n}\n\nfunction getStaticPropKeys(obj: ts.ObjectLiteralExpression): Set<string> {\n const keys = new Set<string>()\n for (const prop of obj.properties) {\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {\n keys.add(prop.name.text)\n }\n }\n return keys\n}\n\nfunction getProps(obj: ts.ObjectLiteralExpression): Map<string, ts.Expression> {\n const map = new Map<string, ts.Expression>()\n for (const prop of obj.properties) {\n if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {\n map.set(prop.name.text, prop.initializer)\n }\n }\n return map\n}\n\n// ── child() static props ────────────────────────────────────────\n\nfunction checkChildStaticProps(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isCallExpression(node)) return\n if (!ts.isIdentifier(node.expression) || node.expression.text !== 'child') return\n\n const arg = node.arguments[0]\n if (!arg || !ts.isObjectLiteralExpression(arg)) return\n\n for (const prop of arg.properties) {\n if (!ts.isPropertyAssignment(prop)) continue\n if (!ts.isIdentifier(prop.name) || prop.name.text !== 'props') continue\n\n // props must be a function, not an object literal\n if (ts.isObjectLiteralExpression(prop.initializer)) {\n const { line, column } = pos(node, sf)\n diagnostics.push({\n rule: 'child-static-props',\n message: `child() at line ${line}: 'props' is a static object literal. It must be a reactive accessor function (s => ({ ... })) so props update when parent state changes.`,\n line,\n column,\n })\n continue\n }\n\n // props accessor: warn when the returned object contains fresh\n // object/array literals. The prop-diff in `child()` compares by\n // reference per top-level key (Object.is), so a freshly-constructed\n // nested value reports changed on every parent update — propsMsg\n // fires every render, which is wasted work at best and an infinite\n // loop vector when combined with a naive `onMsg` forwarder.\n if (ts.isArrowFunction(prop.initializer) || ts.isFunctionExpression(prop.initializer)) {\n const returned = getReturnedObjectLiteral(prop.initializer)\n if (!returned) continue\n for (const keyProp of returned.properties) {\n if (!ts.isPropertyAssignment(keyProp)) continue\n const init = keyProp.initializer\n if (!ts.isObjectLiteralExpression(init) && !ts.isArrayLiteralExpression(init)) continue\n const keyName = ts.isIdentifier(keyProp.name)\n ? keyProp.name.text\n : ts.isStringLiteral(keyProp.name)\n ? keyProp.name.text\n : '<?>'\n const kind = ts.isArrayLiteralExpression(init) ? 'array' : 'object'\n const { line, column } = pos(keyProp, sf)\n diagnostics.push({\n rule: 'child-static-props',\n message: `child() at line ${line}: the 'props' accessor returns a fresh ${kind} literal for '${keyName}'. Prop diffing uses Object.is per key, so a freshly-constructed reference reports changed every render — propsMsg will fire on every parent update. Hoist to a module-level constant, reuse a reference from state, or return null from propsMsg when the value is unchanged.`,\n line,\n column,\n })\n }\n }\n }\n}\n\nfunction getReturnedObjectLiteral(\n fn: ts.ArrowFunction | ts.FunctionExpression,\n): ts.ObjectLiteralExpression | null {\n const body = fn.body\n if (ts.isParenthesizedExpression(body) && ts.isObjectLiteralExpression(body.expression)) {\n return body.expression\n }\n if (ts.isObjectLiteralExpression(body)) return body\n if (ts.isBlock(body)) {\n for (const stmt of body.statements) {\n if (!ts.isReturnStatement(stmt) || !stmt.expression) continue\n const expr = stmt.expression\n if (ts.isObjectLiteralExpression(expr)) return expr\n if (ts.isParenthesizedExpression(expr) && ts.isObjectLiteralExpression(expr.expression)) {\n return expr.expression\n }\n }\n }\n return null\n}\n\n// ── Bitmask overflow warning ────────────────────────────────────\n// The path-scan walker lives in `collect-deps.ts` and is shared with\n// the runtime bit-assignment path. Keeping one scanner means one truth\n// about what counts as a reactive accessor.\n\nfunction checkBitmaskOverflow(\n node: ts.Node,\n sf: ts.SourceFile,\n diagnostics: Diagnostic[],\n paths: Set<string>,\n): void {\n // Only emit once, on the component() call\n if (!ts.isCallExpression(node)) return\n if (!ts.isIdentifier(node.expression) || node.expression.text !== 'component') return\n\n const pathCount = paths.size\n if (pathCount <= 31) return\n\n const overflow = pathCount - 31\n const { line, column } = pos(node, sf)\n\n // Group paths by top-level field so authors know which slice to extract.\n // `resolveSimpleChain` already truncates to depth 2 (e.g. \"user.name\"),\n // so splitting on \".\" gives us the top-level field.\n const byTopLevel = new Map<string, number>()\n for (const p of paths) {\n const top = p.split('.', 1)[0]!\n byTopLevel.set(top, (byTopLevel.get(top) ?? 0) + 1)\n }\n const sorted = [...byTopLevel.entries()].sort((a, b) => b[1] - a[1])\n\n // Pick the top fields whose combined path count would bring us under\n // the 31 limit. These are the best candidates to extract.\n const candidates: string[] = []\n let saved = 0\n for (const [field, n] of sorted) {\n if (pathCount - saved <= 31) break\n candidates.push(field)\n saved += n\n }\n const breakdown = sorted.map(([field, n]) => `${field} (${n})`).join(', ')\n const candidateList = candidates.map((f) => `\\`${f}\\``).join(', ')\n\n // Co-occurrence analysis: identify top-level fields whose every\n // sub-path always fires in the same accessor sets. Those are prime\n // candidates to read as a single object — the parent path (one bit)\n // replaces multiple sub-paths (one bit each), saving (count - 1) bits\n // toward the 31 limit without the larger surgery that `child()`\n // extraction requires.\n const accessorSets = collectAccessorPathSets(sf)\n const cooccurringFields = findCooccurringFields(paths, accessorSets)\n const cooccurrenceNote =\n cooccurringFields.length > 0\n ? `\\n\\nCo-occurrence detected: ` +\n cooccurringFields\n .map(\n ({ field, saved }) =>\n `every sub-path under \\`${field}\\` always fires together; reading \\`s.${field}\\` as one unit saves ${saved} bit${saved === 1 ? '' : 's'}`,\n )\n .join('; ') +\n `. Bundle those reads into a single \\`s.${cooccurringFields[0]!.field}\\` ` +\n `access (e.g. \\`const ${cooccurringFields[0]!.field} = s.${cooccurringFields[0]!.field}\\`) ` +\n `before extraction — cheaper refactor, same budget relief.`\n : ''\n\n diagnostics.push({\n rule: 'bitmask-overflow',\n message:\n `Component at line ${line} has ${pathCount} unique state access paths ` +\n `(${overflow} past the 31-path limit). Paths 32..${pathCount} fall back to ` +\n `FULL_MASK — their changes re-evaluate every binding in the component, ` +\n `negating the bitmask optimization for those updates.\\n\\n` +\n `Top-level fields by path count: ${breakdown}.` +\n cooccurrenceNote +\n `\\n\\n` +\n `Recommended fix: extract ${candidateList} into ${candidates.length === 1 ? 'a' : ''} ` +\n `child component${candidates.length === 1 ? '' : 's'} via \\`child()\\` ` +\n `(see /api/dom#child). Each child gets its own 31-path bitmask, so the ` +\n `extracted paths no longer count against the parent's limit. ` +\n `Alternative: use \\`sliceHandler\\` to embed a state machine that owns ` +\n `the field's reducer.`,\n line,\n column,\n })\n}\n\n/**\n * Identify top-level fields whose every sub-path fires in the SAME set\n * of accessors — the signature of paths that could share a single bit\n * if the author read the parent object as one unit. Returns a list of\n * `{ field, saved }` records where `saved = sub-path count - 1` (the\n * bits freed by collapsing to the parent read).\n *\n * Only meaningful for fields with 2+ sub-paths; single-path top-level\n * fields already occupy exactly one bit.\n */\nfunction findCooccurringFields(\n paths: Set<string>,\n accessorSets: Set<string>[],\n): Array<{ field: string; saved: number }> {\n // Group paths by top-level field. Only fields whose depth-2 paths\n // uniformly share the same appearance-signature are candidates.\n const subPathsByTop = new Map<string, string[]>()\n for (const p of paths) {\n const dot = p.indexOf('.')\n if (dot < 0) continue // depth-1 path — no bundling opportunity\n const top = p.slice(0, dot)\n const arr = subPathsByTop.get(top) ?? []\n arr.push(p)\n subPathsByTop.set(top, arr)\n }\n\n // For each path, record the set of accessors that read it.\n const appearances = new Map<string, Set<number>>()\n for (let i = 0; i < accessorSets.length; i++) {\n for (const path of accessorSets[i]!) {\n if (!appearances.has(path)) appearances.set(path, new Set())\n appearances.get(path)!.add(i)\n }\n }\n\n const out: Array<{ field: string; saved: number }> = []\n for (const [field, subPaths] of subPathsByTop) {\n if (subPaths.length < 2) continue\n // Compute the signature for each sub-path and check they all match.\n const first = appearances.get(subPaths[0]!) ?? new Set<number>()\n let uniform = true\n for (let i = 1; i < subPaths.length; i++) {\n const set = appearances.get(subPaths[i]!) ?? new Set<number>()\n if (!setsEqual(first, set)) {\n uniform = false\n break\n }\n }\n if (uniform) out.push({ field, saved: subPaths.length - 1 })\n }\n return out.sort((a, b) => b.saved - a.saved)\n}\n\nfunction setsEqual<T>(a: Set<T>, b: Set<T>): boolean {\n if (a.size !== b.size) return false\n for (const x of a) if (!b.has(x)) return false\n return true\n}\n\n// ── scope/branch `on` reads no state ────────────────────────────\n// If the discriminant accessor doesn't read any state paths, the key\n// never changes after mount and the subtree never rebuilds. Likely a\n// bug — warn so the author can verify intent.\n\nfunction checkStaticOn(node: ts.Node, sf: ts.SourceFile, diagnostics: Diagnostic[]): void {\n if (!ts.isCallExpression(node)) return\n if (!ts.isIdentifier(node.expression)) return\n const name = node.expression.text\n if (name !== 'scope' && name !== 'branch') return\n\n const optsArg = node.arguments[0]\n if (!optsArg || !ts.isObjectLiteralExpression(optsArg)) return\n\n const onProp = optsArg.properties.find(\n (p): p is ts.PropertyAssignment =>\n ts.isPropertyAssignment(p) && ts.isIdentifier(p.name) && p.name.text === 'on',\n )\n if (!onProp) return\n const onValue = onProp.initializer\n if (!ts.isArrowFunction(onValue) && !ts.isFunctionExpression(onValue)) return\n\n // Extract paths rooted at `on`'s single parameter. Zero-param\n // on (`on: () => 'x'`) definitionally reads no state and must warn.\n const params = onValue.parameters\n const paths = new Set<string>()\n if (params.length === 1) {\n const param = params[0]!.name\n if (!ts.isIdentifier(param)) return\n collectPathsInBody(onValue.body, param.text, paths)\n } else if (params.length !== 0) {\n return\n }\n if (paths.size > 0) return\n\n const { line, column } = pos(node, sf)\n diagnostics.push({\n rule: 'static-on',\n message:\n `${name}() at line ${line}: 'on' reads no state — the key never ` +\n `changes, so the subtree mounts once and never rebuilds. ` +\n `Is this intentional? If so, consider replacing with a static ` +\n `builder; if not, reference the state field(s) that drive the ` +\n `discriminant.`,\n line,\n column,\n })\n}\n\n// Minimal state-path extractor used only by checkStaticOn; it needs the\n// same \"chain rooted at paramName\" logic as the shared collector but\n// without walking into nested reactive-accessor arrows (we only care\n// about reads inside `on`'s immediate body).\nfunction collectPathsInBody(body: ts.Node, paramName: string, out: Set<string>): void {\n if (ts.isPropertyAccessExpression(body)) {\n const parts: string[] = []\n let current: ts.Expression = body\n while (ts.isPropertyAccessExpression(current)) {\n parts.unshift(current.name.text)\n current = current.expression\n }\n if (ts.isIdentifier(current) && current.text === paramName) {\n out.add(parts.slice(0, 2).join('.'))\n }\n }\n if (ts.isElementAccessExpression(body)) {\n if (\n ts.isIdentifier(body.expression) &&\n body.expression.text === paramName &&\n ts.isStringLiteral(body.argumentExpression)\n ) {\n out.add(body.argumentExpression.text)\n }\n }\n ts.forEachChild(body, (child) => collectPathsInBody(child, paramName, out))\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -1,16 +1,52 @@
1
1
  import type { Plugin } from 'vite';
2
+ import { type DiagnosticRule } from './diagnostics.js';
3
+ export type { DiagnosticRule } from './diagnostics.js';
2
4
  export interface LluiPluginOptions {
3
5
  /**
4
6
  * Port for the MCP debug bridge. In dev mode, the runtime relay connects
5
7
  * to `ws://127.0.0.1:<port>` so an external `llui-mcp` server can forward
6
8
  * tool calls into the running app.
7
9
  *
8
- * Defaults to `false` (opt-in). Pass a number (typically `5200`) to
9
- * enable. When enabled but the MCP server isn't running, the plugin
10
- * returns 404 from its discovery endpoint and the browser silently
11
- * skips the connection no retry noise.
10
+ * When omitted, the plugin checks whether `@llui/mcp` is resolvable from
11
+ * the Vite project root. If yes defaults to `5200`. If no stays
12
+ * disabled. This means installing `@llui/mcp` (+ starting its server)
13
+ * Just Works without an explicit config entry. Pass an explicit `false`
14
+ * to opt out even when `@llui/mcp` is installed; pass a number to use
15
+ * a non-default port. When enabled but the MCP server isn't running,
16
+ * the plugin returns 404 from its discovery endpoint and the browser
17
+ * silently skips the connection — no retry noise.
12
18
  */
13
19
  mcpPort?: number | false;
20
+ /**
21
+ * Treat every compiler diagnostic as a build error.
22
+ *
23
+ * Default `false` — diagnostics are emitted via rollup's `this.warn` and
24
+ * can be ignored. Set to `true` in CI so lint-style regressions (namespace
25
+ * imports, bitmask overflow, spread-in-children, `.map()` on state, etc.)
26
+ * fail the build without requiring a custom `build.rollupOptions.onwarn`
27
+ * handler.
28
+ */
29
+ failOnWarning?: boolean;
30
+ /**
31
+ * Silence specific diagnostic rules without disabling the whole lint
32
+ * pass. Each message is tagged with a rule name (shown in brackets at
33
+ * the start of every warning, e.g. `[spread-in-children]`). Listing
34
+ * a rule here drops all diagnostics with that tag before rollup sees
35
+ * them — so they don't fire via `this.warn` and don't fail the build
36
+ * even when `failOnWarning` is enabled.
37
+ *
38
+ * The valid rule names are enumerated by the `DiagnosticRule` type
39
+ * re-exported from this module. Unknown rule names are ignored.
40
+ */
41
+ disabledWarnings?: readonly DiagnosticRule[];
42
+ /**
43
+ * Emit `[llui]`-prefixed `console.info` logs for every transformed
44
+ * component file — state-path bit assignments, mask injections, and
45
+ * helper compile/bail counts. Useful when diagnosing why a binding
46
+ * isn't gated the way you expect, or why a call fell back from
47
+ * template-clone to `elSplit`. Off by default.
48
+ */
49
+ verbose?: boolean;
14
50
  }
15
51
  export default function llui(options?: LluiPluginOptions): Plugin;
16
52
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAA;AA0BjD,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;CACzB;AAED,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAqMpE"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAiB,MAAM,MAAM,CAAA;AAOjD,OAAO,EAAY,KAAK,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAEhE,YAAY,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAA;AAqBtD,MAAM,WAAW,iBAAiB;IAChC;;;;;;;;;;;;;OAaG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IAExB;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,OAAO,CAAA;IAEvB;;;;;;;;;;OAUG;IACH,gBAAgB,CAAC,EAAE,SAAS,cAAc,EAAE,CAAA;IAE5C;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAsCD,MAAM,CAAC,OAAO,UAAU,IAAI,CAAC,OAAO,GAAE,iBAAsB,GAAG,MAAM,CA2RpE"}
package/dist/index.js CHANGED
@@ -1,6 +1,8 @@
1
1
  import MagicString from 'magic-string';
2
2
  import { existsSync, readFileSync, writeFileSync, watch as fsWatch } from 'node:fs';
3
- import { dirname, resolve } from 'node:path';
3
+ import { dirname, relative, resolve } from 'node:path';
4
+ import { createRequire } from 'node:module';
5
+ import { spawn } from 'node:child_process';
4
6
  import { transformLlui } from './transform.js';
5
7
  import { diagnose } from './diagnostics.js';
6
8
  /**
@@ -25,12 +27,56 @@ function findWorkspaceRoot(start = process.cwd()) {
25
27
  dir = parent;
26
28
  }
27
29
  }
30
+ /**
31
+ * Does `@llui/mcp` resolve from `root`'s node_modules? Uses
32
+ * `require.resolve` so monorepo workspaces and hoisted installs both
33
+ * work. Catches failures silently — the only consequence is that we
34
+ * leave `mcpPort` disabled, which is the safe default.
35
+ */
36
+ function hasMcpPackage(root) {
37
+ try {
38
+ const req = createRequire(resolve(root, 'package.json'));
39
+ req.resolve('@llui/mcp/package.json');
40
+ return true;
41
+ }
42
+ catch {
43
+ return false;
44
+ }
45
+ }
46
+ /**
47
+ * Resolve the path to the llui-mcp CLI entry. Reads `bin.llui-mcp`
48
+ * from @llui/mcp's package.json and joins it against the package
49
+ * directory. Returns null if @llui/mcp isn't resolvable.
50
+ */
51
+ function resolveMcpCliPath(root) {
52
+ try {
53
+ const req = createRequire(resolve(root, 'package.json'));
54
+ const pkgJsonPath = req.resolve('@llui/mcp/package.json');
55
+ const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf8'));
56
+ const binEntry = typeof pkgJson.bin === 'string' ? pkgJson.bin : pkgJson.bin?.['llui-mcp'];
57
+ if (!binEntry)
58
+ return null;
59
+ return resolve(dirname(pkgJsonPath), binEntry);
60
+ }
61
+ catch {
62
+ return null;
63
+ }
64
+ }
28
65
  export default function llui(options = {}) {
29
66
  let devMode = false;
30
- // MCP is opt-in: developers who want interactive debugging pass an
31
- // explicit port. Leaving it off avoids 404 polling in projects that
32
- // don't use the companion server.
33
- const mcpPort = options.mcpPort === false || options.mcpPort === undefined ? null : options.mcpPort;
67
+ // `mcpPort` + `mcpMode` are resolved lazily in `configResolved` so we
68
+ // can check for @llui/mcp in the consuming project's node_modules.
69
+ // - `options.mcpPort === false` → disabled
70
+ // - explicit number → wire-only (user manages the server)
71
+ // - undefined + @llui/mcp found → spawn (plugin starts llui-mcp --http)
72
+ // - undefined + no @llui/mcp → disabled
73
+ let mcpPort = null;
74
+ let mcpMode = 'disabled';
75
+ let mcpCliPath = null;
76
+ let mcpChild = null;
77
+ const failOnWarning = options.failOnWarning === true;
78
+ const disabledWarnings = new Set(options.disabledWarnings ?? []);
79
+ const verbose = options.verbose === true;
34
80
  // File-based handshake with @llui/mcp. The MCP server writes a marker
35
81
  // file when its bridge starts; we watch it and send a Vite HMR custom
36
82
  // event so the browser can call __lluiConnect() automatically — without
@@ -93,10 +139,73 @@ export default function llui(options = {}) {
93
139
  enforce: 'pre',
94
140
  configResolved(config) {
95
141
  devMode = config.command === 'serve' || config.mode === 'development';
142
+ if (options.mcpPort === false) {
143
+ mcpMode = 'disabled';
144
+ mcpPort = null;
145
+ }
146
+ else if (typeof options.mcpPort === 'number') {
147
+ mcpMode = 'wire';
148
+ mcpPort = options.mcpPort;
149
+ }
150
+ else if (hasMcpPackage(config.root)) {
151
+ mcpCliPath = resolveMcpCliPath(config.root);
152
+ if (mcpCliPath) {
153
+ mcpMode = 'spawn';
154
+ mcpPort = 5200;
155
+ }
156
+ else {
157
+ mcpMode = 'wire';
158
+ mcpPort = 5200;
159
+ }
160
+ }
161
+ else {
162
+ mcpMode = 'disabled';
163
+ mcpPort = null;
164
+ }
96
165
  },
97
166
  configureServer(server) {
98
- if (mcpPort === null)
167
+ if (mcpPort === null) {
168
+ // #3 diagnostic: MCP server is running but the plugin is opted
169
+ // out. Users in this state usually don't realize the mismatch —
170
+ // loud-and-early log saves the "why isn't my MCP attached" hunt.
171
+ if (existsSync(activeFilePath)) {
172
+ console.warn(`[llui] @llui/mcp server is running (marker at ${activeFilePath}) ` +
173
+ `but the Vite plugin is opted out (mcpPort: false, or @llui/mcp ` +
174
+ `isn't a dep of this project). Add \`llui({ mcpPort: 5200 })\` ` +
175
+ `to vite.config to wire them up, or remove the marker file and ` +
176
+ `stop the MCP server if the mismatch was unintended.`);
177
+ }
99
178
  return;
179
+ }
180
+ // Spawn mode: plugin launches llui-mcp as a child process so
181
+ // `pnpm dev` handles the whole stack. Skip spawning when a marker
182
+ // already exists — something (usually a separate llui-mcp process
183
+ // started before Vite) is already listening. The existing wire
184
+ // behavior takes over from there.
185
+ if (mcpMode === 'spawn' && mcpCliPath !== null && !existsSync(activeFilePath)) {
186
+ mcpChild = spawn(process.execPath, [mcpCliPath, '--http', String(mcpPort)], {
187
+ stdio: ['ignore', 'pipe', 'pipe'],
188
+ env: { ...process.env, LLUI_MCP_PORT: String(mcpPort) },
189
+ });
190
+ mcpChild.stdout?.on('data', (buf) => {
191
+ process.stdout.write(`[mcp] ${buf.toString()}`);
192
+ });
193
+ mcpChild.stderr?.on('data', (buf) => {
194
+ process.stderr.write(`[mcp] ${buf.toString()}`);
195
+ });
196
+ mcpChild.on('exit', (code) => {
197
+ if (code !== 0 && code !== null) {
198
+ console.warn(`[llui] @llui/mcp child exited with code ${code}`);
199
+ }
200
+ mcpChild = null;
201
+ });
202
+ const killChild = () => {
203
+ if (mcpChild && !mcpChild.killed)
204
+ mcpChild.kill('SIGTERM');
205
+ };
206
+ server.httpServer?.on('close', killChild);
207
+ process.once('exit', killChild);
208
+ }
100
209
  // HTTP endpoint: the browser fetches this on load to discover the
101
210
  // current MCP port. Avoids the race where HMR events sent before
102
211
  // the import.meta.hot listener registers get dropped — and lets
@@ -193,10 +302,28 @@ export default function llui(options = {}) {
193
302
  transform(code, id) {
194
303
  if (!id.endsWith('.ts') && !id.endsWith('.tsx'))
195
304
  return;
196
- for (const d of diagnose(code)) {
197
- this.warn(d.message, { line: d.line, column: d.column });
305
+ const diagnostics = diagnose(code);
306
+ if (diagnostics.length > 0) {
307
+ // Prefix every diagnostic with `<file>:<line>:<col>` plus the
308
+ // `[rule-name]` tag so consumers logging `warning.message` in a
309
+ // custom onwarn handler see both the location and the rule they
310
+ // could silence via `disabledWarnings`.
311
+ const cwd = process.cwd();
312
+ const rel = relative(cwd, id);
313
+ const display = rel.startsWith('..') ? id : rel;
314
+ for (const d of diagnostics) {
315
+ if (disabledWarnings.has(d.rule))
316
+ continue;
317
+ const message = `${display}:${d.line}:${d.column}: [${d.rule}] ${d.message}`;
318
+ if (failOnWarning) {
319
+ this.error({ message, loc: { line: d.line, column: d.column, file: id } });
320
+ }
321
+ else {
322
+ this.warn(message, { line: d.line, column: d.column });
323
+ }
324
+ }
198
325
  }
199
- const result = transformLlui(code, id, devMode, mcpPort);
326
+ const result = transformLlui(code, id, devMode, mcpPort, verbose);
200
327
  if (!result)
201
328
  return undefined;
202
329
  // Apply per-statement edits via MagicString for accurate source maps.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Plugin, ViteDevServer } from 'vite'\nimport MagicString from 'magic-string'\nimport { existsSync, readFileSync, writeFileSync, watch as fsWatch, type FSWatcher } from 'node:fs'\nimport { dirname, resolve } from 'node:path'\nimport { transformLlui } from './transform.js'\nimport { diagnose } from './diagnostics.js'\n\n/**\n * Locate the workspace root so we share the MCP active marker file\n * with @llui/mcp regardless of which subdirectory the dev server runs in.\n * Mirrors `findWorkspaceRoot` from @llui/mcp — duplicated to avoid a\n * vite-plugin → mcp dependency cycle. The contract must stay in sync.\n */\nfunction findWorkspaceRoot(start: string = process.cwd()): string {\n let dir = resolve(start)\n let lastPackageJson: string | null = null\n while (true) {\n if (existsSync(resolve(dir, 'pnpm-workspace.yaml'))) return dir\n if (existsSync(resolve(dir, '.git'))) return dir\n if (existsSync(resolve(dir, 'package.json'))) lastPackageJson = dir\n const parent = dirname(dir)\n if (parent === dir) return lastPackageJson ?? start\n dir = parent\n }\n}\n\nexport interface LluiPluginOptions {\n /**\n * Port for the MCP debug bridge. In dev mode, the runtime relay connects\n * to `ws://127.0.0.1:<port>` so an external `llui-mcp` server can forward\n * tool calls into the running app.\n *\n * Defaults to `false` (opt-in). Pass a number (typically `5200`) to\n * enable. When enabled but the MCP server isn't running, the plugin\n * returns 404 from its discovery endpoint and the browser silently\n * skips the connection — no retry noise.\n */\n mcpPort?: number | false\n}\n\nexport default function llui(options: LluiPluginOptions = {}): Plugin {\n let devMode = false\n // MCP is opt-in: developers who want interactive debugging pass an\n // explicit port. Leaving it off avoids 404 polling in projects that\n // don't use the companion server.\n const mcpPort =\n options.mcpPort === false || options.mcpPort === undefined ? null : options.mcpPort\n\n // File-based handshake with @llui/mcp. The MCP server writes a marker\n // file when its bridge starts; we watch it and send a Vite HMR custom\n // event so the browser can call __lluiConnect() automatically — without\n // retry spam, regardless of whether MCP or Vite started first.\n const activeFilePath = resolve(findWorkspaceRoot(), 'node_modules/.cache/llui-mcp/active.json')\n let mcpWatcher: FSWatcher | null = null\n let dirWatcher: FSWatcher | null = null\n // Cached once Vite's HTTP server emits `listening`. `stampDevUrl()`\n // uses this to write the URL into the marker file — either immediately\n // (if MCP already started and wrote one) or later when the marker\n // appears via the directory watcher (MCP-starts-after-Vite path).\n let cachedDevUrl: string | null = null\n\n function readMcpMarker(): { port: number; devUrl?: string } | null {\n try {\n if (!existsSync(activeFilePath)) return null\n const data = JSON.parse(readFileSync(activeFilePath, 'utf8')) as {\n port?: number\n devUrl?: string\n }\n if (typeof data.port !== 'number') return null\n return { port: data.port, ...(data.devUrl ? { devUrl: data.devUrl } : {}) }\n } catch {\n return null\n }\n }\n\n /**\n * Idempotently write `cachedDevUrl` into the marker file. No-op if the\n * URL hasn't been captured yet (Vite hasn't emitted `listening`) or if\n * the marker file doesn't exist (MCP hasn't started yet). Covers both\n * orderings — the listening hook calls this after caching, and the\n * directory watcher calls it when the marker appears later.\n */\n function stampDevUrl(): void {\n if (cachedDevUrl === null) return\n if (!existsSync(activeFilePath)) return\n try {\n const marker = JSON.parse(readFileSync(activeFilePath, 'utf8')) as Record<string, unknown>\n if (marker.devUrl === cachedDevUrl) return\n marker.devUrl = cachedDevUrl\n writeFileSync(activeFilePath, JSON.stringify(marker))\n } catch {\n // Best-effort — failure to update the marker should not crash Vite\n }\n }\n\n function notifyMcpReady(server: ViteDevServer): void {\n const marker = readMcpMarker()\n if (marker === null) return\n server.ws.send({ type: 'custom', event: 'llui:mcp-ready', data: marker })\n }\n\n function notifyMcpOffline(server: ViteDevServer): void {\n server.ws.send({ type: 'custom', event: 'llui:mcp-offline', data: {} })\n }\n\n return {\n name: 'llui',\n enforce: 'pre',\n\n configResolved(config) {\n devMode = config.command === 'serve' || config.mode === 'development'\n },\n\n configureServer(server) {\n if (mcpPort === null) return\n\n // HTTP endpoint: the browser fetches this on load to discover the\n // current MCP port. Avoids the race where HMR events sent before\n // the import.meta.hot listener registers get dropped — and lets\n // the browser connect to the actual port (which may differ from\n // the compile-time default if MCP was started with LLUI_MCP_PORT).\n server.middlewares.use('/__llui_mcp_status', (_req, res) => {\n const marker = readMcpMarker()\n if (marker === null) {\n res.statusCode = 404\n res.end()\n return\n }\n res.statusCode = 200\n res.setHeader('content-type', 'application/json')\n res.end(JSON.stringify({ port: marker.port }))\n })\n\n // Watch the marker file for create/delete. fs.watch on the parent\n // directory catches both events; the file itself may not exist\n // when we start watching.\n const dir = dirname(activeFilePath)\n try {\n // Watch the parent directory for the marker file appearing/disappearing\n const watchDir = (): void => {\n if (!existsSync(dir)) return\n dirWatcher = fsWatch(dir, (_event, filename) => {\n if (filename !== 'active.json') return\n if (existsSync(activeFilePath)) {\n // Stamp BEFORE notifying so the `llui:mcp-ready` payload\n // carries the cached devUrl. This is the MCP-after-Vite\n // path: listening already fired and cached the URL; the\n // marker is only now appearing.\n stampDevUrl()\n notifyMcpReady(server)\n } else {\n notifyMcpOffline(server)\n }\n })\n }\n if (existsSync(dir)) {\n watchDir()\n } else {\n // Parent directory doesn't exist yet — poll for it briefly\n const poll = setInterval(() => {\n if (existsSync(dir)) {\n clearInterval(poll)\n watchDir()\n }\n }, 1000)\n // Clean up the poller if vite shuts down before MCP starts\n server.httpServer?.on('close', () => clearInterval(poll))\n }\n } catch {\n // fs.watch can fail on some filesystems — degrade silently\n }\n\n // Re-send the ready event when a new HMR client connects, in case\n // the page loads while MCP is already running.\n server.ws.on('connection', () => {\n if (existsSync(activeFilePath)) notifyMcpReady(server)\n })\n\n server.httpServer?.on('close', () => {\n mcpWatcher?.close()\n dirWatcher?.close()\n mcpWatcher = null\n dirWatcher = null\n })\n\n // Once Vite's HTTP server is listening, cache our dev URL and stamp\n // it into the marker file. Two orderings are possible:\n // (a) MCP started FIRST → marker exists now → stampDevUrl() writes\n // it, and we broadcast llui:mcp-ready so the browser picks up\n // the devUrl without relying on an incidental fs.watch tick\n // (which can miss on NFS/SMB).\n // (b) MCP will start LATER → marker doesn't exist yet → stamp is a\n // no-op. When MCP eventually writes the marker, the directory\n // watcher fires, calls stampDevUrl(), and notifies.\n server.httpServer?.once('listening', () => {\n const address = server.httpServer?.address()\n if (!address || typeof address !== 'object') return\n const host =\n address.address === '::' || address.address === '0.0.0.0' ? 'localhost' : address.address\n cachedDevUrl = `http://${host}:${address.port}`\n stampDevUrl()\n // Broadcast after stamping so the payload carries devUrl. Only\n // fires in case (a) — notifyMcpReady no-ops when the marker is\n // absent.\n notifyMcpReady(server)\n })\n },\n\n transform(code, id) {\n if (!id.endsWith('.ts') && !id.endsWith('.tsx')) return\n\n for (const d of diagnose(code)) {\n this.warn(d.message, { line: d.line, column: d.column })\n }\n\n const result = transformLlui(code, id, devMode, mcpPort)\n if (!result) return undefined\n\n // Apply per-statement edits via MagicString for accurate source maps.\n // Untouched statements keep their original positions.\n const s = new MagicString(code)\n for (const edit of result.edits) {\n if (edit.start === edit.end) {\n // Insert at position — appendRight for middle, append for end-of-file\n if (edit.start === code.length) s.append(edit.replacement)\n else s.appendRight(edit.start, edit.replacement)\n } else {\n s.overwrite(edit.start, edit.end, edit.replacement)\n }\n }\n\n return {\n code: s.toString(),\n map: s.generateMap({ source: id, includeContent: true, hires: true }),\n }\n },\n }\n}\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Plugin, ViteDevServer } from 'vite'\nimport MagicString from 'magic-string'\nimport { existsSync, readFileSync, writeFileSync, watch as fsWatch, type FSWatcher } from 'node:fs'\nimport { dirname, relative, resolve } from 'node:path'\nimport { createRequire } from 'node:module'\nimport { spawn, type ChildProcess } from 'node:child_process'\nimport { transformLlui } from './transform.js'\nimport { diagnose, type DiagnosticRule } from './diagnostics.js'\n\nexport type { DiagnosticRule } from './diagnostics.js'\n\n/**\n * Locate the workspace root so we share the MCP active marker file\n * with @llui/mcp regardless of which subdirectory the dev server runs in.\n * Mirrors `findWorkspaceRoot` from @llui/mcp — duplicated to avoid a\n * vite-plugin → mcp dependency cycle. The contract must stay in sync.\n */\nfunction findWorkspaceRoot(start: string = process.cwd()): string {\n let dir = resolve(start)\n let lastPackageJson: string | null = null\n while (true) {\n if (existsSync(resolve(dir, 'pnpm-workspace.yaml'))) return dir\n if (existsSync(resolve(dir, '.git'))) return dir\n if (existsSync(resolve(dir, 'package.json'))) lastPackageJson = dir\n const parent = dirname(dir)\n if (parent === dir) return lastPackageJson ?? start\n dir = parent\n }\n}\n\nexport interface LluiPluginOptions {\n /**\n * Port for the MCP debug bridge. In dev mode, the runtime relay connects\n * to `ws://127.0.0.1:<port>` so an external `llui-mcp` server can forward\n * tool calls into the running app.\n *\n * When omitted, the plugin checks whether `@llui/mcp` is resolvable from\n * the Vite project root. If yes → defaults to `5200`. If no → stays\n * disabled. This means installing `@llui/mcp` (+ starting its server)\n * Just Works without an explicit config entry. Pass an explicit `false`\n * to opt out even when `@llui/mcp` is installed; pass a number to use\n * a non-default port. When enabled but the MCP server isn't running,\n * the plugin returns 404 from its discovery endpoint and the browser\n * silently skips the connection — no retry noise.\n */\n mcpPort?: number | false\n\n /**\n * Treat every compiler diagnostic as a build error.\n *\n * Default `false` — diagnostics are emitted via rollup's `this.warn` and\n * can be ignored. Set to `true` in CI so lint-style regressions (namespace\n * imports, bitmask overflow, spread-in-children, `.map()` on state, etc.)\n * fail the build without requiring a custom `build.rollupOptions.onwarn`\n * handler.\n */\n failOnWarning?: boolean\n\n /**\n * Silence specific diagnostic rules without disabling the whole lint\n * pass. Each message is tagged with a rule name (shown in brackets at\n * the start of every warning, e.g. `[spread-in-children]`). Listing\n * a rule here drops all diagnostics with that tag before rollup sees\n * them — so they don't fire via `this.warn` and don't fail the build\n * even when `failOnWarning` is enabled.\n *\n * The valid rule names are enumerated by the `DiagnosticRule` type\n * re-exported from this module. Unknown rule names are ignored.\n */\n disabledWarnings?: readonly DiagnosticRule[]\n\n /**\n * Emit `[llui]`-prefixed `console.info` logs for every transformed\n * component file — state-path bit assignments, mask injections, and\n * helper compile/bail counts. Useful when diagnosing why a binding\n * isn't gated the way you expect, or why a call fell back from\n * template-clone to `elSplit`. Off by default.\n */\n verbose?: boolean\n}\n\n/**\n * Does `@llui/mcp` resolve from `root`'s node_modules? Uses\n * `require.resolve` so monorepo workspaces and hoisted installs both\n * work. Catches failures silently — the only consequence is that we\n * leave `mcpPort` disabled, which is the safe default.\n */\nfunction hasMcpPackage(root: string): boolean {\n try {\n const req = createRequire(resolve(root, 'package.json'))\n req.resolve('@llui/mcp/package.json')\n return true\n } catch {\n return false\n }\n}\n\n/**\n * Resolve the path to the llui-mcp CLI entry. Reads `bin.llui-mcp`\n * from @llui/mcp's package.json and joins it against the package\n * directory. Returns null if @llui/mcp isn't resolvable.\n */\nfunction resolveMcpCliPath(root: string): string | null {\n try {\n const req = createRequire(resolve(root, 'package.json'))\n const pkgJsonPath = req.resolve('@llui/mcp/package.json')\n const pkgJson = JSON.parse(readFileSync(pkgJsonPath, 'utf8')) as {\n bin?: string | Record<string, string>\n }\n const binEntry = typeof pkgJson.bin === 'string' ? pkgJson.bin : pkgJson.bin?.['llui-mcp']\n if (!binEntry) return null\n return resolve(dirname(pkgJsonPath), binEntry)\n } catch {\n return null\n }\n}\n\nexport default function llui(options: LluiPluginOptions = {}): Plugin {\n let devMode = false\n // `mcpPort` + `mcpMode` are resolved lazily in `configResolved` so we\n // can check for @llui/mcp in the consuming project's node_modules.\n // - `options.mcpPort === false` → disabled\n // - explicit number → wire-only (user manages the server)\n // - undefined + @llui/mcp found → spawn (plugin starts llui-mcp --http)\n // - undefined + no @llui/mcp → disabled\n let mcpPort: number | null = null\n let mcpMode: 'disabled' | 'wire' | 'spawn' = 'disabled'\n let mcpCliPath: string | null = null\n let mcpChild: ChildProcess | null = null\n const failOnWarning = options.failOnWarning === true\n const disabledWarnings = new Set<string>(options.disabledWarnings ?? [])\n const verbose = options.verbose === true\n\n // File-based handshake with @llui/mcp. The MCP server writes a marker\n // file when its bridge starts; we watch it and send a Vite HMR custom\n // event so the browser can call __lluiConnect() automatically — without\n // retry spam, regardless of whether MCP or Vite started first.\n const activeFilePath = resolve(findWorkspaceRoot(), 'node_modules/.cache/llui-mcp/active.json')\n let mcpWatcher: FSWatcher | null = null\n let dirWatcher: FSWatcher | null = null\n // Cached once Vite's HTTP server emits `listening`. `stampDevUrl()`\n // uses this to write the URL into the marker file — either immediately\n // (if MCP already started and wrote one) or later when the marker\n // appears via the directory watcher (MCP-starts-after-Vite path).\n let cachedDevUrl: string | null = null\n\n function readMcpMarker(): { port: number; devUrl?: string } | null {\n try {\n if (!existsSync(activeFilePath)) return null\n const data = JSON.parse(readFileSync(activeFilePath, 'utf8')) as {\n port?: number\n devUrl?: string\n }\n if (typeof data.port !== 'number') return null\n return { port: data.port, ...(data.devUrl ? { devUrl: data.devUrl } : {}) }\n } catch {\n return null\n }\n }\n\n /**\n * Idempotently write `cachedDevUrl` into the marker file. No-op if the\n * URL hasn't been captured yet (Vite hasn't emitted `listening`) or if\n * the marker file doesn't exist (MCP hasn't started yet). Covers both\n * orderings — the listening hook calls this after caching, and the\n * directory watcher calls it when the marker appears later.\n */\n function stampDevUrl(): void {\n if (cachedDevUrl === null) return\n if (!existsSync(activeFilePath)) return\n try {\n const marker = JSON.parse(readFileSync(activeFilePath, 'utf8')) as Record<string, unknown>\n if (marker.devUrl === cachedDevUrl) return\n marker.devUrl = cachedDevUrl\n writeFileSync(activeFilePath, JSON.stringify(marker))\n } catch {\n // Best-effort — failure to update the marker should not crash Vite\n }\n }\n\n function notifyMcpReady(server: ViteDevServer): void {\n const marker = readMcpMarker()\n if (marker === null) return\n server.ws.send({ type: 'custom', event: 'llui:mcp-ready', data: marker })\n }\n\n function notifyMcpOffline(server: ViteDevServer): void {\n server.ws.send({ type: 'custom', event: 'llui:mcp-offline', data: {} })\n }\n\n return {\n name: 'llui',\n enforce: 'pre',\n\n configResolved(config) {\n devMode = config.command === 'serve' || config.mode === 'development'\n if (options.mcpPort === false) {\n mcpMode = 'disabled'\n mcpPort = null\n } else if (typeof options.mcpPort === 'number') {\n mcpMode = 'wire'\n mcpPort = options.mcpPort\n } else if (hasMcpPackage(config.root)) {\n mcpCliPath = resolveMcpCliPath(config.root)\n if (mcpCliPath) {\n mcpMode = 'spawn'\n mcpPort = 5200\n } else {\n mcpMode = 'wire'\n mcpPort = 5200\n }\n } else {\n mcpMode = 'disabled'\n mcpPort = null\n }\n },\n\n configureServer(server) {\n if (mcpPort === null) {\n // #3 diagnostic: MCP server is running but the plugin is opted\n // out. Users in this state usually don't realize the mismatch —\n // loud-and-early log saves the \"why isn't my MCP attached\" hunt.\n if (existsSync(activeFilePath)) {\n console.warn(\n `[llui] @llui/mcp server is running (marker at ${activeFilePath}) ` +\n `but the Vite plugin is opted out (mcpPort: false, or @llui/mcp ` +\n `isn't a dep of this project). Add \\`llui({ mcpPort: 5200 })\\` ` +\n `to vite.config to wire them up, or remove the marker file and ` +\n `stop the MCP server if the mismatch was unintended.`,\n )\n }\n return\n }\n\n // Spawn mode: plugin launches llui-mcp as a child process so\n // `pnpm dev` handles the whole stack. Skip spawning when a marker\n // already exists — something (usually a separate llui-mcp process\n // started before Vite) is already listening. The existing wire\n // behavior takes over from there.\n if (mcpMode === 'spawn' && mcpCliPath !== null && !existsSync(activeFilePath)) {\n mcpChild = spawn(process.execPath, [mcpCliPath, '--http', String(mcpPort)], {\n stdio: ['ignore', 'pipe', 'pipe'],\n env: { ...process.env, LLUI_MCP_PORT: String(mcpPort) },\n })\n mcpChild.stdout?.on('data', (buf: Buffer) => {\n process.stdout.write(`[mcp] ${buf.toString()}`)\n })\n mcpChild.stderr?.on('data', (buf: Buffer) => {\n process.stderr.write(`[mcp] ${buf.toString()}`)\n })\n mcpChild.on('exit', (code) => {\n if (code !== 0 && code !== null) {\n console.warn(`[llui] @llui/mcp child exited with code ${code}`)\n }\n mcpChild = null\n })\n const killChild = (): void => {\n if (mcpChild && !mcpChild.killed) mcpChild.kill('SIGTERM')\n }\n server.httpServer?.on('close', killChild)\n process.once('exit', killChild)\n }\n\n // HTTP endpoint: the browser fetches this on load to discover the\n // current MCP port. Avoids the race where HMR events sent before\n // the import.meta.hot listener registers get dropped — and lets\n // the browser connect to the actual port (which may differ from\n // the compile-time default if MCP was started with LLUI_MCP_PORT).\n server.middlewares.use('/__llui_mcp_status', (_req, res) => {\n const marker = readMcpMarker()\n if (marker === null) {\n res.statusCode = 404\n res.end()\n return\n }\n res.statusCode = 200\n res.setHeader('content-type', 'application/json')\n res.end(JSON.stringify({ port: marker.port }))\n })\n\n // Watch the marker file for create/delete. fs.watch on the parent\n // directory catches both events; the file itself may not exist\n // when we start watching.\n const dir = dirname(activeFilePath)\n try {\n // Watch the parent directory for the marker file appearing/disappearing\n const watchDir = (): void => {\n if (!existsSync(dir)) return\n dirWatcher = fsWatch(dir, (_event, filename) => {\n if (filename !== 'active.json') return\n if (existsSync(activeFilePath)) {\n // Stamp BEFORE notifying so the `llui:mcp-ready` payload\n // carries the cached devUrl. This is the MCP-after-Vite\n // path: listening already fired and cached the URL; the\n // marker is only now appearing.\n stampDevUrl()\n notifyMcpReady(server)\n } else {\n notifyMcpOffline(server)\n }\n })\n }\n if (existsSync(dir)) {\n watchDir()\n } else {\n // Parent directory doesn't exist yet — poll for it briefly\n const poll = setInterval(() => {\n if (existsSync(dir)) {\n clearInterval(poll)\n watchDir()\n }\n }, 1000)\n // Clean up the poller if vite shuts down before MCP starts\n server.httpServer?.on('close', () => clearInterval(poll))\n }\n } catch {\n // fs.watch can fail on some filesystems — degrade silently\n }\n\n // Re-send the ready event when a new HMR client connects, in case\n // the page loads while MCP is already running.\n server.ws.on('connection', () => {\n if (existsSync(activeFilePath)) notifyMcpReady(server)\n })\n\n server.httpServer?.on('close', () => {\n mcpWatcher?.close()\n dirWatcher?.close()\n mcpWatcher = null\n dirWatcher = null\n })\n\n // Once Vite's HTTP server is listening, cache our dev URL and stamp\n // it into the marker file. Two orderings are possible:\n // (a) MCP started FIRST → marker exists now → stampDevUrl() writes\n // it, and we broadcast llui:mcp-ready so the browser picks up\n // the devUrl without relying on an incidental fs.watch tick\n // (which can miss on NFS/SMB).\n // (b) MCP will start LATER → marker doesn't exist yet → stamp is a\n // no-op. When MCP eventually writes the marker, the directory\n // watcher fires, calls stampDevUrl(), and notifies.\n server.httpServer?.once('listening', () => {\n const address = server.httpServer?.address()\n if (!address || typeof address !== 'object') return\n const host =\n address.address === '::' || address.address === '0.0.0.0' ? 'localhost' : address.address\n cachedDevUrl = `http://${host}:${address.port}`\n stampDevUrl()\n // Broadcast after stamping so the payload carries devUrl. Only\n // fires in case (a) — notifyMcpReady no-ops when the marker is\n // absent.\n notifyMcpReady(server)\n })\n },\n\n transform(code, id) {\n if (!id.endsWith('.ts') && !id.endsWith('.tsx')) return\n\n const diagnostics = diagnose(code)\n if (diagnostics.length > 0) {\n // Prefix every diagnostic with `<file>:<line>:<col>` plus the\n // `[rule-name]` tag so consumers logging `warning.message` in a\n // custom onwarn handler see both the location and the rule they\n // could silence via `disabledWarnings`.\n const cwd = process.cwd()\n const rel = relative(cwd, id)\n const display = rel.startsWith('..') ? id : rel\n for (const d of diagnostics) {\n if (disabledWarnings.has(d.rule)) continue\n const message = `${display}:${d.line}:${d.column}: [${d.rule}] ${d.message}`\n if (failOnWarning) {\n this.error({ message, loc: { line: d.line, column: d.column, file: id } })\n } else {\n this.warn(message, { line: d.line, column: d.column })\n }\n }\n }\n\n const result = transformLlui(code, id, devMode, mcpPort, verbose)\n if (!result) return undefined\n\n // Apply per-statement edits via MagicString for accurate source maps.\n // Untouched statements keep their original positions.\n const s = new MagicString(code)\n for (const edit of result.edits) {\n if (edit.start === edit.end) {\n // Insert at position — appendRight for middle, append for end-of-file\n if (edit.start === code.length) s.append(edit.replacement)\n else s.appendRight(edit.start, edit.replacement)\n } else {\n s.overwrite(edit.start, edit.end, edit.replacement)\n }\n }\n\n return {\n code: s.toString(),\n map: s.generateMap({ source: id, includeContent: true, hires: true }),\n }\n },\n }\n}\n"]}
@@ -7,7 +7,7 @@ export interface TransformEdit {
7
7
  end: number;
8
8
  replacement: string;
9
9
  }
10
- export declare function transformLlui(source: string, _filename: string, devMode?: boolean, mcpPort?: number | null): {
10
+ export declare function transformLlui(source: string, _filename: string, devMode?: boolean, mcpPort?: number | null, verbose?: boolean): {
11
11
  output: string;
12
12
  edits: TransformEdit[];
13
13
  } | null;
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"AA6KA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,UAAQ,EACf,OAAO,GAAE,MAAM,GAAG,IAAW,GAC5B;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,aAAa,EAAE,CAAA;CAAE,GAAG,IAAI,CAyPnD"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../src/transform.ts"],"names":[],"mappings":"AA6KA;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,WAAW,EAAE,MAAM,CAAA;CACpB;AAED,wBAAgB,aAAa,CAC3B,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,OAAO,UAAQ,EACf,OAAO,GAAE,MAAM,GAAG,IAAW,EAC7B,OAAO,UAAQ,GACd;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,aAAa,EAAE,CAAA;CAAE,GAAG,IAAI,CAmQnD"}