webui: implement modular demo system with TypeScript and shared fixtures

Replace hand-written HTML demo pages with TypeScript demo modules and
automated infrastructure to reduce maintenance overhead and improve
developer experience with type safety and shared code.

Problems Solved:

Demo Maintenance Overhead:
- Hand-written HTML demo pages contained extensive boilerplate duplication
- No type checking for demo setup code or component data
- Manual maintenance of demo/index.html with available demos
- Difficult to share common fake data between demo pages
- No hot module replacement for demo development

Code Quality and Consistency:
- Demo setup code written in plain JavaScript without type safety
- No validation that demo data matches component interfaces
- Inconsistent styling and structure across demo pages
- Duplicated fake data declarations in each demo file

Solution Architecture:

TypeScript Demo Module System:
- Created DemoModule interface for standardized demo structure
- Demo modules export title, description, imports, and setup functions
- Full TypeScript compilation with type checking for demo code
- Dynamic import system for on-demand demo loading with Vite integration

Shared Demo Infrastructure:
- demo-framework/ with types.ts and demo-runner.ts for core functionality
- DemoRunner class handles dynamic loading, cleanup, and error handling
- Single demo-runner.html page loads any demo module dynamically
- Supports URL hash routing for direct demo links

Centralized Fake Data:
- demo-fixtures/ directory with shared TypeScript data files
- sampleToolCalls, sampleTimelineMessages, and sampleContainerState
- Type-safe imports ensure demo data matches component interfaces
- demoUtils with helper functions for consistent demo UI creation

Auto-generated Index Page:
- generate-index.ts scans for *.demo.ts files and extracts metadata
- Creates index-generated.html with links to all available demos
- Automatically includes demo titles and descriptions
- Eliminates manual maintenance of demo listing

Implementation Details:

Demo Framework:
- DemoRunner.loadDemo() uses dynamic imports with Vite ignore comments
- Automatic component import based on demo module configuration
- Support for demo-specific CSS and cleanup functions
- Error handling with detailed error display for debugging

Demo Module Structure:
- sketch-chat-input.demo.ts: Interactive chat with message history
- sketch-container-status.demo.ts: Status variations with real-time updates
- sketch-tool-calls.demo.ts: Multiple tool call examples with progressive loading
- All use shared fixtures and utilities for consistent experience

Vite Integration:
- Hot Module Replacement works for demo modules and shared fixtures
- TypeScript compilation on-the-fly for immediate feedback
- Dynamic imports work seamlessly with Vite's module system
- @vite-ignore comments prevent import analysis warnings

Testing and Validation:
- Tested demo runner loads and displays available components
- Verified component discovery and dynamic import functionality
- Confirmed shared fixture imports work correctly
- Validated auto-generated index creation and content

Files Modified:
- demo-framework/types.ts: TypeScript interfaces for demo system
- demo-framework/demo-runner.ts: Core demo loading and execution logic
- demo-fixtures/: Shared fake data (tool-calls.ts, timeline-messages.ts, container-status.ts, index.ts)
- demo-runner.html: Interactive demo browser with sidebar navigation
- generate-index.ts: Auto-generation script for demo index
- sketch-chat-input.demo.ts: Converted chat input demo to TypeScript
- sketch-container-status.demo.ts: Container status demo with variations
- sketch-tool-calls.demo.ts: Tool calls demo with interactive examples
- readme.md: Comprehensive documentation for new demo system

Benefits:
- Developers get full TypeScript type checking for demo code
- Shared fake data ensures consistency and reduces duplication
- Hot module replacement provides instant feedback during development
- Auto-generated index eliminates manual maintenance
- Modular architecture makes it easy to add new demos
- Vite integration provides fast development iteration

The new system reduces demo maintenance overhead while providing
better developer experience through TypeScript, shared code, and
automated infrastructure.

