diff --git a/content/docs/compiler/index.mdx b/content/docs/compiler/index.mdx index b6c9730..a12ca37 100644 --- a/content/docs/compiler/index.mdx +++ b/content/docs/compiler/index.mdx @@ -23,7 +23,7 @@ The compiler performs three sequential optimization passes on your JSX source co 2. **Static VNode hoisting** -- Fully static JSX expressions inside expression containers are lifted to module scope. 3. **Reactive wrapping** -- Dynamic expressions containing signal reads are wrapped in `() =>` arrow functions. -Each pass is applied during a single AST walk using the TypeScript parser. The compiler uses positional string replacements (applied right-to-left) rather than full AST-to-code generation, keeping the output close to the original source and preserving source map compatibility. +Each pass is applied during a single AST walk using the TypeScript parser. The compiler uses positional string replacements via an O(n) left-to-right string builder rather than full AST-to-code generation, keeping the output close to the original source and preserving source map compatibility. ## Pass 1: Reactive Wrapping @@ -684,7 +684,7 @@ A parent element with both element children and expression children is not eligi ## Implementation Details -The compiler is built on the TypeScript parser (`ts.createSourceFile`) for accurate JSX position tracking. It performs string-level replacements using character offsets, applied from right-to-left so earlier positions remain valid. This approach avoids the overhead of full AST-to-code generation and keeps the output close to the original source. +The compiler is built on the TypeScript parser (`ts.createSourceFile`) for accurate JSX position tracking. It collects string-level replacements using character offsets, then applies them in a single left-to-right pass via a string builder (`parts.push()` + `join()`). This O(n) approach avoids the overhead of full AST-to-code generation and keeps the output close to the original source. The implementation is a single recursive `walk()` function that visits every node in the source file. Template emission is checked first to avoid double-processing elements that get compiled to `_tpl()` calls. When a template-eligible subtree is found, the entire subtree is replaced with a single `_tpl()` call and the walker does not recurse into it. diff --git a/content/docs/mcp/index.mdx b/content/docs/mcp/index.mdx new file mode 100644 index 0000000..1f6c940 --- /dev/null +++ b/content/docs/mcp/index.mdx @@ -0,0 +1,206 @@ +--- +title: "@pyreon/mcp" +description: Model Context Protocol server that gives AI coding assistants deep knowledge of Pyreon APIs, patterns, and project structure. +--- + +`@pyreon/mcp` is a [Model Context Protocol](https://modelcontextprotocol.io/) server that gives AI coding assistants (Claude Code, Cursor, Windsurf, etc.) deep knowledge of Pyreon's APIs, patterns, and your project structure. It provides tools for API lookup, code validation, React migration, error diagnosis, and project introspection. + + + +## Installation + +```package-install +@pyreon/mcp +``` + +## Quick Start + +### Claude Code + +Add to your `.claude/settings.json`: + +```json +{ + "mcpServers": { + "pyreon": { + "command": "bunx", + "args": ["@pyreon/mcp"] + } + } +} +``` + +### Cursor + +Add to `.cursor/mcp.json`: + +```json +{ + "mcpServers": { + "pyreon": { + "command": "bunx", + "args": ["@pyreon/mcp"] + } + } +} +``` + +### Other MCP Clients + +The server uses stdio transport. Any MCP-compatible client can connect by spawning: + +```bash +bunx @pyreon/mcp +``` + +--- + +## Tools + +The MCP server exposes six tools that AI assistants can call. + +### get_api + +Look up any Pyreon API symbol. Returns the signature, a usage example, notes, and common mistakes. + +**Parameters:** + +| Param | Type | Description | +|-------|------|-------------| +| `package` | `string` | Package name without scope (e.g., `"reactivity"`, `"core"`, `"router"`) | +| `symbol` | `string` | Export name (e.g., `"signal"`, `"computed"`, `"createRouter"`) | + +**Example call:** + +```json +{ "package": "reactivity", "symbol": "signal" } +``` + +**Response includes:** +- TypeScript signature +- Usage example with code +- Notes on behavior +- Common mistakes and their fixes + +If the symbol is not found, the tool returns up to 5 fuzzy-matched suggestions. + +### validate + +Check a code snippet for Pyreon anti-patterns and React-isms. + +**Parameters:** + +| Param | Type | Description | +|-------|------|-------------| +| `code` | `string` | The source code to validate | +| `filename` | `string?` | Optional filename for parser context | + +**Detects issues like:** +- `useState` / `useEffect` / `useMemo` usage (should be `signal` / `effect` / `computed`) +- `.value` access on signals (should call `signal()`) +- Missing `by` prop on `` +- Passing raw signal as child instead of calling it + +Each issue includes the line number, current code, suggested fix, and whether it's auto-fixable. + +### migrate_react + +Automatically convert React code to idiomatic Pyreon. + +**Parameters:** + +| Param | Type | Description | +|-------|------|-------------| +| `code` | `string` | React source code to migrate | +| `filename` | `string?` | Optional filename | + +**Transforms:** +- `useState(x)` to `signal(x)` +- `useMemo(() => x, [deps])` to `computed(() => x)` +- `useEffect(() => {...}, [deps])` to `effect(() => {...})` +- `useCallback(fn, [deps])` to plain `fn` (no wrapper needed) +- `useRef(null)` to `createRef()` +- React imports to Pyreon imports + +Returns the migrated code, a list of applied changes, and any remaining issues that need manual attention. + +### diagnose + +Parse an error message into structured fix information. + +**Parameters:** + +| Param | Type | Description | +|-------|------|-------------| +| `error` | `string` | The error message to diagnose | + +**Response includes:** +- Root cause explanation +- Suggested fix (prose) +- Fix code snippet (when applicable) +- Related documentation links + +Recognizes common Pyreon errors like missing imports, type mismatches, SSR context issues, and router configuration problems. + +### get_routes + +List all routes detected in the current project. + +**Parameters:** None + +Scans the project directory for `createRouter` calls and route definition arrays. For each route, reports: +- Path pattern (e.g., `/user/:id`) +- Route name (if set) +- Whether it has a loader +- Whether it has a navigation guard +- Extracted path parameters + +### get_components + +List all components detected in the current project. + +**Parameters:** None + +Scans the project directory for exported component functions. For each component, reports: +- Component name and file path +- Props interface fields +- Signal declarations within the component + +--- + +## API Reference Coverage + +The `get_api` tool has entries for all public exports across these packages: + +| Package | Coverage | +|---------|----------| +| `@pyreon/reactivity` | signal, computed, effect, batch, watch, createStore, createResource, renderEffect, EffectScope | +| `@pyreon/core` | h, Fragment, createContext, useContext, onMount, onUnmount, onUpdate, Show, Switch, Match, For, Suspense, ErrorBoundary, lazy, Dynamic, defineComponent, createRef | +| `@pyreon/runtime-dom` | mount, hydrateRoot, Transition, TransitionGroup, KeepAlive, Portal, applyProp, applyProps | +| `@pyreon/compiler` | transformJSX | +| `@pyreon/router` | createRouter, RouterProvider, RouterView, RouterLink, useRouter, useRoute, useSearchParams, useLoaderData | +| `@pyreon/head` | useHead, HeadProvider | +| `@pyreon/server` | createHandler, prerender, island, hydrateIslands, startClient | +| `@pyreon/vite-plugin` | pyreon (Vite plugin factory) | + +--- + +## How It Works + +The MCP server runs as a subprocess communicating over stdio. When an AI assistant needs Pyreon-specific knowledge, it calls one of the tools above instead of guessing from training data. This ensures the assistant always has accurate, up-to-date API information regardless of its training cutoff. + +The project scanning tools (`get_routes`, `get_components`) use the same TypeScript-based scanner from `@pyreon/compiler` to analyze the actual project source code. Results are cached per working directory and regenerated when the directory changes. + +--- + +## Exports Summary + +| Export | Description | +|--------|-------------| +| CLI entry (`bin`) | Starts the MCP server on stdio transport | +| `API_REFERENCE` | Structured API documentation database | +| `generateContext` | Project scanner (re-exported from `@pyreon/compiler`) | +| `ProjectContext` | Type: scanned project metadata | +| `RouteInfo` | Type: detected route information | +| `ComponentInfo` | Type: detected component information | +| `IslandInfo` | Type: detected island information | diff --git a/content/docs/mcp/meta.json b/content/docs/mcp/meta.json new file mode 100644 index 0000000..3b7bccb --- /dev/null +++ b/content/docs/mcp/meta.json @@ -0,0 +1,5 @@ +{ + "title": "MCP Server", + "defaultOpen": true, + "pages": ["index"] +} diff --git a/content/docs/meta.json b/content/docs/meta.json index 515045b..df00545 100644 --- a/content/docs/meta.json +++ b/content/docs/meta.json @@ -15,6 +15,7 @@ "head", "server", "vite-plugin", + "mcp", "---Compatibility Layers---", "react-compat", "preact-compat",