diff --git a/templates/assistant-ui/.cursor/rules/echo_rules.mdc b/templates/assistant-ui/.cursor/rules/echo_rules.mdc
new file mode 100644
index 000000000..5bcf2c038
--- /dev/null
+++ b/templates/assistant-ui/.cursor/rules/echo_rules.mdc
@@ -0,0 +1,170 @@
+---
+description: Guidelines and best practices for building Echo Assistant UI applications with @assistant-ui/react, AI SDK v5, and Next.js server/client boundaries
+globs: **/*.ts,**/*.tsx,**/*.js,**/*.jsx
+---
+
+# Echo Assistant UI Guidelines
+
+## Architecture
+
+This is a Next.js application using `@assistant-ui/react` with Vercel AI SDK v5 and Echo as the AI provider router. It provides a full-featured chat UI with streaming support.
+
+### Key Dependencies
+
+- `@assistant-ui/react` for the chat UI framework
+- `@assistant-ui/react-ai-sdk` for AI SDK integration
+- `@assistant-ui/react-markdown` for markdown rendering
+- `@merit-systems/echo-next-sdk` for Echo AI provider integration
+- `ai` (Vercel AI SDK v5) for model interaction
+- `next` for the application framework
+
+## SDK Initialization
+
+### Echo Server-Side Setup
+
+ALWAYS initialize the Echo SDK in `echo.ts` at the project root:
+
+```typescript
+import Echo from '@merit-systems/echo-next-sdk';
+
+const echo = Echo({
+ appId: process.env.NEXT_PUBLIC_ECHO_APP_ID ?? 'ECHO_APP_ID',
+});
+
+export const { getUser, isSignedIn, openai, anthropic, google } = echo;
+export default echo.handlers;
+```
+
+### Echo Route Handler
+
+ALWAYS register Echo authentication handlers at `app/api/echo/[...path]/route.ts`:
+
+```typescript
+import handlers from '@/echo';
+export { handlers as GET, handlers as POST };
+```
+
+## Environment Variables
+
+ALWAYS store your Echo App ID in `.env.local`:
+
+```bash
+NEXT_PUBLIC_ECHO_APP_ID=your_echo_app_id
+```
+
+NEVER hardcode API keys or app IDs directly in your code. ALWAYS use environment variables.
+
+## Chat API Route
+
+The chat API route at `app/api/chat/route.ts` connects Assistant UI to Echo models:
+
+```typescript
+import { openai } from '@/echo';
+import { streamText } from 'ai';
+
+export async function POST(req: Request) {
+ const { messages, model } = await req.json();
+ const result = streamText({
+ model: openai(model),
+ messages,
+ });
+ return result.toDataStreamResponse();
+}
+```
+
+ALWAYS validate the `model` and `messages` parameters before processing.
+
+## Assistant UI Components
+
+### Runtime Provider
+
+Use `@assistant-ui/react-ai-sdk` to connect the AI SDK runtime to Assistant UI:
+
+```typescript
+'use client';
+
+import { useChat } from '@ai-sdk/react';
+import { useVercelUseChatRuntime } from '@assistant-ui/react-ai-sdk';
+import { AssistantRuntimeProvider } from '@assistant-ui/react';
+
+export function ChatProvider({ children }: { children: React.ReactNode }) {
+ const chat = useChat({ api: '/api/chat' });
+ const runtime = useVercelUseChatRuntime(chat);
+ return (
+
+ {children}
+
+ );
+}
+```
+
+### Using Assistant UI Components
+
+Import chat components from `@assistant-ui/react`:
+
+```typescript
+import { Thread } from '@assistant-ui/react';
+
+export function ChatPage() {
+ return ;
+}
+```
+
+NEVER build custom chat UIs from scratch when Assistant UI provides the component. Use the built-in `Thread`, `ThreadList`, `Composer`, and `Message` components.
+
+## Server/Client Boundaries
+
+- Server components: Echo SDK initialization, API routes, data fetching
+- Client components: Assistant UI components, chat interactions, user input
+
+NEVER import `@merit-systems/echo-next-sdk` in a client component. Only use it in server-side code and API routes.
+
+## Project Structure
+
+Follow this structure:
+
+```
+app/
+ api/
+ chat/route.ts # Chat API endpoint
+ echo/[...path]/route.ts # Echo auth handlers
+ layout.tsx
+ page.tsx
+components/ # Client-side UI components
+echo.ts # Server-side Echo initialization
+providers.tsx # Client providers
+lib/ # Shared utilities
+```
+
+## Error Handling
+
+ALWAYS handle errors explicitly in API routes:
+
+```typescript
+try {
+ const result = await someOperation();
+ return result;
+} catch (error) {
+ console.error('Operation failed:', error);
+ return new Response(
+ JSON.stringify({ error: 'Internal server error' }),
+ { status: 500, headers: { 'Content-Type': 'application/json' } }
+ );
+}
+```
+
+## TypeScript Guidelines
+
+- Use strict typing and avoid `any`.
+- Export explicit types for shared data structures.
+- Use `as const` for string literals in discriminated union types.
+
+## Testing
+
+NEVER call external services directly in unit tests. ALWAYS mock the Echo SDK and Assistant UI runtime:
+
+```typescript
+vi.mock('@/echo', () => ({
+ openai: vi.fn(() => mockModel),
+}));
+```
diff --git a/templates/authjs/.cursor/rules/echo_rules.mdc b/templates/authjs/.cursor/rules/echo_rules.mdc
new file mode 100644
index 000000000..e7f8cb4b7
--- /dev/null
+++ b/templates/authjs/.cursor/rules/echo_rules.mdc
@@ -0,0 +1,218 @@
+---
+description: Guidelines and best practices for building Echo applications with Auth.js (NextAuth) integration, including authentication flows, session management, and Echo SDK usage
+globs: **/*.ts,**/*.tsx,**/*.js,**/*.jsx
+---
+
+# Echo Auth.js Guidelines
+
+## Architecture
+
+This is a Next.js application that uses Echo as an Auth.js (NextAuth v5) provider for authentication, combined with the Echo Next SDK for AI functionality. It demonstrates OAuth-based login through Echo.
+
+### Key Dependencies
+
+- `next-auth` (v5 beta) for authentication
+- `@merit-systems/echo-authjs-provider` for the Echo Auth.js provider
+- `@merit-systems/echo-next-sdk` for Echo AI integration
+- `@merit-systems/echo-typescript-sdk` for server-side Echo API calls
+- `ai` (Vercel AI SDK) for model interaction
+- `next` for the application framework
+
+## Authentication Setup
+
+### Auth Configuration
+
+ALWAYS configure Auth.js in `src/auth/index.ts` using the Echo provider:
+
+```typescript
+import NextAuth from 'next-auth';
+import Echo from '@merit-systems/echo-authjs-provider';
+
+export const { handlers, signIn, signOut, auth } = NextAuth({
+ providers: [
+ Echo({
+ appId: process.env.ECHO_APP_ID!,
+ }),
+ ],
+ callbacks: {
+ async jwt({ token, account }) {
+ if (account) {
+ token.accessToken = account.access_token;
+ token.refreshToken = account.refresh_token;
+ }
+ return token;
+ },
+ async session({ session, token }) {
+ session.accessToken = token.accessToken as string;
+ session.refreshToken = token.refreshToken as string;
+ return session;
+ },
+ },
+});
+```
+
+### Auth Route Handler
+
+ALWAYS register the NextAuth route handler at `src/app/api/auth/[...nextauth]/route.ts`:
+
+```typescript
+import { handlers } from '@/auth';
+export const { GET, POST } = handlers;
+```
+
+### Session Type Augmentation
+
+ALWAYS augment the NextAuth types in `src/types/next-auth.d.ts` to include Echo tokens:
+
+```typescript
+declare module 'next-auth' {
+ interface Session {
+ accessToken: string;
+ refreshToken: string;
+ }
+}
+```
+
+## Echo SDK Initialization
+
+### Server-Side Echo Setup
+
+ALWAYS initialize the Echo SDK in `src/echo/index.ts`:
+
+```typescript
+import Echo from '@merit-systems/echo-next-sdk';
+
+export const { handlers, isSignedIn, openai, anthropic } = Echo({
+ appId: process.env.ECHO_APP_ID!,
+});
+```
+
+### Echo Route Handler
+
+ALWAYS register Echo handlers at `src/app/api/echo/[...echo]/route.ts`:
+
+```typescript
+import { handlers } from '@/echo';
+export const { GET, POST } = handlers;
+```
+
+## Environment Variables
+
+ALWAYS store secrets in `.env.local`:
+
+```bash
+ECHO_APP_ID=your_echo_app_id
+AUTH_SECRET=your_nextauth_secret
+```
+
+NEVER hardcode API keys, app IDs, or auth secrets. ALWAYS use environment variables.
+
+Note: `AUTH_SECRET` is required by NextAuth v5 for JWT encryption.
+
+## Authentication Patterns
+
+### Protecting Pages
+
+Use the `auth()` function from your auth config to check sessions:
+
+```typescript
+import { auth } from '@/auth';
+import { redirect } from 'next/navigation';
+
+export default async function DashboardPage() {
+ const session = await auth();
+ if (!session) {
+ redirect('/');
+ }
+ return
Welcome, {session.user?.name}
;
+}
+```
+
+### Sign In / Sign Out
+
+Use the `signIn` and `signOut` server actions:
+
+```typescript
+import { signIn, signOut } from '@/auth';
+
+// In a server action or form
+await signIn('echo');
+await signOut();
+```
+
+## Server/Client Boundaries
+
+- Server components: Authentication checks, Echo SDK calls, data fetching
+- Client components: UI interactions, sign-in buttons, session display
+
+NEVER import `@merit-systems/echo-next-sdk` or access `auth()` in client components. Use server components or API routes for authenticated operations.
+
+## Echo Client for API Calls
+
+Use `@merit-systems/echo-typescript-sdk` for direct Echo API calls on the server:
+
+```typescript
+import { EchoClient } from '@merit-systems/echo-typescript-sdk';
+
+const echoClient = new EchoClient({
+ appId: process.env.ECHO_APP_ID!,
+});
+```
+
+## Project Structure
+
+Follow this structure:
+
+```
+src/
+ app/
+ api/
+ auth/[...nextauth]/route.ts # NextAuth handlers
+ echo/[...echo]/route.ts # Echo handlers
+ dashboard/page.tsx # Protected page
+ layout.tsx
+ page.tsx
+ auth/
+ index.ts # NextAuth configuration
+ echo/
+ index.ts # Echo SDK initialization
+ lib/
+ echo-client.ts # Echo TypeScript SDK client
+ types/
+ next-auth.d.ts # Type augmentation
+```
+
+## Error Handling
+
+ALWAYS handle authentication errors gracefully:
+
+```typescript
+try {
+ const session = await auth();
+ if (!session) {
+ return new Response('Unauthorized', { status: 401 });
+ }
+ // proceed with authenticated logic
+} catch (error) {
+ console.error('Auth error:', error);
+ return new Response('Internal server error', { status: 500 });
+}
+```
+
+## TypeScript Guidelines
+
+- Use strict typing and avoid `any`.
+- ALWAYS augment NextAuth types when adding custom session fields.
+- Export explicit types for shared data structures.
+
+## Testing
+
+NEVER call external auth services in tests. ALWAYS mock NextAuth and the Echo SDK:
+
+```typescript
+vi.mock('@/auth', () => ({
+ auth: vi.fn(() => Promise.resolve({ user: { name: 'Test' } })),
+ signIn: vi.fn(),
+ signOut: vi.fn(),
+}));
+```
diff --git a/templates/echo-cli/.cursor/rules/echo_rules.mdc b/templates/echo-cli/.cursor/rules/echo_rules.mdc
new file mode 100644
index 000000000..845646aed
--- /dev/null
+++ b/templates/echo-cli/.cursor/rules/echo_rules.mdc
@@ -0,0 +1,171 @@
+---
+description: Guidelines and best practices for building the Echo CLI application, including command structure, authentication, wallet integration, and TypeScript patterns
+globs: **/*.ts,**/*.js
+---
+
+# Echo CLI Guidelines
+
+## Architecture
+
+This is a Node.js CLI application built with Commander.js and the Echo TypeScript SDK. It provides a terminal-based chat agent with wallet-based authentication.
+
+### Key Dependencies
+
+- `commander` for CLI command parsing
+- `@clack/prompts` for interactive terminal prompts
+- `@merit-systems/echo-typescript-sdk` for Echo API integration
+- `@merit-systems/ai-x402` for AI payment integration
+
+## Project Structure
+
+Follow this structure:
+
+```
+src/
+ index.ts # CLI entry point and command registration
+ constants.ts # Shared constants (ASCII art, auth options)
+ print.ts # Output formatting utilities
+ auth/ # Authentication modules
+ client.ts # Echo client setup
+ login.ts # Login flows
+ logout.ts # Logout handling
+ wallet.ts # Wallet authentication
+ local-wallet.ts # Local wallet management
+ providers.ts # Auth provider configuration
+ config/ # Configuration management
+ index.ts # Config entry point
+ store.ts # Persistent storage
+ models.ts # Model configuration
+ wallet.ts # Wallet config
+ core/ # Core functionality
+ chat.ts # Chat session management
+ history.ts # Conversation history
+ model.ts # Model selection
+ profile.ts # User profile
+ utils/ # Shared utilities
+ auth.ts # Auth helpers
+ errors.ts # Error handling
+ spinner.ts # Loading indicators
+ stream.ts # Stream processing
+ wallet.ts # Wallet utilities
+ validation/ # Input validation
+ schemas.ts # Validation schemas
+ validator.ts # Validation logic
+```
+
+## Command Registration
+
+ALWAYS register commands using Commander.js in `src/index.ts`:
+
+```typescript
+import { Command } from 'commander';
+
+const program = new Command();
+
+program
+ .name('echodex')
+ .description('CLI Coding Agent Powered by Echo')
+ .version('1.0.0');
+
+program
+ .command('login')
+ .description('Authenticate with Echo or Wallet')
+ .action(async () => {
+ // handler
+ });
+```
+
+ALWAYS call `process.exit()` with appropriate codes at the end of each command action.
+
+## Authentication
+
+### Authentication Methods
+
+The CLI supports multiple authentication methods:
+- Echo OAuth login
+- External wallet connection
+- Local wallet generation
+
+ALWAYS check authentication state before executing protected commands:
+
+```typescript
+import { isAuthenticated } from '@/utils';
+
+const authenticated = await isAuthenticated();
+if (!authenticated) {
+ program.help();
+ process.exit(0);
+}
+```
+
+### Wallet Security
+
+NEVER log or display private keys unless the user explicitly requests it (e.g., `export-private-key` command).
+
+ALWAYS warn users when performing sensitive wallet operations.
+
+## Interactive Prompts
+
+Use `@clack/prompts` for all user interactions:
+
+```typescript
+import { select, isCancel } from '@clack/prompts';
+
+const choice = await select({
+ message: 'Choose an option:',
+ options: [
+ { value: 'a', label: 'Option A' },
+ { value: 'b', label: 'Option B' },
+ ],
+});
+
+if (isCancel(choice)) {
+ warning('Operation cancelled');
+ process.exit(1);
+}
+```
+
+ALWAYS handle cancellation by checking `isCancel()` on prompt results.
+
+## Path Aliases
+
+This project uses TypeScript path aliases. ALWAYS use `@/` imports:
+
+```typescript
+// CORRECT
+import { isAuthenticated } from '@/utils';
+import { ECHODEX_ASCII_ART } from '@/constants';
+
+// INCORRECT
+import { isAuthenticated } from '../../utils';
+```
+
+## Error Handling
+
+ALWAYS handle errors explicitly and provide user-friendly output:
+
+```typescript
+try {
+ const result = await someOperation();
+ return result;
+} catch (error) {
+ console.error('Operation failed:', error);
+ process.exit(1);
+}
+```
+
+Use the `print.ts` utilities for consistent output formatting:
+- `info()` for informational messages
+- `warning()` for warnings
+- `header()` for section headers
+
+## TypeScript Guidelines
+
+- Use strict typing and avoid `any`.
+- Export explicit types for shared data structures.
+- Use `as const` for string literals and enum-like objects.
+- ALWAYS add `@types/node` to devDependencies.
+
+## Testing
+
+NEVER call external services directly in tests. ALWAYS mock the Echo SDK and wallet providers.
diff --git a/templates/next-chat/.cursor/rules/echo_rules.mdc b/templates/next-chat/.cursor/rules/echo_rules.mdc
new file mode 100644
index 000000000..e62f51f61
--- /dev/null
+++ b/templates/next-chat/.cursor/rules/echo_rules.mdc
@@ -0,0 +1,198 @@
+---
+description: Guidelines and best practices for building Echo Next.js chat applications, including SDK initialization, streaming chat, server/client boundaries, and UI component patterns
+globs: **/*.ts,**/*.tsx,**/*.js,**/*.jsx
+---
+
+# Echo Next.js Chat Guidelines
+
+## Architecture
+
+This is a full-featured Next.js chat application using the Echo SDK for AI billing, authentication, and model routing. It includes streaming chat, user management, and a rich set of AI UI elements.
+
+### Key Dependencies
+
+- `@merit-systems/echo-next-sdk` for server-side Echo integration
+- `@merit-systems/echo-react-sdk` for client-side Echo components
+- `@ai-sdk/react` for React hooks (useChat)
+- `ai` (Vercel AI SDK v5) for streaming and model interaction
+- `next` for the application framework
+- Radix UI components for the UI layer
+
+## SDK Initialization
+
+### Server-Side Echo Setup
+
+ALWAYS initialize the Echo SDK in `src/echo/index.ts`:
+
+```typescript
+import Echo from '@merit-systems/echo-next-sdk';
+
+export const { handlers, isSignedIn, openai, anthropic } = Echo({
+ appId: process.env.ECHO_APP_ID!,
+});
+```
+
+### Client-Side Provider
+
+ALWAYS wrap the application with `EchoProvider` in `src/providers.tsx`:
+
+```typescript
+'use client';
+
+import { EchoProvider } from '@merit-systems/echo-react-sdk';
+
+export function Providers({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
+```
+
+## Environment Variables
+
+ALWAYS store your Echo App ID in `.env.local`:
+
+```bash
+ECHO_APP_ID=your_echo_app_id
+NEXT_PUBLIC_ECHO_APP_ID=your_echo_app_id
+```
+
+NEVER hardcode API keys or app IDs. ALWAYS use environment variables.
+
+## Streaming Chat API
+
+### Chat API Route
+
+Use the Vercel AI SDK with Echo model providers for streaming responses:
+
+```typescript
+import { openai } from '@/echo';
+import { streamText, convertToModelMessages, type UIMessage } from 'ai';
+
+export const maxDuration = 30;
+
+export async function POST(req: Request) {
+ const { messages, model }: { messages: UIMessage[]; model: string } = await req.json();
+
+ if (!model || !messages || !Array.isArray(messages)) {
+ return new Response(JSON.stringify({ error: 'Bad Request' }), { status: 400 });
+ }
+
+ const result = streamText({
+ model: openai(model),
+ messages: convertToModelMessages(messages),
+ });
+
+ return result.toUIMessageStreamResponse();
+}
+```
+
+### Client-Side Chat Hook
+
+Use `useChat` from `@ai-sdk/react` for client-side chat state management:
+
+```typescript
+'use client';
+
+import { useChat } from '@ai-sdk/react';
+
+export function Chat() {
+ const { messages, input, handleInputChange, handleSubmit } = useChat({
+ api: '/api/chat',
+ });
+ // render chat UI
+}
+```
+
+## AI UI Elements
+
+This template includes reusable AI UI components in `src/components/ai-elements/`:
+
+- `conversation.tsx` - Chat conversation container
+- `prompt-input.tsx` - User input with model selection
+- `response.tsx` - AI response rendering
+- `code-block.tsx` - Syntax-highlighted code blocks
+- `sources.tsx` - Source citation display
+- `suggestion.tsx` - Suggested prompts
+- `task.tsx` - Task/tool execution display
+- `image.tsx` - Image generation display
+
+ALWAYS use these existing components rather than building custom equivalents.
+
+## Echo UI Components
+
+Use the shared Echo UI components in `src/components/`:
+
+- `echo-button.tsx` - Echo sign-in button
+- `echo-popover.tsx` - Account popover menu
+- `echo-account-next.tsx` - Account management
+- `balance.tsx` - Token balance display
+- `money-input.tsx` - Currency input for top-ups
+
+## Server/Client Boundaries
+
+- Server components: Echo SDK initialization, API routes, authentication checks
+- Client components: Chat UI, Echo provider, interactive elements
+
+NEVER import `@merit-systems/echo-next-sdk` in client components. Use `@merit-systems/echo-react-sdk` for client-side Echo features.
+
+## Project Structure
+
+Follow this structure:
+
+```
+src/
+ app/
+ api/
+ echo/[...echo]/route.ts # Echo auth handlers
+ chat/route.ts # Streaming chat endpoint
+ layout.tsx
+ page.tsx
+ components/
+ ai-elements/ # Chat UI components
+ echo-button.tsx # Echo integration components
+ echo-popover.tsx
+ balance.tsx
+ echo/
+ index.ts # Server-side Echo initialization
+ lib/
+ utils.ts # Shared utilities
+ currency-utils.ts # Currency formatting
+ providers.tsx # Client providers
+```
+
+## Error Handling
+
+ALWAYS handle errors explicitly in API routes and provide meaningful HTTP status codes:
+
+```typescript
+try {
+ const result = await someOperation();
+ return result;
+} catch (error) {
+ console.error('Operation failed:', error);
+ return new Response(
+ JSON.stringify({ error: 'Internal server error' }),
+ { status: 500, headers: { 'Content-Type': 'application/json' } }
+ );
+}
+```
+
+## TypeScript Guidelines
+
+- Use strict typing and avoid `any`.
+- Export explicit types for shared data structures.
+- Use `as const` for string literals in discriminated union types.
+- Type chat messages using `UIMessage` from the `ai` package.
+
+## Testing
+
+NEVER call external services in unit tests. ALWAYS mock the Echo SDK:
+
+```typescript
+vi.mock('@/echo', () => ({
+ openai: vi.fn(() => mockModel),
+}));
+```
diff --git a/templates/next-image/.cursor/rules/echo_rules.mdc b/templates/next-image/.cursor/rules/echo_rules.mdc
new file mode 100644
index 000000000..1328ecc38
--- /dev/null
+++ b/templates/next-image/.cursor/rules/echo_rules.mdc
@@ -0,0 +1,151 @@
+---
+description: Guidelines and best practices for building Echo Next.js image generation applications, including SDK initialization, image API integration, server/client boundaries, and UI patterns
+globs: **/*.ts,**/*.tsx,**/*.js,**/*.jsx
+---
+
+# Echo Next.js Image Generation Guidelines
+
+## Architecture
+
+This is a Next.js application for AI-powered image generation using the Echo SDK. It provides image generation through Echo's model routing with automatic billing and user management.
+
+### Key Dependencies
+
+- `@merit-systems/echo-next-sdk` for server-side Echo integration
+- `@merit-systems/echo-react-sdk` for client-side Echo components
+- `ai` (Vercel AI SDK) for model interaction
+- `openai` for image generation API calls
+- `next` for the application framework
+- Radix UI components for the UI layer
+
+## SDK Initialization
+
+### Server-Side Echo Setup
+
+ALWAYS initialize the Echo SDK in `src/echo/index.ts`:
+
+```typescript
+import Echo from '@merit-systems/echo-next-sdk';
+
+export const { handlers, isSignedIn, openai, anthropic } = Echo({
+ appId: process.env.ECHO_APP_ID!,
+});
+```
+
+## Environment Variables
+
+ALWAYS store your Echo App ID in `.env.local`:
+
+```bash
+ECHO_APP_ID=your_echo_app_id
+NEXT_PUBLIC_ECHO_APP_ID=your_echo_app_id
+```
+
+NEVER hardcode API keys or app IDs. ALWAYS use environment variables.
+
+## Image Generation
+
+### Server Actions
+
+Use Next.js server actions in `src/lib/image-actions.ts` for image generation:
+
+```typescript
+'use server';
+
+import { openai } from '@/echo';
+
+export async function generateImage(prompt: string, model: string) {
+ // Generate image using Echo-proxied OpenAI
+ const response = await openai.images.generate({
+ model,
+ prompt,
+ });
+ return response.data;
+}
+```
+
+ALWAYS use server actions or API routes for image generation. NEVER call the OpenAI API directly from client components.
+
+### Image Utilities
+
+Keep image processing utilities in `src/lib/image-utils.ts` and type definitions in `src/lib/types.ts`.
+
+Keep model and size constants in `src/lib/constants.ts`.
+
+## Echo UI Components
+
+Use the shared Echo UI components in `src/components/`:
+
+- `echo-button.tsx` - Echo sign-in button
+- `echo-popover.tsx` - Account popover menu
+- `echo-account-next.tsx` - Account management
+- `echo-tokens.tsx` - Token display
+- `balance.tsx` - Token balance display
+- `signin.tsx` - Sign-in page component
+- `image-details-dialog.tsx` - Image detail view
+
+## Server/Client Boundaries
+
+- Server components: Echo SDK initialization, image generation actions, authentication
+- Client components: Image display, user input, Echo provider components
+
+NEVER import `@merit-systems/echo-next-sdk` in client components. Use `@merit-systems/echo-react-sdk` for client-side Echo features.
+
+## Project Structure
+
+Follow this structure:
+
+```
+src/
+ app/
+ api/
+ echo/[...echo]/route.ts # Echo auth handlers
+ layout.tsx
+ page.tsx
+ components/
+ ui/ # Reusable UI primitives
+ echo-button.tsx # Echo integration components
+ echo-tokens.tsx
+ image-details-dialog.tsx # Image-specific components
+ ai-elements/
+ prompt-input.tsx # Image prompt input
+ echo/
+ index.ts # Server-side Echo initialization
+ lib/
+ types.ts # Image type definitions
+ constants.ts # Model and size constants
+ image-actions.ts # Server actions for generation
+ image-utils.ts # Image processing utilities
+ utils.ts # Shared utilities
+ currency-utils.ts # Currency formatting
+```
+
+## Error Handling
+
+ALWAYS handle image generation errors and provide user feedback:
+
+```typescript
+try {
+ const result = await generateImage(prompt, model);
+ return result;
+} catch (error) {
+ console.error('Image generation failed:', error);
+ // Return user-friendly error
+}
+```
+
+## TypeScript Guidelines
+
+- Use strict typing and avoid `any`.
+- Define image-related types in `src/lib/types.ts`.
+- Export explicit types for shared data structures.
+
+## Testing
+
+NEVER call external services in unit tests. ALWAYS mock the Echo SDK and image generation:
+
+```typescript
+vi.mock('@/echo', () => ({
+ openai: { images: { generate: vi.fn() } },
+}));
+```
diff --git a/templates/next-video-template/.cursor/rules/echo_rules.mdc b/templates/next-video-template/.cursor/rules/echo_rules.mdc
new file mode 100644
index 000000000..686fc25e9
--- /dev/null
+++ b/templates/next-video-template/.cursor/rules/echo_rules.mdc
@@ -0,0 +1,161 @@
+---
+description: Guidelines and best practices for building Echo Next.js video generation applications, including SDK initialization, video API integration, Google GenAI usage, and UI patterns
+globs: **/*.ts,**/*.tsx,**/*.js,**/*.jsx
+---
+
+# Echo Next.js Video Generation Guidelines
+
+## Architecture
+
+This is a Next.js application for AI-powered video generation using the Echo SDK. It integrates with Google GenAI for video generation, uses React Query for async state management, and provides automatic billing through Echo.
+
+### Key Dependencies
+
+- `@merit-systems/echo-next-sdk` for server-side Echo integration
+- `@merit-systems/echo-react-sdk` for client-side Echo components
+- `@google/genai` for Google AI video generation
+- `@tanstack/react-query` for async state management
+- `ai` (Vercel AI SDK) for model interaction
+- `next` for the application framework
+- Radix UI components for the UI layer
+
+## SDK Initialization
+
+### Server-Side Echo Setup
+
+ALWAYS initialize the Echo SDK in `src/echo/index.ts`:
+
+```typescript
+import Echo from '@merit-systems/echo-next-sdk';
+
+export const { handlers, isSignedIn, openai, anthropic } = Echo({
+ appId: process.env.ECHO_APP_ID!,
+});
+```
+
+## Environment Variables
+
+ALWAYS store your Echo App ID in `.env.local`:
+
+```bash
+ECHO_APP_ID=your_echo_app_id
+NEXT_PUBLIC_ECHO_APP_ID=your_echo_app_id
+```
+
+NEVER hardcode API keys or app IDs. ALWAYS use environment variables.
+
+## Video Generation
+
+### API Layer
+
+Keep video API calls in `src/lib/api/video-api.ts`. Use server actions or API routes for all generation requests.
+
+ALWAYS use server-side code for video generation API calls. NEVER expose API keys to the client.
+
+### Video Operations
+
+Keep video processing logic in `src/lib/video-operations.ts` and history management in `src/lib/video-history.ts`.
+
+### Custom Hooks
+
+Use the custom hooks in `src/lib/hooks/` for video-related state management:
+
+- `useVideoGeneration.ts` - Video generation state and actions
+- `useVideoHistory.ts` - Video history management
+- `useVideoOperations.ts` - Video processing operations
+
+ALWAYS use React Query (`@tanstack/react-query`) for async state management in video operations.
+
+### Types and Constants
+
+Define video-related types in `src/lib/types.ts` and constants (models, sizes, durations) in `src/lib/constants.ts`.
+
+## Echo UI Components
+
+Use the shared Echo UI components in `src/components/`:
+
+- `echo-button.tsx` - Echo sign-in button
+- `echo-popover.tsx` - Account popover menu
+- `echo-account-next.tsx` - Account management
+- `signin.tsx` - Sign-in page component
+- `video-history.tsx` - Video generation history
+- `video-details-dialog.tsx` - Video detail view
+- `image-details-dialog.tsx` - Image detail view (for thumbnails)
+
+## Server/Client Boundaries
+
+- Server components: Echo SDK initialization, video generation API calls, authentication
+- Client components: Video display, generation UI, Echo provider, React Query
+
+NEVER import `@merit-systems/echo-next-sdk` in client components. Use `@merit-systems/echo-react-sdk` for client-side Echo features.
+
+## Project Structure
+
+Follow this structure:
+
+```
+src/
+ app/
+ api/
+ echo/[...echo]/route.ts # Echo auth handlers
+ layout.tsx
+ page.tsx
+ components/
+ ui/ # Reusable UI primitives
+ echo-button.tsx # Echo integration components
+ video-history.tsx # Video-specific components
+ video-details-dialog.tsx
+ ai-elements/
+ prompt-input.tsx # Generation prompt input
+ echo/
+ index.ts # Server-side Echo initialization
+ lib/
+ api/
+ video-api.ts # Video generation API
+ hooks/
+ useVideoGeneration.ts # Video generation hook
+ useVideoHistory.ts # History management hook
+ useVideoOperations.ts # Video operations hook
+ types.ts # Type definitions
+ constants.ts # Model and config constants
+ video-operations.ts # Video processing
+ video-history.ts # History storage
+ image-actions.ts # Image generation actions
+ utils.ts # Shared utilities
+ currency-utils.ts # Currency formatting
+```
+
+## Error Handling
+
+ALWAYS handle video generation errors and provide user feedback:
+
+```typescript
+try {
+ const result = await generateVideo(prompt, model);
+ return result;
+} catch (error) {
+ console.error('Video generation failed:', error);
+ // Return user-friendly error
+}
+```
+
+## TypeScript Guidelines
+
+- Use strict typing and avoid `any`.
+- Define video-related types in `src/lib/types.ts`.
+- Export explicit types for shared data structures.
+- Use `as const` for string literals in discriminated union types.
+
+## Testing
+
+NEVER call external services in unit tests. ALWAYS mock the Echo SDK and video generation APIs:
+
+```typescript
+vi.mock('@/echo', () => ({
+ openai: vi.fn(() => mockModel),
+}));
+
+vi.mock('@google/genai', () => ({
+ // mock implementation
+}));
+```
diff --git a/templates/next/.cursor/rules/echo_rules.mdc b/templates/next/.cursor/rules/echo_rules.mdc
new file mode 100644
index 000000000..b896b19b6
--- /dev/null
+++ b/templates/next/.cursor/rules/echo_rules.mdc
@@ -0,0 +1,177 @@
+---
+description: Guidelines and best practices for building Echo Next.js applications, including SDK initialization, server/client boundaries, environment variables, and API routes
+globs: **/*.ts,**/*.tsx,**/*.js,**/*.jsx
+---
+
+# Echo Next.js Guidelines
+
+## SDK Initialization
+
+### Server-Side Initialization
+
+ALWAYS initialize the Echo SDK in `src/echo/index.ts` for server-side usage:
+
+```typescript
+import Echo from '@merit-systems/echo-next-sdk';
+
+export const { handlers, isSignedIn, openai, anthropic } = Echo({
+ appId: process.env.ECHO_APP_ID!,
+});
+```
+
+### Client-Side Provider
+
+ALWAYS wrap your application with `EchoProvider` in your providers file:
+
+```typescript
+'use client';
+
+import { EchoProvider } from '@merit-systems/echo-next-sdk/client';
+
+export function Providers({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
+```
+
+## Environment Variables
+
+ALWAYS store your Echo App ID in `.env.local`:
+
+```bash
+# Server-side only
+ECHO_APP_ID=your_echo_app_id
+
+# Client-side (public)
+NEXT_PUBLIC_ECHO_APP_ID=your_echo_app_id
+```
+
+NEVER hardcode API keys or app IDs directly in your code. ALWAYS use environment variables.
+
+## Server/Client Boundaries
+
+### Server Components
+
+ALWAYS use server components for Echo AI calls that require authentication:
+
+```typescript
+import { openai } from '@/echo';
+import { generateText } from 'ai';
+
+export default async function Page() {
+ const { text } = await generateText({
+ model: openai('gpt-4o'),
+ prompt: 'Hello, world!',
+ });
+ return {text}
;
+}
+```
+
+### Client Components
+
+Use client components ONLY for UI interactions. NEVER make direct AI calls from client components with server secrets:
+
+```typescript
+// CORRECT - Client component uses Echo UI components
+'use client';
+
+import { EchoTokens } from '@merit-systems/echo-next-sdk/client';
+
+export function EchoButton() {
+ return ;
+}
+```
+
+NEVER import `@merit-systems/echo-next-sdk` (server SDK) in a client component. Only use `@merit-systems/echo-next-sdk/client` on the client side.
+
+## API Routes
+
+### Echo Authentication Handler
+
+ALWAYS register Echo authentication handlers at `app/api/echo/[...echo]/route.ts`:
+
+```typescript
+import { handlers } from '@/echo';
+export const { GET, POST } = handlers;
+```
+
+### Custom API Routes with AI
+
+Use the Vercel AI SDK (`ai` package) with Echo model providers for streaming:
+
+```typescript
+import { openai } from '@/echo';
+import { streamText, convertToModelMessages, type UIMessage } from 'ai';
+
+export const maxDuration = 30;
+
+export async function POST(req: Request) {
+ const { messages, model }: { messages: UIMessage[]; model: string } = await req.json();
+
+ if (!model || !messages || !Array.isArray(messages)) {
+ return new Response(JSON.stringify({ error: 'Bad Request' }), { status: 400 });
+ }
+
+ const result = streamText({
+ model: openai(model),
+ messages: convertToModelMessages(messages),
+ });
+
+ return result.toUIMessageStreamResponse();
+}
+```
+
+## Error Handling
+
+ALWAYS handle errors explicitly in API routes and provide meaningful HTTP status codes:
+
+```typescript
+try {
+ const result = await someOperation();
+ return result;
+} catch (error) {
+ console.error('Operation failed:', error);
+ return new Response(
+ JSON.stringify({ error: 'Internal server error', message: 'Failed to process request' }),
+ { status: 500, headers: { 'Content-Type': 'application/json' } }
+ );
+}
+```
+
+## Project Structure
+
+Follow this structure for Echo Next.js projects:
+
+```
+src/
+ app/
+ api/
+ echo/[...echo]/route.ts # Echo auth handlers
+ chat/route.ts # Custom API routes
+ layout.tsx
+ page.tsx
+ components/ # Client-side components
+ echo/
+ index.ts # Server-side Echo initialization
+ lib/ # Shared utilities and types
+ providers.tsx # Client providers including EchoProvider
+```
+
+## TypeScript Guidelines
+
+- Use strict typing and avoid `any`.
+- Export explicit types for shared data structures.
+- Use `as const` for string literals in discriminated union types.
+
+## Testing
+
+NEVER call external services directly in unit tests. ALWAYS mock the Echo SDK:
+
+```typescript
+vi.mock('@/echo', () => ({
+ openai: vi.fn(() => mockModel),
+}));
+```
diff --git a/templates/nextjs-api-key-template/.cursor/rules/echo_rules.mdc b/templates/nextjs-api-key-template/.cursor/rules/echo_rules.mdc
new file mode 100644
index 000000000..5d53a71cd
--- /dev/null
+++ b/templates/nextjs-api-key-template/.cursor/rules/echo_rules.mdc
@@ -0,0 +1,210 @@
+---
+description: Guidelines and best practices for building Echo Next.js applications with API key management, Prisma database integration, and server-side authentication
+globs: **/*.ts,**/*.tsx,**/*.js,**/*.jsx,**/*.prisma
+---
+
+# Echo Next.js API Key Template Guidelines
+
+## Architecture
+
+This is a Next.js application demonstrating server-side API key management with Echo. It uses Prisma with PostgreSQL for database storage, Echo for AI billing and authentication, and provides a full-featured chat interface.
+
+### Key Dependencies
+
+- `@merit-systems/echo-next-sdk` for server-side Echo integration
+- `@merit-systems/echo-react-sdk` for client-side Echo components
+- `@merit-systems/echo-typescript-sdk` for direct Echo API calls
+- `@prisma/client` for database access
+- `ai` (Vercel AI SDK v5) for streaming and model interaction
+- `next` for the application framework
+- Docker for local PostgreSQL database
+
+## SDK Initialization
+
+### Server-Side Echo Setup
+
+ALWAYS initialize the Echo SDK in `src/echo/index.ts`:
+
+```typescript
+import Echo from '@merit-systems/echo-next-sdk';
+
+export const { handlers, isSignedIn, openai, anthropic } = Echo({
+ appId: process.env.ECHO_APP_ID!,
+});
+```
+
+### Client-Side Provider
+
+ALWAYS wrap the application with `EchoProvider` in `src/providers.tsx`:
+
+```typescript
+'use client';
+
+import { EchoProvider } from '@merit-systems/echo-react-sdk';
+
+export function Providers({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
+```
+
+## Environment Variables
+
+ALWAYS store secrets in `.env.local`:
+
+```bash
+ECHO_APP_ID=your_echo_app_id
+NEXT_PUBLIC_ECHO_APP_ID=your_echo_app_id
+DATABASE_URL=postgresql://user:password@localhost:5432/echo
+```
+
+NEVER hardcode API keys, app IDs, or database URLs. ALWAYS use environment variables.
+
+## Database (Prisma)
+
+### Schema
+
+The Prisma schema is defined in `prisma/schema.prisma` with PostgreSQL:
+
+```prisma
+generator client {
+ provider = "prisma-client-js"
+ output = "../src/generated/prisma"
+ binaryTargets = ["native", "rhel-openssl-3.0.x"]
+}
+
+datasource db {
+ provider = "postgresql"
+ url = env("DATABASE_URL")
+}
+```
+
+### Prisma Client
+
+ALWAYS use the singleton pattern for the Prisma client in `src/lib/db.ts`:
+
+```typescript
+import { PrismaClient } from '@/generated/prisma';
+
+const globalForPrisma = globalThis as unknown as { prisma: PrismaClient };
+
+export const prisma = globalForPrisma.prisma || new PrismaClient();
+
+if (process.env.NODE_ENV !== 'production') globalForPrisma.prisma = prisma;
+```
+
+### Database Commands
+
+- `prisma generate` - Generate the Prisma client
+- `prisma migrate dev` - Create and apply migrations in development
+- `prisma migrate deploy` - Apply migrations in production
+- `prisma studio` - Open the database browser
+
+ALWAYS run `prisma generate` after schema changes. The generated client outputs to `src/generated/prisma`.
+
+### Local Development
+
+The project uses Docker for local PostgreSQL. Run `docker-compose -f docker-local-db.yml up -d` to start the database.
+
+## API Key Management
+
+- Store API keys in the database, associated with user records.
+- NEVER expose API keys in client-side code or responses.
+- ALWAYS validate API keys on the server side before processing requests.
+- Use proper hashing when storing sensitive keys.
+
+## Streaming Chat
+
+Use the Vercel AI SDK with Echo for streaming chat:
+
+```typescript
+import { openai } from '@/echo';
+import { streamText, convertToModelMessages, type UIMessage } from 'ai';
+
+export async function POST(req: Request) {
+ const { messages, model }: { messages: UIMessage[]; model: string } = await req.json();
+ const result = streamText({
+ model: openai(model),
+ messages: convertToModelMessages(messages),
+ });
+ return result.toUIMessageStreamResponse();
+}
+```
+
+## Server/Client Boundaries
+
+- Server components: Echo SDK, Prisma queries, API key validation, authentication
+- Client components: Chat UI, Echo provider, interactive elements
+
+NEVER import `@merit-systems/echo-next-sdk` or `@prisma/client` in client components. NEVER expose database queries or API keys to the client.
+
+## Project Structure
+
+Follow this structure:
+
+```
+prisma/
+ schema.prisma # Database schema
+ migrations/ # Database migrations
+src/
+ generated/
+ prisma/ # Generated Prisma client
+ app/
+ api/
+ echo/[...echo]/route.ts # Echo auth handlers
+ chat/route.ts # Streaming chat endpoint
+ layout.tsx
+ page.tsx
+ components/
+ ai-elements/ # Chat UI components
+ echo-button.tsx # Echo integration components
+ echo/
+ index.ts # Server-side Echo initialization
+ lib/
+ db.ts # Prisma client singleton
+ utils.ts # Shared utilities
+ providers.tsx # Client providers
+```
+
+## Error Handling
+
+ALWAYS handle errors explicitly and provide meaningful HTTP status codes:
+
+```typescript
+try {
+ const result = await prisma.user.findUnique({ where: { apiKey } });
+ if (!result) {
+ return new Response(JSON.stringify({ error: 'Invalid API key' }), { status: 401 });
+ }
+ // proceed
+} catch (error) {
+ console.error('Database error:', error);
+ return new Response(
+ JSON.stringify({ error: 'Internal server error' }),
+ { status: 500, headers: { 'Content-Type': 'application/json' } }
+ );
+}
+```
+
+## TypeScript Guidelines
+
+- Use strict typing and avoid `any`.
+- Use Prisma-generated types for database models.
+- Export explicit types for shared data structures.
+
+## Testing
+
+NEVER call external services or the real database in unit tests. ALWAYS mock Prisma and the Echo SDK:
+
+```typescript
+vi.mock('@/lib/db', () => ({
+ prisma: { user: { findUnique: vi.fn(), create: vi.fn() } },
+}));
+
+vi.mock('@/echo', () => ({
+ openai: vi.fn(() => mockModel),
+}));
+```
diff --git a/templates/react-chat/.cursor/rules/echo_rules.mdc b/templates/react-chat/.cursor/rules/echo_rules.mdc
new file mode 100644
index 000000000..236666262
--- /dev/null
+++ b/templates/react-chat/.cursor/rules/echo_rules.mdc
@@ -0,0 +1,178 @@
+---
+description: Guidelines and best practices for building Echo React chat applications with Vite, including SDK initialization, chat UI patterns, environment variables, and component architecture
+globs: **/*.ts,**/*.tsx,**/*.js,**/*.jsx
+---
+
+# Echo React Chat (Vite) Guidelines
+
+## Architecture
+
+This is a client-side React chat application built with Vite and the Echo React SDK. It provides a streaming chat interface with AI billing and user management through Echo.
+
+### Key Dependencies
+
+- `@merit-systems/echo-react-sdk` for Echo integration (provider, auth, UI)
+- `@ai-sdk/react` for React chat hooks (useChat)
+- `ai` (Vercel AI SDK v5) for streaming and model interaction
+- `react` and `react-dom` for the UI framework
+- `vite` for the build tool
+- Radix UI components for the UI layer
+
+## SDK Initialization
+
+### EchoProvider Setup
+
+ALWAYS wrap your application with `EchoProvider` at the root level in `src/main.tsx`:
+
+```typescript
+import { StrictMode } from 'react';
+import { createRoot } from 'react-dom/client';
+import { EchoProvider } from '@merit-systems/echo-react-sdk';
+import App from './App.tsx';
+
+createRoot(document.getElementById('root')!).render(
+
+
+
+
+
+);
+```
+
+## Environment Variables
+
+ALWAYS store your Echo App ID in `.env`:
+
+```bash
+VITE_ECHO_APP_ID=your_echo_app_id
+```
+
+NEVER hardcode API keys or app IDs. ALWAYS use `import.meta.env.VITE_*` environment variables.
+
+Note: Vite only exposes variables prefixed with `VITE_` to client code. NEVER store server secrets in `VITE_` prefixed variables as they are bundled into the client.
+
+## Chat Implementation
+
+### Chat Component
+
+Use `useChat` from `@ai-sdk/react` for chat state management:
+
+```typescript
+import { useChat } from '@ai-sdk/react';
+
+export function Chat() {
+ const { messages, input, handleInputChange, handleSubmit } = useChat({
+ api: '/api/chat',
+ });
+ // render chat UI
+}
+```
+
+### AI UI Elements
+
+This template includes reusable AI UI components in `src/components/ai-elements/`:
+
+- `conversation.tsx` - Chat conversation container
+- `prompt-input.tsx` - User input with model selection
+- `response.tsx` - AI response rendering
+- `code-block.tsx` - Syntax-highlighted code blocks
+- `sources.tsx` - Source citation display
+- `suggestion.tsx` - Suggested prompts
+- `task.tsx` - Task/tool execution display
+- `image.tsx` - Image generation display
+
+ALWAYS use these existing components rather than building custom equivalents.
+
+## Client-Side Architecture
+
+This is entirely a client-side application. All Echo interactions happen through the React SDK:
+
+- Use `@merit-systems/echo-react-sdk` for all Echo functionality.
+- The `EchoProvider` manages authentication state and token management.
+- Use Echo UI components for user-facing Echo features.
+
+NEVER attempt to use `@merit-systems/echo-next-sdk` in this project. That package is exclusively for Next.js server-side usage.
+
+## Echo UI Components
+
+Use the shared Echo UI components in `src/components/`:
+
+- `echo-button.tsx` - Echo sign-in button
+- `echo-popover.tsx` - Account popover menu
+- `balance.tsx` - Token balance display
+- `money-input.tsx` - Currency input for top-ups
+- `logo.tsx` - Echo logo component
+
+## Component Patterns
+
+### Separation of Concerns
+
+- Keep Echo provider setup in `src/main.tsx`.
+- Keep the main chat logic in `src/chat.tsx`.
+- Keep the app header/navigation in `src/header.tsx`.
+- Keep Echo-specific components in `src/components/`.
+- Keep AI chat UI elements in `src/components/ai-elements/`.
+
+## Project Structure
+
+Follow this structure:
+
+```
+src/
+ main.tsx # Entry point with EchoProvider
+ App.tsx # Root component
+ chat.tsx # Chat implementation
+ header.tsx # App header/navigation
+ components/
+ ai-elements/ # Chat UI components
+ echo-button.tsx # Echo integration components
+ echo-popover.tsx
+ balance.tsx
+ lib/
+ utils.ts # Shared utilities
+ currency-utils.ts # Currency formatting
+```
+
+## Error Handling
+
+ALWAYS handle errors explicitly and provide meaningful feedback:
+
+```typescript
+try {
+ const result = await someOperation();
+ return result;
+} catch (error) {
+ console.error('Operation failed:', error);
+ // Show user-friendly error message
+}
+```
+
+## TypeScript Guidelines
+
+- Use strict typing and avoid `any`.
+- Export explicit types for shared data structures.
+- Use `as const` for string literals in discriminated union types.
+
+## Vite Configuration
+
+Use the standard Vite React configuration with TypeScript:
+
+```typescript
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+
+export default defineConfig({
+ plugins: [react()],
+});
+```
+
+## Testing
+
+NEVER call external services in unit tests. ALWAYS mock the Echo SDK:
+
+```typescript
+vi.mock('@merit-systems/echo-react-sdk', () => ({
+ EchoProvider: ({ children }: { children: React.ReactNode }) => <>{children}>,
+ EchoTokens: () => ,
+}));
+```
diff --git a/templates/react-image/.cursor/rules/echo_rules.mdc b/templates/react-image/.cursor/rules/echo_rules.mdc
new file mode 100644
index 000000000..521e2258e
--- /dev/null
+++ b/templates/react-image/.cursor/rules/echo_rules.mdc
@@ -0,0 +1,174 @@
+---
+description: Guidelines and best practices for building Echo React image generation applications with Vite, including SDK initialization, image generation patterns, and component architecture
+globs: **/*.ts,**/*.tsx,**/*.js,**/*.jsx
+---
+
+# Echo React Image Generation (Vite) Guidelines
+
+## Architecture
+
+This is a client-side React application built with Vite for AI-powered image generation using the Echo React SDK. It provides image generation with automatic billing and user management through Echo.
+
+### Key Dependencies
+
+- `@merit-systems/echo-react-sdk` for Echo integration (provider, auth, UI)
+- `@ai-sdk/react` for React hooks
+- `ai` (Vercel AI SDK v5) for model interaction
+- `react` and `react-dom` for the UI framework
+- `vite` for the build tool
+- Radix UI components for the UI layer
+
+## SDK Initialization
+
+### EchoProvider Setup
+
+ALWAYS wrap your application with `EchoProvider` at the root level in `src/main.tsx`:
+
+```typescript
+import { StrictMode } from 'react';
+import { createRoot } from 'react-dom/client';
+import { EchoProvider } from '@merit-systems/echo-react-sdk';
+import App from './App.tsx';
+
+createRoot(document.getElementById('root')!).render(
+
+
+
+
+
+);
+```
+
+## Environment Variables
+
+ALWAYS store your Echo App ID in `.env`:
+
+```bash
+VITE_ECHO_APP_ID=your_echo_app_id
+```
+
+NEVER hardcode API keys or app IDs. ALWAYS use `import.meta.env.VITE_*` environment variables.
+
+Note: Vite only exposes variables prefixed with `VITE_` to client code. NEVER store server secrets in `VITE_` prefixed variables as they are bundled into the client.
+
+## Image Generation
+
+### Image Generation Component
+
+Keep image generation logic in `src/components/ImageGeneration.tsx`:
+
+```typescript
+export function ImageGeneration() {
+ // Image prompt input, model selection, and generated image display
+}
+```
+
+ALWAYS handle loading states and errors during image generation. Display appropriate feedback while images are being generated.
+
+## Client-Side Architecture
+
+This is entirely a client-side application. All Echo interactions happen through the React SDK:
+
+- Use `@merit-systems/echo-react-sdk` for all Echo functionality.
+- The `EchoProvider` manages authentication state and token management.
+- Use Echo UI components for user-facing Echo features.
+
+NEVER attempt to use `@merit-systems/echo-next-sdk` in this project. That package is exclusively for Next.js server-side usage.
+
+## Echo UI Components
+
+Use the shared Echo UI components in `src/components/`:
+
+- `echo-button.tsx` - Echo sign-in button
+- `echo-popover.tsx` - Account popover menu
+- `echo-account-react.tsx` - React-specific account management
+- `echo-account.tsx` - Account display
+- `balance.tsx` - Token balance display
+- `money-input.tsx` - Currency input for top-ups
+- `top-up-button.tsx` - Quick top-up button
+- `logo.tsx` - Echo logo component
+
+### UI Primitives
+
+Reusable UI primitives are in `src/components/ui/`:
+
+- `skeleton.tsx` - Loading skeleton placeholders
+- `input.tsx` - Styled input component
+- `tooltip.tsx` - Tooltip component
+- `popover.tsx` - Popover component
+- `avatar.tsx` - User avatar component
+
+## Component Patterns
+
+### Separation of Concerns
+
+- Keep Echo provider setup in `src/main.tsx`.
+- Keep the main app layout in `src/App.tsx`.
+- Keep image generation in `src/components/ImageGeneration.tsx`.
+- Keep Echo-specific components in `src/components/`.
+- Keep UI primitives in `src/components/ui/`.
+
+## Project Structure
+
+Follow this structure:
+
+```
+src/
+ main.tsx # Entry point with EchoProvider
+ App.tsx # Root component with layout
+ components/
+ ImageGeneration.tsx # Image generation component
+ ui/ # Reusable UI primitives
+ echo-button.tsx # Echo integration components
+ echo-popover.tsx
+ echo-account-react.tsx
+ echo-account.tsx
+ balance.tsx
+ top-up-button.tsx
+ lib/
+ utils.ts # Shared utilities
+ currency-utils.ts # Currency formatting
+```
+
+## Error Handling
+
+ALWAYS handle errors explicitly and provide meaningful feedback:
+
+```typescript
+try {
+ const result = await generateImage(prompt);
+ return result;
+} catch (error) {
+ console.error('Image generation failed:', error);
+ // Show user-friendly error message
+}
+```
+
+## TypeScript Guidelines
+
+- Use strict typing and avoid `any`.
+- Export explicit types for shared data structures.
+- Use `as const` for string literals in discriminated union types.
+
+## Vite Configuration
+
+Use the standard Vite React configuration:
+
+```typescript
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+
+export default defineConfig({
+ plugins: [react()],
+});
+```
+
+## Testing
+
+NEVER call external services in unit tests. ALWAYS mock the Echo SDK:
+
+```typescript
+vi.mock('@merit-systems/echo-react-sdk', () => ({
+ EchoProvider: ({ children }: { children: React.ReactNode }) => <>{children}>,
+}));
+```
diff --git a/templates/react/.cursor/rules/echo_rules.mdc b/templates/react/.cursor/rules/echo_rules.mdc
new file mode 100644
index 000000000..5047d43c0
--- /dev/null
+++ b/templates/react/.cursor/rules/echo_rules.mdc
@@ -0,0 +1,148 @@
+---
+description: Guidelines and best practices for building Echo React (Vite) applications, including SDK initialization, provider setup, environment variables, and component patterns
+globs: **/*.ts,**/*.tsx,**/*.js,**/*.jsx
+---
+
+# Echo React (Vite) Guidelines
+
+## SDK Initialization
+
+### EchoProvider Setup
+
+ALWAYS wrap your application with `EchoProvider` at the root level in `main.tsx`:
+
+```typescript
+import { StrictMode } from 'react';
+import { createRoot } from 'react-dom/client';
+import App from './App.tsx';
+import { EchoProvider } from '@merit-systems/echo-react-sdk';
+
+createRoot(document.getElementById('root')!).render(
+
+
+
+
+
+);
+```
+
+### Using Echo Components
+
+Use the pre-built Echo UI components from `@merit-systems/echo-react-sdk`:
+
+```typescript
+import { EchoTokens } from '@merit-systems/echo-react-sdk';
+
+function App() {
+ return (
+ <>
+ Welcome to Echo
+
+ >
+ );
+}
+```
+
+## Environment Variables
+
+ALWAYS store your Echo App ID in `.env`:
+
+```bash
+VITE_ECHO_APP_ID=your_echo_app_id
+```
+
+NEVER hardcode API keys or app IDs directly in your code. ALWAYS use `import.meta.env.VITE_*` environment variables.
+
+Note: Vite only exposes environment variables prefixed with `VITE_` to client code. NEVER store server secrets in `VITE_` prefixed variables as they are bundled into the client.
+
+## Client-Side Architecture
+
+This is a client-side React application. All Echo interactions happen through the React SDK:
+
+- Use `@merit-systems/echo-react-sdk` for all Echo functionality.
+- The `EchoProvider` manages authentication state and token management.
+- Use Echo UI components (`EchoTokens`, etc.) for user-facing Echo features.
+
+NEVER attempt to use `@merit-systems/echo-next-sdk` in a Vite/React project. That package is exclusively for Next.js server-side usage.
+
+## Component Patterns
+
+### Echo-Aware Components
+
+When building components that interact with Echo, keep Echo logic isolated:
+
+```typescript
+// CORRECT - Echo component handles its own concerns
+import { EchoTokens } from '@merit-systems/echo-react-sdk';
+
+export function TokenDisplay() {
+ return (
+
+
+
+ );
+}
+```
+
+### Separation of Concerns
+
+- Keep Echo provider setup in `main.tsx`.
+- Keep Echo-specific components in a dedicated directory (e.g., `src/components/echo/`).
+- Keep UI components separate from Echo integration logic.
+
+## Error Handling
+
+ALWAYS handle errors explicitly and provide meaningful feedback to users:
+
+```typescript
+try {
+ const result = await someOperation();
+ return result;
+} catch (error) {
+ console.error('Operation failed:', error);
+ // Show user-friendly error message
+}
+```
+
+## Project Structure
+
+Follow this structure for Echo React (Vite) projects:
+
+```
+src/
+ App.tsx # Main application component
+ main.tsx # Entry point with EchoProvider
+ components/ # UI components
+ lib/ # Shared utilities
+ assets/ # Static assets
+```
+
+## TypeScript Guidelines
+
+- Use strict typing and avoid `any`.
+- Export explicit types for shared data structures.
+- Use `as const` for string literals in discriminated union types.
+
+## Vite Configuration
+
+Use the standard Vite React configuration:
+
+```typescript
+import { defineConfig } from 'vite';
+import react from '@vitejs/plugin-react';
+
+export default defineConfig({
+ plugins: [react()],
+});
+```
+
+## Testing
+
+NEVER call external services directly in unit tests. ALWAYS mock the Echo SDK:
+
+```typescript
+vi.mock('@merit-systems/echo-react-sdk', () => ({
+ EchoProvider: ({ children }: { children: React.ReactNode }) => <>{children}>,
+ EchoTokens: () => ,
+}));
+```