Co-Authored-By: sketch <hello@sketch.dev>
Change-ID: s3d91894eb7c4a79fk
diff --git a/webui/src/web-components/demo/demo-fixtures/timeline-messages.ts b/webui/src/web-components/demo/demo-fixtures/timeline-messages.ts
new file mode 100644
index 0000000..a98c728
--- /dev/null
+++ b/webui/src/web-components/demo/demo-fixtures/timeline-messages.ts
@@ -0,0 +1,113 @@
+/**
+ * Shared fake timeline message data for demos
+ */
+
+import { AgentMessage } from "../../../types";
+import { sampleToolCalls } from "./tool-calls";
+
+const baseTimestamp = new Date("2024-01-15T10:00:00Z");
+
+export const sampleTimelineMessages: AgentMessage[] = [
+  {
+    type: "user",
+    end_of_turn: true,
+    content:
+      "Can you help me implement a file upload component with drag and drop support?",
+    timestamp: new Date(baseTimestamp.getTime()).toISOString(),
+    conversation_id: "demo-conversation",
+    idx: 0,
+  },
+  {
+    type: "agent",
+    end_of_turn: false,
+    content:
+      "I'll help you create a file upload component with drag and drop support. Let me start by analyzing your current project structure and then implement the component.",
+    timestamp: new Date(baseTimestamp.getTime() + 1000).toISOString(),
+    conversation_id: "demo-conversation",
+    idx: 1,
+  },
+  {
+    type: "agent",
+    end_of_turn: false,
+    content: "First, let me check your current directory structure:",
+    tool_calls: [sampleToolCalls[2]], // bash command
+    timestamp: new Date(baseTimestamp.getTime() + 2000).toISOString(),
+    conversation_id: "demo-conversation",
+    idx: 2,
+  },
+  {
+    type: "tool",
+    end_of_turn: false,
+    content:
+      "src/\n├── components/\n│   ├── Button.tsx\n│   └── Input.tsx\n├── styles/\n│   └── globals.css\n└── utils/\n    └── helpers.ts",
+    tool_name: "bash",
+    tool_call_id: "toolu_01bash123",
+    timestamp: new Date(baseTimestamp.getTime() + 3000).toISOString(),
+    conversation_id: "demo-conversation",
+    idx: 3,
+  },
+  {
+    type: "agent",
+    end_of_turn: true,
+    content:
+      "Perfect! I can see you have a components directory. Now I'll create a FileUpload component with drag and drop functionality. This will include:\n\n1. A drop zone area\n2. File selection via click\n3. Progress indicators\n4. File validation\n5. Preview of selected files",
+    timestamp: new Date(baseTimestamp.getTime() + 4000).toISOString(),
+    conversation_id: "demo-conversation",
+    idx: 4,
+  },
+];
+
+export const longTimelineMessage: AgentMessage = {
+  type: "agent",
+  end_of_turn: true,
+  content: `I've analyzed your codebase and here's a comprehensive plan for implementing the file upload component:
+
+## Implementation Plan
+
+### 1. Component Structure
+The FileUpload component will be built using React with TypeScript. It will consist of:
+- A main container with drop zone styling
+- File input element (hidden)
+- Visual feedback for drag states
+- File list display area
+- Progress indicators
+
+### 2. Key Features
+- **Drag & Drop**: Full drag and drop support with visual feedback
+- **Multiple Files**: Support for selecting multiple files at once
+- **File Validation**: Size limits, file type restrictions
+- **Progress Tracking**: Upload progress for each file
+- **Error Handling**: User-friendly error messages
+- **Accessibility**: Proper ARIA labels and keyboard navigation
+
+### 3. Technical Considerations
+- Use the HTML5 File API for file handling
+- Implement proper event handlers for drag events
+- Add debouncing for performance
+- Include comprehensive error boundaries
+- Ensure mobile responsiveness
+
+### 4. Styling Approach
+- CSS modules for component-scoped styles
+- Responsive design with mobile-first approach
+- Smooth animations and transitions
+- Consistent with your existing design system
+
+This implementation will provide a robust, user-friendly file upload experience that integrates seamlessly with your existing application.`,
+  timestamp: new Date(baseTimestamp.getTime() + 5000).toISOString(),
+  conversation_id: "demo-conversation",
+  idx: 5,
+};
+
+export const mixedTimelineMessages: AgentMessage[] = [
+  ...sampleTimelineMessages,
+  longTimelineMessage,
+  {
+    type: "user",
+    end_of_turn: true,
+    content: "That sounds great! Can you also add file type validation?",
+    timestamp: new Date(baseTimestamp.getTime() + 6000).toISOString(),
+    conversation_id: "demo-conversation",
+    idx: 6,
+  },
+];