Proper Code vs. Base44

LEVERAGEAI Decision Making Processes

Architecting Claude Part 1

Evaluations, Standards and Styling: Proper Analysis weighing Constraint Driven Design; Robust and Resilient Performance; On a Scale of Elegant Simplicity:

Full Context can be found @ :

https://claude.ai/chat/69459500-ac65-4343-8be9-75a5c0cb81ed?artifactId=main_application

Constraint Analysis

Primary Constraint: Existing categorization framework limits integration complexity. The 8 libraries map cleanly to current categories:

  • Automation (5/8): schedule, watchdog, pyautogui, smtplib+email, pyttsx3

  • Data Processing (2/8): openpyxl, pytesseract+Pillow

  • Web Scraping (1/8): requests+BeautifulSoup

Secondary Constraint: Dependency management becomes the architectural bottleneck - these libraries require external system dependencies (tesseract, audio drivers).

Integration Architecture

Template-Driven Approach

Create script scaffolds that embed library patterns directly into PyStudio's existing framework:

/templates/automation/
  ├── scheduler_template.py
  ├── file_watcher_template.py  
  ├── gui_automation_template.py
  ├── email_automation_template.py
  └── tts_template.py

Execution Layer Enhancement

Extend current script execution to handle:

  • Pre-execution dependency checks

  • Runtime environment setup

  • Error context for missing system dependencies

Category Enhancement

Leverage existing tag system to add sub-categories:

  • automationscheduler, file-monitor, gui-control, email, speech

  • data-processingexcel, ocr

  • web-scrapingcontent-extraction

Leverage Points

  1. Template Integration: Instead of building new UI, enhance the "New Script" workflow with library-specific templates

  2. Dependency Pipeline: Create installation scripts that run before first execution

  3. Error Context: Transform library import failures into actionable setup instructions

Critical Decision

The existing script structure suggests PyStudio already handles execution contexts well. The question: Does it run in a sandboxed Python environment or system Python?

This determines whether we:

  • A) Build dependency management into the app

  • B) Rely on user system configuration

Next: Provide the codebase. I'll identify the execution constraint and design the integration to amplify existing architectural strengths rather than add complexity.

# # Thought Process:

The user is clarifying that we're rebuilding PyStudio from scratch, so I don't need to be constrained by the existing categories shown in the screenshot. This opens up much more architectural flexibility.

Looking at the 8 Python libraries from the document:

  1. schedule - task scheduling/automation

  2. watchdog - file system monitoring

  3. pyautogui - GUI automation

  4. smtplib + email - email automation

  5. pytesseract + Pillow - OCR/image processing

  6. openpyxl - Excel manipulation

  7. requests + BeautifulSoup - web scraping

  8. pyttsx3 - text-to-speech

Since we're rebuilding, I should think about this from a systems architecture perspective with leverage points in mind. What's the core constraint that shapes everything else?

The constraint is likely going to be execution environment management - these libraries have varying dependency requirements. Some are pure Python (schedule, requests), others require system binaries (tesseract), and others interact with OS-level services (pyautogui, pyttsx3).

From an elegant simplicity perspective, I should identify the minimal set of categories that capture the essential patterns, then design the architecture to handle the complexity behind simple interfaces.

Looking at the patterns:

  • Time-based execution (schedule)

  • Event-driven execution (watchdog)

  • System interaction (pyautogui, pyttsx3)

  • Data transformation (openpyxl, pytesseract+Pillow)

  • Network operations (requests+BeautifulSoup, smtplib+email)

But that's still thinking in terms of technical implementation. From a user perspective, what are they actually trying to accomplish?

  • Automation: Replace manual repetitive tasks

  • Integration: Connect different systems/services

  • Processing: Transform data between formats

  • Monitoring: Watch for changes and respond

Actually, let me step back. The leverage point here is probably the execution model itself.

I see a breakthrough in organizing scripts by their fundamental execution paradigms. The new categorization focuses on when and how scripts run, which directly aligns with user intentions and system architecture. This approach transcends traditional library-based classifications, creating a more intuitive and flexible framework for automation tools.

The four core execution modes - Scheduled, Reactive, Interactive, and Continuous - provide a clean, user-centric way to conceptualize script behavior. Each mode represents a distinct approach to task management and system interaction.

Architecture Foundation

Core Constraint Identified: Execution model determines everything else.

Proposed Category Structure

Instead of grouping by library function, group by execution pattern:

1. Scheduled

  • schedule - time-based triggers

  • smtplib+email - recurring reports/notifications

  • Pattern: Runs on time, exits cleanly

2. Reactive

  • watchdog - file system events

  • requests+BeautifulSoup - webhook/API responses

  • Pattern: Waits for external events, processes, continues waiting

3. Interactive

  • pyautogui - GUI automation sequences

  • pytesseract+Pillow - on-demand OCR processing

  • openpyxl - batch data transformation

  • Pattern: Runs once per invocation, returns results

4. Persistent

  • pyttsx3 - continuous voice interface

  • Combined automation workflows

  • Pattern: Runs continuously, maintains state

Architectural Implications

This execution-based categorization solves the dependency management constraint elegantly:

  • Scheduled/Interactive: Can validate dependencies at script creation

  • Reactive/Persistent: Must validate dependencies at startup and gracefully handle failures

Template Strategy

Each category gets execution-specific scaffolding:

python

# Scheduled template
class ScheduledTask:
    def setup(self): pass
    def execute(self): pass  # User implements this
    def cleanup(self): pass

# Reactive template  
class ReactiveTask:
    def setup(self): pass
    def handle_event(self, event): pass  # User implements this
    def should_continue(self): return True

Critical Questions for Codebase Review

  1. Runtime Environment: Embedded Python interpreter or system Python?

  2. Process Model: Single process or script isolation?

  3. State Management: How do persistent scripts maintain state between app restarts?

The answers determine whether we build a script runner or a Python runtime manager.

Ready for codebase analysis.

User:

Embedded Python interpreter or system Python? # What are the advantages and disadvantages of each?

Single process or script isolation? Please explain the advantages and disadvantages of these as ell.

State Management: How do persistent scripts maintain state between app restarts? I hadn't thought of this - lets brainstorm and engineer and elegant strategy and solution.

LLM - Claude

Thoughts:

These are fundamental architectural questions that will shape the entire system. Let me think through each systematically.

  1. Embedded Python interpreter vs System Python

Embedded Python interpreter: Advantages:

  • Complete control over the Python environment

  • No dependency conflicts with user's system Python

  • Can bundle specific versions of libraries we need

  • Sandboxed execution - security benefits

  • Consistent behavior across different user environments

  • Can implement custom import hooks, security restrictions

  • Easier to manage library versions

Disadvantages:

  • Larger app size (need to bundle Python interpreter)

  • More complex build process

  • Need to handle platform-specific binaries

  • Updates require app updates

  • May not have access to user's existing Python packages

  • More memory usage (separate interpreter)

System Python: Advantages:

  • Smaller app footprint

  • User can leverage their existing Python environment and packages

  • Easier to integrate with user's development workflow

  • Can use whatever Python version user prefers

  • Access to user's installed packages

Disadvantages:

  • Dependency hell - conflicts with user's environment

  • Inconsistent behavior across different systems

  • Security concerns - full system access

  • Harder to ensure consistent library versions

  • User might not have Python installed

  • Different Python versions might break scripts

  1. Single process vs Script isolation

Single process: Advantages:

  • Lower memory overhead

  • Faster inter-script communication

  • Shared state between scripts possible

  • Easier to manage overall

  • Better for GUI responsiveness

Disadvantages:

  • One script crash can bring down everything

  • Memory leaks accumulate

  • Harder to kill runaway scripts

  • Global state pollution

  • Threading complexity for concurrent scripts

Script isolation (separate processes): Advantages:

  • Fault isolation - one crash doesn't affect others

  • True parallelism

  • Easy to kill individual scripts

  • Memory isolation

  • Better security isolation

  • Can run different Python versions per script

Disadvantages:

  • Higher memory overhead

  • Inter-process communication complexity

  • Harder to share state

  • More complex process management

  • Platform differences in process handling

  1. State Management for Persistent Scripts

I'm exploring robust persistence strategies that balance simplicity and flexibility. A hybrid approach seems most promising, combining lightweight storage with adaptable state management. The goal is creating a system that can maintain script state across app restarts while keeping implementation straightforward and efficient.

Key considerations include minimizing overhead, supporting flexible storage mechanisms, and providing seamless state preservation. The solution needs to accommodate different script requirements while maintaining a clean, intuitive interface for developers.

LLM Claude Response:

Runtime Environment Analysis

Embedded Python Interpreter

Advantages:

  • Dependency determinism: Zero conflicts with user's system

  • Security sandbox: Controlled execution environment

  • Version consistency: Same behavior across all users

  • Library bundling: Ship exact versions we've tested

Disadvantages:

  • App size: +50-100MB for interpreter + core libraries

  • Update coupling: Python updates require app updates

  • Build complexity: Platform-specific binaries

System Python

Advantages:

  • Lean footprint: App stays small

  • User ecosystem: Access to their existing packages

  • Development workflow: Natural integration

Disadvantages:

  • Dependency chaos: Version conflicts kill reliability

  • Environment variability: "Works on my machine" syndrome

  • Security exposure: Full system access

Recommendation: Embedded interpreter. The reliability constraint trumps size concerns.


Process Architecture Analysis

Single Process

Advantages:

  • State sharing: Scripts can communicate directly

  • Resource efficiency: Lower memory overhead

  • Simpler IPC: Direct function calls

Disadvantages:

  • Cascade failure: One bad script kills everything

  • Resource contention: Blocking operations freeze UI

  • Memory pollution: Leaks accumulate

Script Isolation

Advantages:

  • Fault boundaries: Script crashes stay contained

  • Resource isolation: CPU/memory limits per script

  • True parallelism: No GIL constraints

Disadvantages:

  • Memory overhead: ~10-20MB per Python process

  • IPC complexity: Process communication mechanisms

  • State sharing: More complex inter-script coordination

Recommendation: Hybrid model. UI process + isolated script processes with managed IPC.


State Management Strategy

The Constraint

Persistent scripts need state that survives:

  • App restarts

  • Script modifications

  • System reboots

  • Crashes

Elegant Solution: Event-Sourced State Pods

class StatePod:
    def __init__(self, script_id: str):
        self.db = sqlite3.connect(f"state/{script_id}.db")
        self.state = {}
        self.replay_events()
    
    def set(self, key: str, value: any):
        self.state[key] = value
        self._log_event("SET", key, value)
    
    def get(self, key: str, default=None):
        return self.state.get(key, default)
    
    def _log_event(self, action, key, value):
        self.db.execute(
            "INSERT INTO events (timestamp, action, key, value) VALUES (?, ?, ?, ?)",
            (time.time(), action, key, pickle.dumps(value))
        )

Benefits:

  • Automatic persistence: Every state change logged

  • Crash recovery: Replay events to restore state

  • Script versioning: State survives code changes

  • Debugging: Full state history visible

  • Cleanup: Old events can be compacted

State Sharing Between Scripts:

python

# Shared message bus
SharedState.publish("weather_data", temperature_reading)
SharedState.subscribe("weather_data", callback=update_dashboard)

Memory Management:

  • Lazy loading: Only active scripts load state

  • State expiration: TTL on unused state entries

  • Compression: Pickle + gzip for large objects

This creates persistent script identities that maintain context across restarts while keeping the implementation simple and debuggable.

User:

*Here is the original code that needs Fixed:

Poorly Written Code Example:

import React, { useState, useEffect } from "react";
import { Document, SearchQuery, ScrapedContent, Report } from "@/entities/all";
import { 
  FileText, 
  Search, 
  Globe, 
  TrendingUp, 
  Zap, 
  Database,
  Clock,
  CheckCircle
} from "lucide-react";
import BrutalistCard from "../components/BrutalistCard";
import ProcessingQueue from "../components/ProcessingQueue";

export default function Dashboard() {
  const [stats, setStats] = useState({
    totalDocuments: 0,
    totalSearches: 0,
    totalScraped: 0,
    totalReports: 0
  });
  const [recentActivity, setRecentActivity] = useState([]);
  const [processingQueue, setProcessingQueue] = useState([]);
  const [isLoading, setIsLoading] = useState(true);

  useEffect(() => {
    loadDashboardData();
  }, []);

  const loadDashboardData = async () => {
    try {
      const [documents, searches, scraped, reports] = await Promise.all([
        Document.list(),
        SearchQuery.list(),
        ScrapedContent.list(),
        Report.list()
      ]);

      setStats({
        totalDocuments: documents.length,
        totalSearches: searches.length,
        totalScraped: scraped.length,
        totalReports: reports.length
      });

      // Mock recent activity
      const mockActivity = [
        { name: "python-tutorial.pdf", type: "Document Upload", status: "completed", timestamp: "2 min ago" },
        { name: "django-docs scraping", type: "Web Scraping", status: "processing", timestamp: "5 min ago", progress: 65 },
        { name: "Weekly Analytics Report", type: "Report Generation", status: "completed", timestamp: "1 hour ago" },
        { name: "machine-learning-guide.md", type: "Document Upload", status: "pending", timestamp: "3 hours ago" }
      ];

      setRecentActivity(mockActivity);
      setProcessingQueue(mockActivity.filter(item => item.status === "processing" || item.status === "pending"));
      
    } catch (error) {
      console.error("Error loading dashboard data:", error);
    } finally {
      setIsLoading(false);
    }
  };

  const StatCard = ({ title, value, icon: Icon, color }) => (
    <BrutalistCard color={color} hover>
      <div className="flex items-center justify-between">
        <div>
          <p className="font-black text-2xl text-black mb-1">{value}</p>
          <p className="font-bold text-sm text-black uppercase tracking-wider">
            {title}
          </p>
        </div>
        <div className="bg-black p-3 border-2 border-black">
          <Icon className="w-6 h-6 text-white" />
        </div>
      </div>
    </BrutalistCard>
  );

  if (isLoading) {
    return (
      <div className="space-y-8">
        <div className="text-center">
          <h1 className="text-4xl font-black text-black uppercase tracking-tight mb-4">
            LOADING DASHBOARD...
          </h1>
          <div className="bg-blue-500 border-4 border-black brutalist-shadow p-8 inline-block">
            <Zap className="w-12 h-12 text-white animate-pulse" />
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="space-y-8">
      {/* Header */}
      <div className="text-center mb-12">
        <h1 className="text-5xl font-black text-black uppercase tracking-tight mb-4">
          SYSTEM DASHBOARD
        </h1>
        <div className="bg-yellow-400 border-4 border-black brutalist-shadow p-4 inline-block">
          <p className="font-black text-xl text-black uppercase tracking-wider">
            MONITORING ALL SYSTEMS
          </p>
        </div>
      </div>

      {/* Stats Grid */}
      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
        <StatCard
          title="Documents"
          value={stats.totalDocuments}
          icon={FileText}
          color="blue"
        />
        <StatCard
          title="Searches"
          value={stats.totalSearches}
          icon={Search}
          color="pink"
        />
        <StatCard
          title="Scraped Pages"
          value={stats.totalScraped}
          icon={Globe}
          color="green"
        />
        <StatCard
          title="Reports"
          value={stats.totalReports}
          icon={TrendingUp}
          color="orange"
        />
      </div>

      {/* Main Content Grid */}
      <div className="grid lg:grid-cols-2 gap-8">
        {/* Processing Queue */}
        <ProcessingQueue items={processingQueue} />

        {/* Recent Activity */}
        <BrutalistCard>
          <div className="flex items-center justify-between mb-6">
            <h3 className="text-xl font-black uppercase tracking-wider">
              RECENT ACTIVITY
            </h3>
            <div className="bg-black text-white px-3 py-1 border-2 border-black">
              <span className="font-black text-sm">LIVE FEED</span>
            </div>
          </div>

          <div className="space-y-4 max-h-96 overflow-y-auto">
            {recentActivity.map((activity, index) => (
              <div
                key={index}
                className="bg-gray-100 border-4 border-black p-4 flex items-center justify-between"
              >
                <div className="flex items-center space-x-4">
                  {activity.status === 'completed' ? (
                    <CheckCircle className="w-6 h-6 text-green-500" />
                  ) : activity.status === 'processing' ? (
                    <Zap className="w-6 h-6 text-blue-500 animate-pulse" />
                  ) : (
                    <Clock className="w-6 h-6 text-gray-500" />
                  )}
                  <div>
                    <p className="font-black text-sm uppercase">
                      {activity.name}
                    </p>
                    <p className="font-bold text-xs text-gray-600 mt-1">
                      {activity.type} • {activity.timestamp}
                    </p>
                  </div>
                </div>
                <div className={`
                  px-3 py-1 border-2 border-black font-black text-xs uppercase
                  ${activity.status === 'completed' ? 'bg-green-500 text-white' : ''}
                  ${activity.status === 'processing' ? 'bg-blue-500 text-white' : ''}
                  ${activity.status === 'pending' ? 'bg-gray-500 text-white' : ''}
                `}>
                  {activity.status}
                </div>
              </div>
            ))}
          </div>
        </BrutalistCard>
      </div>

      {/* System Status */}
      <div className="grid md:grid-cols-3 gap-6">
        <BrutalistCard color="green">
          <div className="text-center">
            <Database className="w-8 h-8 text-black mx-auto mb-3" />
            <p className="font-black text-lg text-black uppercase">
              DATABASE
            </p>
            <p className="font-bold text-sm text-black mt-1">
              OPERATIONAL
            </p>
          </div>
        </BrutalistCard>

        <BrutalistCard color="blue">
          <div className="text-center">
            <Zap className="w-8 h-8 text-black mx-auto mb-3" />
            <p className="font-black text-lg text-black uppercase">
              AI PROCESSING
            </p>
            <p className="font-bold text-sm text-black mt-1">
              ACTIVE
            </p>
          </div>
        </BrutalistCard>

        <BrutalistCard color="pink">
          <div className="text-center">
            <TrendingUp className="w-8 h-8 text-black mx-auto mb-3" />
            <p className="font-black text-lg text-black uppercase">
              SEARCH ENGINE
            </p>
            <p className="font-bold text-sm text-black mt-1">
              READY
            </p>
          </div>
        </BrutalistCard>
      </div>
    </div>
  );
}

Analysis

The user is asking me to critically analyze the React Dashboard component from a LEVERAGEAI perspective, focusing on:

Constraint-based approach
Architecture and Spec-driven design
Clear type definitions
Testing mapped out before code is written
No sloppy logic or unnecessary dependencies

Let me examine the code systematically:
javascriptimport React, { useState, useEffect } from "react";
import { Document, SearchQuery, ScrapedContent, Report } from "@/entities/all";
import { 
  FileText, 
  Search, 
  Globe, 
  TrendingUp, 
  Zap, 
  Database,
  Clock,
  CheckCircle
} from "lucide-react";
import BrutalistCard from "../components/BrutalistCard";
import ProcessingQueue from "../components/ProcessingQueue";
Issues I can identify:

No TypeScript - This is JavaScript, not TypeScript, so there are no explicit type definitions
Importing from "@/entities/all" - This is a barrel export which can cause circular dependencies and makes it unclear what's actually being used
No interface definitions - The component doesn't define interfaces for props, state, or data structures
Mixed concerns - The component is doing data fetching, state management, and rendering all in one place

Looking at the component structure:
javascriptexport default function Dashboard() {
  const [stats, setStats] = useState({
    totalDocuments: 0,
    totalSearches: 0,
    totalScraped: 0,
    totalReports: 0
  });
  const [recentActivity, setRecentActivity] = useState([]);
  const [processingQueue, setProcessingQueue] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
Issues:

No type safety - useState calls have no type parameters
Implicit any types - Arrays and objects have no defined structure
No prop interface - Component takes no props but should probably be configurable

The state management reveals significant type safety and structural vulnerabilities.
 Without proper TypeScript interfaces,
 the component lacks robust type checking, leaving it prone to runtime errors and 
reducing code predictability. The useState hooks are essentially untyped, which means
 any data structure could be accidentally passed, breaking expected behavior.
The data loading approach mixes real API calls with mock data, creating an inconsistent 
and potentially unreliable data retrieval mechanism. Hardcoded mock entries suggest 
a prototype-level implementation that needs more sophisticated data generation or
 external configuration.
The StatCard component demonstrates a clean, declarative design with clear prop
 expectations, using destructuring to extract specific visual configuration 
parameters like title, value, icon, and color.
However, the implementation reveals several architectural weaknesses. 
The component lacks robust prop validation, relies on inline definitions that 
reduce modularity, and uses hardcoded CSS classes that limit design system flexibility.
 The rendering strategy doesn't account for dynamic layout requirements or potential 
performance optimizations through memoization.
The overall rendering logic exposes critical architectural concerns around
 error handling, loading states, and component responsibilities. 
The current implementation tightly couples data fetching, state management, 
and UI rendering, violating core separation of concerns principles.
Accessibility and responsive design considerations appear minimal, with no 
clear strategy for handling different screen sizes or providing semantic 
HTML structure for screen readers.
From an engineering perspective, the component demonstrates significant technical debt. 
Its monolithic design creates challenges for testing, scaling, and maintaining the codebase.
 The lack of dependency injection and error boundaries introduces 
substantial risk for system-wide failures.
Performance constraints further compound these issues, with potential memory
 leaks and unmanaged API interactions that could degrade application responsiveness 
and user experience.

Further Analysis:

Critical Analysis: Dashboard Component Failures

Type Safety Violation

javascript

const [recentActivity, setRecentActivity] = useState([]);

Problem: No TypeScript, no interfaces, no runtime validation. This is any[] masquerading as type safety.

Correct Approach:

typescript

interface ActivityItem {
  name: string;
  type: ActivityType;
  status: ProcessingStatus;
  timestamp: string;
  progress?: number;
}

const [recentActivity, setRecentActivity] = useState<ActivityItem[]>([]);

Architecture Violation: Mixed Concerns

javascript

export default function Dashboard() {
  // Data fetching
  // State management  
  // Business logic
  // Rendering
  // Error handling
}

Problem: Single component doing 5 different jobs. Untestable, unmaintainable.

Constraint-Based Solution:

  • Data Layer: useDashboardData() hook

  • Presentation Layer: Pure components

  • State Layer: Context/reducer pattern

  • Error Boundary: Separate component

Dependency Chaos

javascript

import { Document, SearchQuery, ScrapedContent, Report } from "@/entities/all";

Problem: Barrel imports create circular dependencies and hide actual usage.

Correct: Import only what you use from specific modules.

Mock Data Anti-Pattern

javascript

// Mock recent activity
const mockActivity = [
  { name: "python-tutorial.pdf", type: "Document Upload" }
];

Problem: Production code contains hardcoded test data. This is a deployment time bomb.

Solution: Dependency injection with data adapters.

Error Handling Failure

javascript

} catch (error) {
  console.error("Error loading dashboard data:", error);
} finally {
  setIsLoading(false);
}

Problem: Silent failure. User sees stale data with no indication of failure.

Constraint: Dashboard must surface errors and provide recovery paths.

No Testing Strategy

The component structure makes it impossible to:

  • Mock data sources

  • Test error states

  • Test loading states

  • Test user interactions

  • Achieve proper coverage

Performance Neglect

javascript

const StatCard = ({ title, value, icon: Icon, color }) => (

Problem: Inline component definition causes unnecessary re-renders.

The Root Constraint Violation

This component couples data fetching to presentation. Every change to data structure requires UI changes. Every UI change risks breaking data logic.

Correct Architecture:

typescript

// Data layer
const dashboardData = useDashboardData();

// Presentation layer  
return <DashboardView data={dashboardData} />;

Specification Absence

No clear definition of:

  • What constitutes dashboard "success"

  • Error recovery behaviors

  • Performance requirements

  • Data freshness requirements

Before writing code, we need:

  1. Data contracts (what APIs return)

  2. Error scenarios (network fail, auth fail, etc.)

  3. Performance constraints (load time, update frequency)

  4. User flows (what happens on each interaction)

This is prototype code shipped to production. The architectural debt will compound exponentially.

Example of poorly written code --

The following is a digest of the repository "PyKnowledgeApp".
This digest is designed to be easily parsed by Large Language Models.

--- SUMMARY ---
Repository: PyKnowledgeApp
Files Analyzed: 79
Total Text Size: 923.61 KB
Estimated Tokens (text only): ~237,904

--- DIRECTORY STRUCTURE ---
PyKnowledgeApp/
├── src/
│   ├── api/
│   │   ├── base44Client.js
│   │   ├── entities.js
│   │   └── integrations.js
│   ├── components/
│   │   ├── ui/
│   │   │   ├── accordion.jsx
│   │   │   ├── alert-dialog.jsx
│   │   │   ├── alert.jsx
│   │   │   ├── aspect-ratio.jsx
│   │   │   ├── avatar.jsx
│   │   │   ├── badge.jsx
│   │   │   ├── breadcrumb.jsx
│   │   │   ├── button.jsx
│   │   │   ├── calendar.jsx
│   │   │   ├── card.jsx
│   │   │   ├── carousel.jsx
│   │   │   ├── chart.jsx
│   │   │   ├── checkbox.jsx
│   │   │   ├── collapsible.jsx
│   │   │   ├── command.jsx
│   │   │   ├── context-menu.jsx
│   │   │   ├── dialog.jsx
│   │   │   ├── drawer.jsx
│   │   │   ├── dropdown-menu.jsx
│   │   │   ├── form.jsx
│   │   │   ├── hover-card.jsx
│   │   │   ├── input-otp.jsx
│   │   │   ├── input.jsx
│   │   │   ├── label.jsx
│   │   │   ├── menubar.jsx
│   │   │   ├── navigation-menu.jsx
│   │   │   ├── pagination.jsx
│   │   │   ├── popover.jsx
│   │   │   ├── progress.jsx
│   │   │   ├── radio-group.jsx
│   │   │   ├── resizable.jsx
│   │   │   ├── scroll-area.jsx
│   │   │   ├── select.jsx
│   │   │   ├── separator.jsx
│   │   │   ├── sheet.jsx
│   │   │   ├── sidebar.jsx
│   │   │   ├── skeleton.jsx
│   │   │   ├── slider.jsx
│   │   │   ├── sonner.jsx
│   │   │   ├── switch.jsx
│   │   │   ├── table.jsx
│   │   │   ├── tabs.jsx
│   │   │   ├── textarea.jsx
│   │   │   ├── toast.jsx
│   │   │   ├── toaster.jsx
│   │   │   ├── toggle-group.jsx
│   │   │   ├── toggle.jsx
│   │   │   ├── tooltip.jsx
│   │   │   └── use-toast.jsx
│   │   ├── BrutalistButton.jsx
│   │   ├── BrutalistCard.jsx
│   │   └── ProcessingQueue.jsx
│   ├── hooks/
│   │   └── use-mobile.jsx
│   ├── pages/
│   │   ├── Dashboard.jsx
│   │   ├── index.jsx
│   │   ├── KnowledgeBase.jsx
│   │   ├── Layout.jsx
│   │   ├── Reports.jsx
│   │   ├── Search.jsx
│   │   ├── Settings.jsx
│   │   ├── Upload.jsx
│   │   └── WebScraper.jsx
│   ├── utils/
│   │   └── index.ts [binary]
│   ├── App.css
│   ├── App.jsx
│   ├── index.css
│   └── main.jsx
├── components.json
├── eslint.config.js
├── jsconfig.json
├── package.json
├── postcss.config.js
├── PyStudio_export.json
├── README.md
├── tailwind.config.js
└── vite.config.js


--- FILE CONTENTS ---
============================================================
FILE: src/api/base44Client.js
============================================================
import { createClient } from '@base44/sdk';
// import { getAccessToken } from '@base44/sdk/utils/auth-utils';

// Create a client with authentication required
export const base44 = createClient({
  appId: "68b2d9dd295ddae8d2a8eac8", 
  requiresAuth: true // Ensure authentication is required for all operations
});


============================================================
FILE: src/api/entities.js
============================================================
import { base44 } from './base44Client';


export const Document = base44.entities.Document;

export const SearchQuery = base44.entities.SearchQuery;

export const ScrapedContent = base44.entities.ScrapedContent;

export const Report = base44.entities.Report;



// auth sdk:
export const User = base44.auth;

============================================================
FILE: src/api/integrations.js
============================================================
import { base44 } from './base44Client';




export const Core = base44.integrations.Core;

export const InvokeLLM = base44.integrations.Core.InvokeLLM;

export const SendEmail = base44.integrations.Core.SendEmail;

export const UploadFile = base44.integrations.Core.UploadFile;

export const GenerateImage = base44.integrations.Core.GenerateImage;

export const ExtractDataFromUploadedFile = base44.integrations.Core.ExtractDataFromUploadedFile;








============================================================
FILE: src/components/ui/accordion.jsx
============================================================
import * as React from "react"
import * as AccordionPrimitive from "@radix-ui/react-accordion"
import { ChevronDown } from "lucide-react"

import { cn } from "@/lib/utils"

const Accordion = AccordionPrimitive.Root

const AccordionItem = React.forwardRef(({ className, ...props }, ref) => (
  <AccordionPrimitive.Item ref={ref} className={cn("border-b", className)} {...props} />
))
AccordionItem.displayName = "AccordionItem"

const AccordionTrigger = React.forwardRef(({ className, children, ...props }, ref) => (
  <AccordionPrimitive.Header className="flex">
    <AccordionPrimitive.Trigger
      ref={ref}
      className={cn(
        "flex flex-1 items-center justify-between py-4 text-sm font-medium transition-all hover:underline text-left [&[data-state=open]>svg]:rotate-180",
        className
      )}
      {...props}>
      {children}
      <ChevronDown
        className="h-4 w-4 shrink-0 text-muted-foreground transition-transform duration-200" />
    </AccordionPrimitive.Trigger>
  </AccordionPrimitive.Header>
))
AccordionTrigger.displayName = AccordionPrimitive.Trigger.displayName

const AccordionContent = React.forwardRef(({ className, children, ...props }, ref) => (
  <AccordionPrimitive.Content
    ref={ref}
    className="overflow-hidden text-sm data-[state=closed]:animate-accordion-up data-[state=open]:animate-accordion-down"
    {...props}>
    <div className={cn("pb-4 pt-0", className)}>{children}</div>
  </AccordionPrimitive.Content>
))
AccordionContent.displayName = AccordionPrimitive.Content.displayName

export { Accordion, AccordionItem, AccordionTrigger, AccordionContent }


============================================================
FILE: src/components/ui/alert-dialog.jsx
============================================================
import * as React from "react"
import * as AlertDialogPrimitive from "@radix-ui/react-alert-dialog"

import { cn } from "@/lib/utils"
import { buttonVariants } from "@/components/ui/button"

const AlertDialog = AlertDialogPrimitive.Root

const AlertDialogTrigger = AlertDialogPrimitive.Trigger

const AlertDialogPortal = AlertDialogPrimitive.Portal

const AlertDialogOverlay = React.forwardRef(({ className, ...props }, ref) => (
  <AlertDialogPrimitive.Overlay
    className={cn(
      "fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
      className
    )}
    {...props}
    ref={ref} />
))
AlertDialogOverlay.displayName = AlertDialogPrimitive.Overlay.displayName

const AlertDialogContent = React.forwardRef(({ className, ...props }, ref) => (
  <AlertDialogPortal>
    <AlertDialogOverlay />
    <AlertDialogPrimitive.Content
      ref={ref}
      className={cn(
        "fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
        className
      )}
      {...props} />
  </AlertDialogPortal>
))
AlertDialogContent.displayName = AlertDialogPrimitive.Content.displayName

const AlertDialogHeader = ({
  className,
  ...props
}) => (
  <div
    className={cn("flex flex-col space-y-2 text-center sm:text-left", className)}
    {...props} />
)
AlertDialogHeader.displayName = "AlertDialogHeader"

const AlertDialogFooter = ({
  className,
  ...props
}) => (
  <div
    className={cn("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2", className)}
    {...props} />
)
AlertDialogFooter.displayName = "AlertDialogFooter"

const AlertDialogTitle = React.forwardRef(({ className, ...props }, ref) => (
  <AlertDialogPrimitive.Title ref={ref} className={cn("text-lg font-semibold", className)} {...props} />
))
AlertDialogTitle.displayName = AlertDialogPrimitive.Title.displayName

const AlertDialogDescription = React.forwardRef(({ className, ...props }, ref) => (
  <AlertDialogPrimitive.Description
    ref={ref}
    className={cn("text-sm text-muted-foreground", className)}
    {...props} />
))
AlertDialogDescription.displayName =
  AlertDialogPrimitive.Description.displayName

const AlertDialogAction = React.forwardRef(({ className, ...props }, ref) => (
  <AlertDialogPrimitive.Action ref={ref} className={cn(buttonVariants(), className)} {...props} />
))
AlertDialogAction.displayName = AlertDialogPrimitive.Action.displayName

const AlertDialogCancel = React.forwardRef(({ className, ...props }, ref) => (
  <AlertDialogPrimitive.Cancel
    ref={ref}
    className={cn(buttonVariants({ variant: "outline" }), "mt-2 sm:mt-0", className)}
    {...props} />
))
AlertDialogCancel.displayName = AlertDialogPrimitive.Cancel.displayName

export {
  AlertDialog,
  AlertDialogPortal,
  AlertDialogOverlay,
  AlertDialogTrigger,
  AlertDialogContent,
  AlertDialogHeader,
  AlertDialogFooter,
  AlertDialogTitle,
  AlertDialogDescription,
  AlertDialogAction,
  AlertDialogCancel,
}


============================================================
FILE: src/components/ui/alert.jsx
============================================================
import * as React from "react"
import { cva } from "class-variance-authority";

import { cn } from "@/lib/utils"

const alertVariants = cva(
  "relative w-full rounded-lg border px-4 py-3 text-sm [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground [&>svg~*]:pl-7",
  {
    variants: {
      variant: {
        default: "bg-background text-foreground",
        destructive:
          "border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive",
      },
    },
    defaultVariants: {
      variant: "default",
    },
  }
)

const Alert = React.forwardRef(({ className, variant, ...props }, ref) => (
  <div
    ref={ref}
    role="alert"
    className={cn(alertVariants({ variant }), className)}
    {...props} />
))
Alert.displayName = "Alert"

const AlertTitle = React.forwardRef(({ className, ...props }, ref) => (
  <h5
    ref={ref}
    className={cn("mb-1 font-medium leading-none tracking-tight", className)}
    {...props} />
))
AlertTitle.displayName = "AlertTitle"

const AlertDescription = React.forwardRef(({ className, ...props }, ref) => (
  <div
    ref={ref}
    className={cn("text-sm [&_p]:leading-relaxed", className)}
    {...props} />
))
AlertDescription.displayName = "AlertDescription"

export { Alert, AlertTitle, AlertDescription }

Analysis:

Looking at this codebase, I can see several critical issues:

  1. Base44 Dependency: They're using some third-party service called Base44 for client creation and entities. This creates a vendor lock-in and dependency on an external service that might not be reliable.

  2. No TypeScript: Everything is JavaScript with no type safety.

  3. Architecture Issues:

    • Mixed concerns in components

    • No clear separation between data, business logic, and UI

    • Barrel imports that create circular dependencies

    • No testing strategy visible

  4. UI Component Overload: They have 50+ UI components from what looks like shadcn/ui, which is overkill and creates bloat.

  5. No Clear Domain Model: The entities (Document, SearchQuery, ScrapedContent, Report) are just pass-throughs to Base44 entities.

  6. No Python Integration: Despite being called "PyKnowledgeApp", there's no actual Python script execution or management visible.

Now, the user wants to rebuild this as "VibeCodeRehab" with:

  • TypeScript

  • Production ready architecture

  • Python script integration (which aligns with our earlier discussion about the 8 Python automation libraries)

I need to create a comprehensive roadmap that addresses:

  1. The architectural constraints we identified earlier

  2. The execution model (embedded Python + script isolation)

  3. The state management strategy (Event-Sourced State Pods)

  4. The category structure we designed (Scheduled, Reactive, Interactive, Persistent)

  5. TypeScript throughout

  6. Proper testing strategy

  7. Clear separation of concerns

Let me structure this as a constraint-driven roadmap.

Critical Structure Analysis

Fatal Architectural Flaws:

  1. Vendor Lock-in: Base44 dependency creates single point of failure

  2. Type Void: JavaScript everywhere, no contracts, no safety

  3. Component Bloat: 50+ UI components for a script manager

  4. No Python Runtime: "PyKnowledgeApp" with zero Python execution

  5. Mixed Concerns: Data/UI/Logic tangled in every file

The Base44 Problem: External entity management means zero control over data models, performance, or reliability.


VibeCodeRehab: Production Architecture Roadmap

Phase 1: Foundation (Week 1-2)

Core Constraint System

typescript

// Domain contracts first
interface ScriptExecution {
  id: ScriptId;
  status: ExecutionStatus;
  startTime: Timestamp;
  process: ProcessHandle;
  stateSnapshot: StateSnapshot;
}

interface ExecutionStatus {
  type: 'scheduled' | 'reactive' | 'interactive' | 'persistent';
  state: 'pending' | 'running' | 'paused' | 'completed' | 'failed';
  progress?: number;
  lastHeartbeat: Timestamp;
}

Runtime Architecture

VibeCodeRehab/
├── core/
│   ├── python-runtime/     # Embedded Python + dependency management
│   ├── process-manager/    # Script isolation + IPC
│   ├── state-engine/       # Event-sourced state pods
│   └── execution-scheduler/ # Time-based + event-based triggers
├── domain/
│   ├── script-types/       # Scheduled, Reactive, Interactive, Persistent
│   ├── library-templates/  # 8 Python automation libraries
│   └── execution-context/  # Runtime environment contracts
├── infrastructure/
│   ├── sqlite-adapter/     # Local state persistence
│   ├── file-watcher/       # System integration
│   └── process-bridge/     # Python ↔ TypeScript communication
└── interface/
    ├── script-editor/      # Monaco-based editing
    ├── execution-monitor/  # Real-time process dashboard
    └── template-library/   # Pre-built automation scripts

Phase 2: Python Runtime Integration (Week 3-4)

Embedded Python Strategy

typescript

class PythonRuntime {
  private interpreter: EmbeddedPython;
  private dependencyManager: DependencyManager;
  
  async executeScript(script: ScriptDefinition): Promise<ExecutionHandle> {
    // Validate dependencies
    await this.dependencyManager.ensureLibraries(script.dependencies);
    
    // Create isolated process
    const process = await this.createIsolatedProcess(script);
    
    // Setup state pod
    const statePod = new StatePod(script.id);
    
    return new ExecutionHandle(process, statePod);
  }
}

Library Template System

typescript

// Template for schedule library
export const ScheduleTemplate: ScriptTemplate = {
  id: 'schedule-automation',
  category: 'scheduled',
  dependencies: ['schedule', 'time'],
  scaffold: `
import schedule
import time
from vibe_bridge import StatePod, notify_ui

state = StatePod("${scriptId}")

def task_function():
    # User implements this
    pass

schedule.every(${interval}).${unit}.do(task_function)

while True:
    schedule.run_pending()
    time.sleep(1)
  `,
  configSchema: z.object({
    interval: z.number(),
    unit: z.enum(['minutes', 'hours', 'days'])
  })
};

Phase 3: State Management Engine (Week 5)

Event-Sourced State Pods

typescript

class StatePod {
  constructor(private scriptId: string) {
    this.db = new SQLiteAdapter(`state/${scriptId}.db`);
    this.replayEvents();
  }
  
  set<T>(key: string, value: T): void {
    this.state[key] = value;
    this.logEvent('SET', key, value);
    this.notifySubscribers(key, value);
  }
  
  subscribe(key: string, callback: (value: any) => void): void {
    // Inter-script communication
  }
}

Process Communication Bridge

python

# vibe_bridge.py - Injected into every script
class VibeBridge:
    def __init__(self, script_id: str):
        self.script_id = script_id
        self.ipc = IPCChannel(script_id)
    
    def set_state(self, key: str, value: any):
        self.ipc.send('STATE_SET', {'key': key, 'value': value})
    
    def notify_ui(self, message: str, level: str = 'info'):
        self.ipc.send('UI_NOTIFY', {'message': message, 'level': level})

Phase 4: Execution Categories (Week 6-7)

Category-Specific Managers

typescript

class ScheduledExecutionManager {
  private cronJobs: Map<ScriptId, CronJob> = new Map();
  
  schedule(script: ScheduledScript): void {
    const job = new CronJob(script.schedule, () => {
      this.pythonRuntime.executeScript(script);
    });
    this.cronJobs.set(script.id, job);
  }
}

class ReactiveExecutionManager {
  private watchers: Map<ScriptId, FileWatcher> = new Map();
  
  watch(script: ReactiveScript): void {
    const watcher = new FileWatcher(script.watchPath, (event) => {
      this.pythonRuntime.executeScript(script, { event });
    });
    this.watchers.set(script.id, watcher);
  }
}

Phase 5: UI Layer (Week 8-9)

Constraint-Driven UI Architecture

typescript

// No component bloat - purpose-built components only
interface CoreComponents {
  ScriptEditor: MonacoEditorComponent;
  ExecutionMonitor: ProcessDashboardComponent;
  TemplateLibrary: ScriptTemplateComponent;
  StateInspector: StatePodViewerComponent;
}

// Real-time execution monitoring
const ExecutionDashboard: React.FC = () => {
  const executions = useRealtimeExecutions();
  const processes = useProcessMonitor();
  
  return (
    <ProcessGrid>
      {executions.map(exec => (
        <ProcessCard 
          key={exec.id}
          execution={exec}
          onTerminate={() => processManager.terminate(exec.id)}
          onPause={() => processManager.pause(exec.id)}
        />
      ))}
    </ProcessGrid>
  );
};

Phase 6: Production Hardening (Week 10-12)

Testing Strategy

typescript

// Contract testing
describe('PythonRuntime', () => {
  it('should isolate script failures', async () => {
    const badScript = createFailingScript();
    const goodScript = createWorkingScript();
    
    await runtime.execute(badScript);
    const result = await runtime.execute(goodScript);
    
    expect(result.status).toBe('completed');
  });
});

// Integration testing
describe('StatePod', () => {
  it('should survive process crashes', async () => {
    const pod = new StatePod('test-script');
    pod.set('counter', 42);
    
    // Simulate crash
    pod.destroy();
    
    const newPod = new StatePod('test-script');
    expect(newPod.get('counter')).toBe(42);
  });
});

Error Recovery System

typescript

class ExecutionRecoveryManager {
  async recoverFromCrash(scriptId: ScriptId): Promise<void> {
    const lastState = await this.stateEngine.getLastSnapshot(scriptId);
    const script = await this.scriptManager.getScript(scriptId);
    
    // Restart with recovered state
    await this.pythonRuntime.executeScript(script, { 
      initialState: lastState 
    });
  }
}

Core Principles Enforced:

  1. Type Safety: TypeScript contracts for everything

  2. Fault Isolation: Script failures don't cascade

  3. State Persistence: Survives crashes and restarts

  4. Real-time Monitoring: Live execution feedback

  5. Dependency Management: Embedded Python with controlled libraries

  6. Template-Driven: Pre-built automation patterns

  7. Testing from Day 1: Contract and integration tests

Timeline: 12 weeks to production-ready Python automation platform.

Next Step: Define the core domain contracts and start with the PythonRuntime foundation.

The user wants me to continue with the next step, which I mentioned was "Define the core domain contracts and start with the PythonRuntime foundation." I should now provide concrete TypeScript domain contracts and begin architecting the PythonRuntime foundation.

Let me think about what the core domain contracts should include:

  1. Core domain entities

  2. Script execution contracts

  3. State management contracts

  4. Process management contracts

  5. Library template contracts

Then I'll start designing the PythonRuntime foundation with the embedded interpreter approach we agreed on.

I should be systematic and architecture-driven as per the user's preferences, focusing on constraints and leverage points.

// =============================================
// CORE DOMAIN CONTRACTS
// =============================================

// Base types
export type ScriptId = string & { readonly brand: unique symbol };
export type ProcessId = string & { readonly brand: unique symbol };
export type Timestamp = number & { readonly brand: unique symbol };

// Script Categories - Execution Pattern Based
export type ScriptCategory = 'scheduled' | 'reactive' | 'interactive' | 'persistent';

export type ExecutionState = 
  | 'pending'    // Queued for execution
  | 'starting'   // Process initialization
  | 'running'    // Active execution
  | 'paused'     // Temporarily suspended
  | 'completed'  // Finished successfully
  | 'failed'     // Execution error
  | 'terminated' // User/system killed
  | 'recovering'; // Crash recovery in progress

// Python Library Dependencies
export interface LibraryDependency {
  readonly name: string;
  readonly version: string;
  readonly systemDeps?: string[]; // tesseract, audio drivers, etc.
  readonly installCommand?: string;
}

// Script Definition Contract
export interface ScriptDefinition {
  readonly id: ScriptId;
  readonly name: string;
  readonly category: ScriptCategory;
  readonly code: string;
  readonly dependencies: readonly LibraryDependency[];
  readonly config: ScriptConfig;
  readonly metadata: ScriptMetadata;
}

export interface ScriptConfig {
  readonly timeout?: number; // milliseconds
  readonly memory?: number;  // MB limit
  readonly restart?: boolean; // auto-restart on failure
  readonly schedule?: ScheduleConfig;
  readonly watchPaths?: string[]; // for reactive scripts
}

export interface ScheduleConfig {
  readonly type: 'cron' | 'interval';
  readonly expression: string; // cron or interval expression
  readonly timezone?: string;
}

export interface ScriptMetadata {
  readonly author: string;
  readonly description: string;
  readonly tags: readonly string[];
  readonly created: Timestamp;
  readonly modified: Timestamp;
  readonly version: string;
}

// =============================================
// EXECUTION CONTRACTS
// =============================================

export interface ExecutionContext {
  readonly scriptId: ScriptId;
  readonly processId: ProcessId;
  readonly category: ScriptCategory;
  readonly startTime: Timestamp;
  readonly environment: ExecutionEnvironment;
  readonly statePod: StatePodHandle;
}

export interface ExecutionEnvironment {
  readonly pythonVersion: string;
  readonly workingDirectory: string;
  readonly environmentVars: Record<string, string>;
  readonly resourceLimits: ResourceLimits;
}

export interface ResourceLimits {
  readonly maxMemory: number; // MB
  readonly maxCpu: number;    // percentage
  readonly maxDuration: number; // milliseconds
}

export interface ExecutionResult {
  readonly scriptId: ScriptId;
  readonly processId: ProcessId;
  readonly status: ExecutionState;
  readonly startTime: Timestamp;
  readonly endTime?: Timestamp;
  readonly exitCode?: number;
  readonly stdout: string;
  readonly stderr: string;
  readonly metrics: ExecutionMetrics;
}

export interface ExecutionMetrics {
  readonly memoryPeak: number;
  readonly cpuTime: number;
  readonly duration: number;
  readonly stateChanges: number;
}

// =============================================
// STATE MANAGEMENT CONTRACTS
// =============================================

export interface StatePodHandle {
  readonly scriptId: ScriptId;
  get<T>(key: string): Promise<T | undefined>;
  set<T>(key: string, value: T): Promise<void>;
  delete(key: string): Promise<void>;
  subscribe<T>(key: string, callback: (value: T) => void): () => void;
  getHistory(key: string): Promise<StateEvent[]>;
  createSnapshot(): Promise<StateSnapshot>;
  restoreFromSnapshot(snapshot: StateSnapshot): Promise<void>;
}

export interface StateEvent {
  readonly timestamp: Timestamp;
  readonly action: 'SET' | 'DELETE' | 'SNAPSHOT';
  readonly key: string;
  readonly value?: unknown;
  readonly metadata?: Record<string, unknown>;
}

export interface StateSnapshot {
  readonly scriptId: ScriptId;
  readonly timestamp: Timestamp;
  readonly state: Record<string, unknown>;
  readonly checksum: string;
}

// =============================================
// PROCESS MANAGEMENT CONTRACTS
// =============================================

export interface ProcessHandle {
  readonly processId: ProcessId;
  readonly scriptId: ScriptId;
  readonly pid: number;
  readonly status: ExecutionState;
  
  pause(): Promise<void>;
  resume(): Promise<void>;
  terminate(): Promise<void>;
  getMetrics(): Promise<ProcessMetrics>;
  sendSignal(signal: string): Promise<void>;
}

export interface ProcessMetrics {
  readonly memoryUsage: number;
  readonly cpuUsage: number;
  readonly uptime: number;
  readonly lastHeartbeat: Timestamp;
}

// =============================================
// TEMPLATE SYSTEM CONTRACTS
// =============================================

export interface ScriptTemplate {
  readonly id: string;
  readonly name: string;
  readonly category: ScriptCategory;
  readonly description: string;
  readonly dependencies: readonly LibraryDependency[];
  readonly scaffold: string; // Python code template
  readonly configSchema: unknown; // Zod schema
  readonly examples: readonly TemplateExample[];
}

export interface TemplateExample {
  readonly name: string;
  readonly description: string;
  readonly config: unknown;
  readonly expectedOutput: string;
}

// =============================================
// EVENT SYSTEM CONTRACTS
// =============================================

export type SystemEvent = 
  | ScriptExecutionEvent
  | ProcessLifecycleEvent
  | StateChangeEvent
  | SystemHealthEvent;

export interface ScriptExecutionEvent {
  readonly type: 'script.execution';
  readonly scriptId: ScriptId;
  readonly processId: ProcessId;
  readonly state: ExecutionState;
  readonly timestamp: Timestamp;
  readonly metadata?: Record<string, unknown>;
}

export interface ProcessLifecycleEvent {
  readonly type: 'process.lifecycle';
  readonly processId: ProcessId;
  readonly action: 'created' | 'started' | 'paused' | 'resumed' | 'terminated';
  readonly timestamp: Timestamp;
}

export interface StateChangeEvent {
  readonly type: 'state.change';
  readonly scriptId: ScriptId;
  readonly key: string;
  readonly oldValue?: unknown;
  readonly newValue?: unknown;
  readonly timestamp: Timestamp;
}

export interface SystemHealthEvent {
  readonly type: 'system.health';
  readonly component: string;
  readonly status: 'healthy' | 'degraded' | 'unhealthy';
  readonly message: string;
  readonly timestamp: Timestamp;
}

// =============================================
// ERROR HANDLING CONTRACTS
// =============================================

export abstract class VibeCodeError extends Error {
  abstract readonly code: string;
  abstract readonly category: 'user' | 'system' | 'dependency';
  abstract readonly recoverable: boolean;
}

export class ScriptExecutionError extends VibeCodeError {
  readonly code = 'SCRIPT_EXECUTION_FAILED';
  readonly category = 'user';
  readonly recoverable = true;
  
  constructor(
    public readonly scriptId: ScriptId,
    public readonly exitCode: number,
    public readonly stderr: string,
    message: string
  ) {
    super(message);
  }
}

export class DependencyMissingError extends VibeCodeError {
  readonly code = 'DEPENDENCY_MISSING';
  readonly category = 'dependency';
  readonly recoverable = true;
  
  constructor(
    public readonly dependency: LibraryDependency,
    message: string
  ) {
    super(message);
  }
}

export class ResourceExhaustedError extends VibeCodeError {
  readonly code = 'RESOURCE_EXHAUSTED';
  readonly category = 'system';
  readonly recoverable = false;
  
  constructor(
    public readonly resource: 'memory' | 'cpu' | 'disk',
    public readonly limit: number,
    public readonly actual: number,
    message: string
  ) {
    super(message);
  }
}

// =============================================
// PYTHON RUNTIME FOUNDATION
// =============================================

import { ChildProcess, spawn } from 'child_process';
import { join, resolve } from 'path';
import { createWriteStream, existsSync, mkdirSync } from 'fs';
import { 
  ScriptDefinition, 
  ExecutionContext, 
  ExecutionResult, 
  ProcessHandle,
  LibraryDependency,
  ScriptId,
  ProcessId,
  ExecutionState,
  VibeCodeError 
} from './domain-contracts';

// =============================================
// EMBEDDED PYTHON INTERPRETER
// =============================================

export class EmbeddedPythonInterpreter {
  private readonly pythonPath: string;
  private readonly sitePackages: string;
  private readonly initialized: boolean = false;

  constructor(private readonly config: PythonConfig) {
    this.pythonPath = resolve(config.runtimePath, 'python');
    this.sitePackages = resolve(config.runtimePath, 'lib', 'site-packages');
  }

  async initialize(): Promise<void> {
    if (this.initialized) return;

    // Verify embedded Python exists
    if (!existsSync(this.pythonPath)) {
      throw new PythonRuntimeError(
        'RUNTIME_MISSING',
        `Embedded Python not found at ${this.pythonPath}`
      );
    }

    // Verify basic functionality
    await this.verifyInstallation();
    
    // Install vibe-bridge module
    await this.installVibeBridge();
    
    this.initialized = true;
  }

  private async verifyInstallation(): Promise<void> {
    return new Promise((resolve, reject) => {
      const proc = spawn(this.pythonPath, ['-c', 'import sys; print(sys.version)'], {
        stdio: 'pipe'
      });

      proc.on('exit', (code) => {
        if (code === 0) {
          resolve();
        } else {
          reject(new PythonRuntimeError(
            'RUNTIME_BROKEN',
            'Embedded Python verification failed'
          ));
        }
      });
    });
  }

  private async installVibeBridge(): Promise<void> {
    // Install our custom bridge module that handles IPC
    const bridgeSource = this.generateVibeBridgeModule();
    const bridgePath = join(this.sitePackages, 'vibe_bridge.py');
    
    await require('fs/promises').writeFile(bridgePath, bridgeSource);
  }

  private generateVibeBridgeModule(): string {
    return `
"""
VibeCodeRehab Python Bridge
Handles communication between Python scripts and TypeScript runtime
"""
import json
import sys
import os
from typing import Any, Optional, Callable
from datetime import datetime

class VibeBridge:
    def __init__(self, script_id: str):
        self.script_id = script_id
        self.ipc_path = os.environ.get('VIBE_IPC_PATH', '/tmp/vibe_ipc')
        self._heartbeat_interval = 5  # seconds
        
    def set_state(self, key: str, value: Any) -> None:
        """Set state that persists across script restarts"""
        self._send_ipc('STATE_SET', {'key': key, 'value': value})
    
    def get_state(self, key: str, default: Any = None) -> Any:
        """Get persistent state value"""
        response = self._send_ipc('STATE_GET', {'key': key})
        return response.get('value', default)
    
    def notify_ui(self, message: str, level: str = 'info') -> None:
        """Send notification to UI"""
        self._send_ipc('UI_NOTIFY', {
            'message': message, 
            'level': level,
            'timestamp': datetime.now().isoformat()
        })
    
    def log_progress(self, current: int, total: int, message: str = '') -> None:
        """Report execution progress"""
        progress = (current / total) * 100 if total > 0 else 0
        self._send_ipc('PROGRESS_UPDATE', {
            'current': current,
            'total': total,
            'percentage': progress,
            'message': message
        })
    
    def heartbeat(self) -> None:
        """Send heartbeat to indicate script is alive"""
        self._send_ipc('HEARTBEAT', {'timestamp': datetime.now().isoformat()})
    
    def _send_ipc(self, command: str, data: dict) -> dict:
        """Send IPC message to TypeScript runtime"""
        message = {
            'script_id': self.script_id,
            'command': command,
            'data': data,
            'timestamp': datetime.now().isoformat()
        }
        
        # Write to stdout in structured format for IPC
        print(f"__VIBE_IPC__{json.dumps(message)}__END_IPC__", flush=True)
        
        # For GET operations, we'd need to implement response handling
        # This is a simplified version
        return {}

# Global bridge instance - initialized by runtime
bridge: Optional[VibeBridge] = None

def init_bridge(script_id: str) -> VibeBridge:
    global bridge
    bridge = VibeBridge(script_id)
    return bridge

def get_bridge() -> VibeBridge:
    if bridge is None:
        raise RuntimeError("VibeBridge not initialized. Call init_bridge() first.")
    return bridge
`;
  }

  getExecutablePath(): string {
    return this.pythonPath;
  }

  getSitePackagesPath(): string {
    return this.sitePackages;
  }
}

// =============================================
// DEPENDENCY MANAGER
// =============================================

export class DependencyManager {
  constructor(
    private readonly interpreter: EmbeddedPythonInterpreter,
    private readonly cache: DependencyCache
  ) {}

  async ensureDependencies(dependencies: readonly LibraryDependency[]): Promise<void> {
    const missing = await this.findMissingDependencies(dependencies);
    
    if (missing.length > 0) {
      await this.installDependencies(missing);
    }

    // Verify all dependencies are working
    await this.verifyDependencies(dependencies);
  }

  private async findMissingDependencies(
    dependencies: readonly LibraryDependency[]
  ): Promise<LibraryDependency[]> {
    const missing: LibraryDependency[] = [];

    for (const dep of dependencies) {
      const isInstalled = await this.isDependencyInstalled(dep);
      if (!isInstalled) {
        missing.push(dep);
      }
    }

    return missing;
  }

  private async isDependencyInstalled(dep: LibraryDependency): Promise<boolean> {
    return new Promise((resolve) => {
      const proc = spawn(this.interpreter.getExecutablePath(), [
        '-c', 
        `import ${dep.name}; print('${dep.name} installed')`
      ], { stdio: 'pipe' });

      proc.on('exit', (code) => {
        resolve(code === 0);
      });
    });
  }

  private async installDependencies(dependencies: LibraryDependency[]): Promise<void> {
    for (const dep of dependencies) {
      await this.installSingleDependency(dep);
    }
  }

  private async installSingleDependency(dep: LibraryDependency): Promise<void> {
    // Check cache first
    if (await this.cache.has(dep)) {
      await this.cache.install(dep, this.interpreter.getSitePackagesPath());
      return;
    }

    // Install using pip
    const pipArgs = ['pip', 'install', `${dep.name}==${dep.version}`];
    
    return new Promise((resolve, reject) => {
      const proc = spawn(this.interpreter.getExecutablePath(), pipArgs, {
        stdio: 'pipe'
      });

      let stderr = '';
      proc.stderr?.on('data', (data) => {
        stderr += data.toString();
      });

      proc.on('exit', async (code) => {
        if (code === 0) {
          // Cache successful installation
          await this.cache.store(dep, this.interpreter.getSitePackagesPath());
          resolve();
        } else {
          reject(new DependencyInstallError(dep, stderr));
        }
      });
    });
  }

  private async verifyDependencies(dependencies: readonly LibraryDependency[]): Promise<void> {
    // Verify all dependencies can be imported together
    const importStatements = dependencies
      .map(dep => `import ${dep.name}`)
      .join('; ');

    return new Promise((resolve, reject) => {
      const proc = spawn(this.interpreter.getExecutablePath(), [
        '-c', 
        importStatements
      ], { stdio: 'pipe' });

      proc.on('exit', (code) => {
        if (code === 0) {
          resolve();
        } else {
          reject(new DependencyConflictError(dependencies));
        }
      });
    });
  }
}

// =============================================
// PROCESS MANAGER
// =============================================

export class ProcessManager {
  private readonly activeProcesses = new Map<ProcessId, ProcessHandle>();
  private readonly processCounter = new ProcessCounter();

  async createProcess(
    script: ScriptDefinition,
    context: ExecutionContext
  ): Promise<ProcessHandle> {
    const processId = this.processCounter.next();
    
    // Prepare execution environment
    const env = this.prepareEnvironment(script, context);
    const scriptPath = await this.writeScriptToFile(script, context);
    
    // Create Python process
    const childProcess = spawn(
      context.environment.pythonPath || 'python',
      [scriptPath],
      {
        env,
        stdio: ['pipe', 'pipe', 'pipe'],
        cwd: context.environment.workingDirectory
      }
    );

    // Create process handle
    const handle = new PythonProcessHandle(
      processId,
      script.id,
      childProcess,
      context
    );

    this.activeProcesses.set(processId, handle);

    // Setup cleanup on exit
    childProcess.on('exit', () => {
      this.activeProcesses.delete(processId);
    });

    return handle;
  }

  private prepareEnvironment(
    script: ScriptDefinition, 
    context: ExecutionContext
  ): NodeJS.ProcessEnv {
    return {
      ...process.env,
      ...context.environment.environmentVars,
      VIBE_SCRIPT_ID: script.id,
      VIBE_PROCESS_ID: context.processId,
      VIBE_IPC_PATH: this.getIPCPath(context.processId),
      PYTHONPATH: context.environment.pythonPath
    };
  }

  private async writeScriptToFile(
    script: ScriptDefinition,
    context: ExecutionContext
  ): Promise<string> {
    const scriptDir = join(context.environment.workingDirectory, 'scripts');
    const scriptPath = join(scriptDir, `${script.id}.py`);

    if (!existsSync(scriptDir)) {
      mkdirSync(scriptDir, { recursive: true });
    }

    // Inject bridge initialization
    const wrappedScript = this.wrapScriptWithBridge(script);
    
    await require('fs/promises').writeFile(scriptPath, wrappedScript);
    return scriptPath;
  }

  private wrapScriptWithBridge(script: ScriptDefinition): string {
    return `
# VibeCodeRehab Runtime Injection
import os
import sys
from vibe_bridge import init_bridge

# Initialize bridge
script_id = os.environ.get('VIBE_SCRIPT_ID')
bridge = init_bridge(script_id)

# User script begins here
${script.code}
`;
  }

  private getIPCPath(processId: ProcessId): string {
    return join(os.tmpdir(), `vibe_ipc_${processId}`);
  }

  getActiveProcesses(): ProcessHandle[] {
    return Array.from(this.activeProcesses.values());
  }

  getProcess(processId: ProcessId): ProcessHandle | undefined {
    return this.activeProcesses.get(processId);
  }
}

// =============================================
// PYTHON PROCESS HANDLE
// =============================================

class PythonProcessHandle implements ProcessHandle {
  private _status: ExecutionState = 'starting';

  constructor(
    public readonly processId: ProcessId,
    public readonly scriptId: ScriptId,
    private readonly childProcess: ChildProcess,
    private readonly context: ExecutionContext
  ) {
    this.setupProcessMonitoring();
  }

  get status(): ExecutionState {
    return this._status;
  }

  get pid(): number {
    return this.childProcess.pid!;
  }

  async pause(): Promise<void> {
    this.childProcess.kill('SIGSTOP');
    this._status = 'paused';
  }

  async resume(): Promise<void> {
    this.childProcess.kill('SIGCONT');
    this._status = 'running';
  }

  async terminate(): Promise<void> {
    this.childProcess.kill('SIGTERM');
    this._status = 'terminated';
  }

  async getMetrics(): Promise<ProcessMetrics> {
    // Implementation would query system metrics
    return {
      memoryUsage: 0,
      cpuUsage: 0,
      uptime: Date.now() - this.context.startTime,
      lastHeartbeat: Date.now() as Timestamp
    };
  }

  async sendSignal(signal: string): Promise<void> {
    this.childProcess.kill(signal);
  }

  private setupProcessMonitoring(): void {
    this.childProcess.stdout?.on('data', (data) => {
      this.handleStdout(data.toString());
    });

    this.childProcess.stderr?.on('data', (data) => {
      this.handleStderr(data.toString());
    });

    this.childProcess.on('exit', (code, signal) => {
      this.handleExit(code, signal);
    });
  }

  private handleStdout(data: string): void {
    // Parse IPC messages from stdout
    const ipcRegex = /__VIBE_IPC__(.+?)__END_IPC__/g;
    let match;

    while ((match = ipcRegex.exec(data)) !== null) {
      try {
        const message = JSON.parse(match[1]);
        this.handleIPCMessage(message);
      } catch (error) {
        console.error('Failed to parse IPC message:', error);
      }
    }

    // Regular stdout (after removing IPC messages)
    const cleanOutput = data.replace(ipcRegex, '');
    if (cleanOutput.trim()) {
      // Emit stdout event
      this.emit('stdout', cleanOutput);
    }
  }

  private handleStderr(data: string): void {
    this.emit('stderr', data);
  }

  private handleExit(code: number | null, signal: string | null): void {
    if (code === 0) {
      this._status = 'completed';
    } else {
      this._status = 'failed';
    }
    
    this.emit('exit', { code, signal });
  }

  private handleIPCMessage(message: any): void {
    switch (message.command) {
      case 'STATE_SET':
        this.context.statePod.set(message.data.key, message.data.value);
        break;
      case 'UI_NOTIFY':
        this.emit('notification', message.data);
        break;
      case 'PROGRESS_UPDATE':
        this.emit('progress', message.data);
        break;
      case 'HEARTBEAT':
        this.emit('heartbeat', message.data);
        break;
    }
  }

  private emit(event: string, data: any): void {
    // EventEmitter implementation
    // This would integrate with the broader event system
  }
}

// =============================================
// SUPPORTING TYPES AND CLASSES
// =============================================

interface PythonConfig {
  runtimePath: string;
  sitePackagesPath?: string;
  version: string;
}

interface DependencyCache {
  has(dep: LibraryDependency): Promise<boolean>;
  store(dep: LibraryDependency, sourcePath: string): Promise<void>;
  install(dep: LibraryDependency, targetPath: string): Promise<void>;
}

class ProcessCounter {
  private counter = 0;
  
  next(): ProcessId {
    return `proc_${++this.counter}` as ProcessId;
  }
}

// =============================================
// ERROR CLASSES
// =============================================

class PythonRuntimeError extends VibeCodeError {
  readonly category = 'system';
  readonly recoverable = false;
  
  constructor(
    public readonly code: string,
    message: string
  ) {
    super(message);
  }
}

class DependencyInstallError extends VibeCodeError {
  readonly code = 'DEPENDENCY_INSTALL_FAILED';
  readonly category = 'dependency';
  readonly recoverable = true;
  
  constructor(
    public readonly dependency: LibraryDependency,
    public readonly installError: string
  ) {
    super(`Failed to install ${dependency.name}: ${installError}`);
  }
}

class DependencyConflictError extends VibeCodeError {
  readonly code = 'DEPENDENCY_CONFLICT';
  readonly category = 'dependency';
  readonly recoverable = true;
  
  constructor(
    public readonly dependencies: readonly LibraryDependency[]
  ) {
    super(`Dependency conflict detected among: ${dependencies.map(d => d.name).join(', ')}`);
  }
}

// =============================================
// EXECUTION ENGINE - ORCHESTRATION LAYER
// =============================================

import { EventEmitter } from 'events';
import { resolve, join } from 'path';
import { 
  ScriptDefinition, 
  ExecutionContext, 
  ExecutionResult,
  ProcessHandle,
  ScriptId,
  ProcessId,
  Timestamp,
  ExecutionState,
  StatePodHandle,
  StateSnapshot,
  SystemEvent,
  ScriptCategory
} from './domain-contracts';
import { 
  EmbeddedPythonInterpreter, 
  DependencyManager, 
  ProcessManager 
} from './python-runtime';

// =============================================
// MAIN EXECUTION ENGINE
// =============================================

export class ExecutionEngine extends EventEmitter {
  private readonly pythonInterpreter: EmbeddedPythonInterpreter;
  private readonly dependencyManager: DependencyManager;
  private readonly processManager: ProcessManager;
  private readonly stateEngine: StateEngine;
  private readonly categoryManagers: Map<ScriptCategory, CategoryExecutionManager>;

  constructor(config: ExecutionEngineConfig) {
    super();
    
    this.pythonInterpreter = new EmbeddedPythonInterpreter(config.python);
    this.dependencyManager = new DependencyManager(
      this.pythonInterpreter, 
      config.dependencyCache
    );
    this.processManager = new ProcessManager();
    this.stateEngine = new StateEngine(config.database);
    
    // Initialize category-specific execution managers
    this.categoryManagers = new Map([
      ['scheduled', new ScheduledExecutionManager(this)],
      ['reactive', new ReactiveExecutionManager(this)],
      ['interactive', new InteractiveExecutionManager(this)],
      ['persistent', new PersistentExecutionManager(this)]
    ]);
  }

  async initialize(): Promise<void> {
    // Initialize core components
    await this.pythonInterpreter.initialize();
    await this.stateEngine.initialize();
    
    // Initialize category managers
    for (const manager of this.categoryManagers.values()) {
      await manager.initialize();
    }

    this.emit('system.ready');
  }

  async executeScript(script: ScriptDefinition): Promise<ExecutionResult> {
    const executionId = this.generateExecutionId();
    
    try {
      // Pre-execution validation
      await this.validateScript(script);
      
      // Ensure dependencies
      await this.dependencyManager.ensureDependencies(script.dependencies);
      
      // Get category-specific manager
      const categoryManager = this.categoryManagers.get(script.category);
      if (!categoryManager) {
        throw new Error(`No manager for category: ${script.category}`);
      }

      // Execute via category manager
      const result = await categoryManager.execute(script, executionId);
      
      this.emit('script.execution', {
        type: 'script.execution',
        scriptId: script.id,
        processId: result.processId,
        state: result.status,
        timestamp: Date.now() as Timestamp
      } as SystemEvent);

      return result;

    } catch (error) {
      this.emit('script.error', {
        type: 'script.execution',
        scriptId: script.id,
        processId: executionId,
        state: 'failed',
        timestamp: Date.now() as Timestamp,
        metadata: { error: error.message }
      } as SystemEvent);

      throw error;
    }
  }

  async scheduleScript(script: ScriptDefinition): Promise<void> {
    if (script.category !== 'scheduled') {
      throw new Error('Only scheduled scripts can be scheduled');
    }

    const manager = this.categoryManagers.get('scheduled') as ScheduledExecutionManager;
    await manager.schedule(script);
  }

  async startReactiveScript(script: ScriptDefinition): Promise<void> {
    if (script.category !== 'reactive') {
      throw new Error('Only reactive scripts can be started as reactive');
    }

    const manager = this.categoryManagers.get('reactive') as ReactiveExecutionManager;
    await manager.startWatching(script);
  }

  async getExecutionStatus(processId: ProcessId): Promise<ExecutionState> {
    const process = this.processManager.getProcess(processId);
    return process?.status || 'failed';
  }

  async getActiveExecutions(): Promise<ProcessHandle[]> {
    return this.processManager.getActiveProcesses();
  }

  async recoverFromCrash(scriptId: ScriptId): Promise<void> {
    const script = await this.getScript(scriptId);
    const lastSnapshot = await this.stateEngine.getLastSnapshot(scriptId);
    
    if (lastSnapshot) {
      // Restart with recovered state
      const context = await this.createExecutionContext(script, lastSnapshot);
      await this.executeScript(script);
    }
  }

  private async validateScript(script: ScriptDefinition): Promise<void> {
    // Syntax validation
    if (!script.code.trim()) {
      throw new Error('Script code cannot be empty');
    }

    // Category-specific validation
    const manager = this.categoryManagers.get(script.category);
    if (manager && manager.validateScript) {
      await manager.validateScript(script);
    }
  }

  private generateExecutionId(): ProcessId {
    return `exec_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` as ProcessId;
  }

  private async createExecutionContext(
    script: ScriptDefinition, 
    stateSnapshot?: StateSnapshot
  ): Promise<ExecutionContext> {
    const processId = this.generateExecutionId();
    const statePod = await this.stateEngine.createStatePod(script.id);
    
    if (stateSnapshot) {
      await statePod.restoreFromSnapshot(stateSnapshot);
    }

    return {
      scriptId: script.id,
      processId,
      category: script.category,
      startTime: Date.now() as Timestamp,
      environment: {
        pythonVersion: '3.11',
        workingDirectory: resolve('./runtime/workspace'),
        environmentVars: {},
        resourceLimits: {
          maxMemory: script.config.memory || 512,
          maxCpu: 80,
          maxDuration: script.config.timeout || 300000
        }
      },
      statePod
    };
  }

  private async getScript(scriptId: ScriptId): Promise<ScriptDefinition> {
    // This would integrate with script storage
    throw new Error('Script storage not implemented');
  }
}

// =============================================
// STATE ENGINE - EVENT SOURCED PERSISTENCE
// =============================================

export class StateEngine {
  private readonly statePods = new Map<ScriptId, StatePodImplementation>();

  constructor(private readonly database: StateDatabase) {}

  async initialize(): Promise<void> {
    await this.database.initialize();
  }

  async createStatePod(scriptId: ScriptId): Promise<StatePodHandle> {
    if (this.statePods.has(scriptId)) {
      return this.statePods.get(scriptId)!;
    }

    const pod = new StatePodImplementation(scriptId, this.database);
    await pod.initialize();
    
    this.statePods.set(scriptId, pod);
    return pod;
  }

  async getLastSnapshot(scriptId: ScriptId): Promise<StateSnapshot | undefined> {
    return this.database.getLastSnapshot(scriptId);
  }

  async cleanupOldStates(maxAge: number): Promise<void> {
    const cutoff = Date.now() - maxAge;
    await this.database.deleteEventsBefore(cutoff as Timestamp);
  }
}

class StatePodImplementation implements StatePodHandle {
  private state: Map<string, unknown> = new Map();
  private subscribers: Map<string, Set<(value: unknown) => void>> = new Map();

  constructor(
    public readonly scriptId: ScriptId,
    private readonly database: StateDatabase
  ) {}

  async initialize(): Promise<void> {
    // Replay events to rebuild state
    const events = await this.database.getEvents(this.scriptId);
    for (const event of events) {
      this.applyEvent(event);
    }
  }

  async get<T>(key: string): Promise<T | undefined> {
    return this.state.get(key) as T | undefined;
  }

  async set<T>(key: string, value: T): Promise<void> {
    const oldValue = this.state.get(key);
    this.state.set(key, value);

    // Log event
    await this.database.logEvent({
      timestamp: Date.now() as Timestamp,
      action: 'SET',
      key,
      value,
      metadata: { scriptId: this.scriptId }
    });

    // Notify subscribers
    const keySubscribers = this.subscribers.get(key);
    if (keySubscribers) {
      for (const callback of keySubscribers) {
        callback(value);
      }
    }
  }

  async delete(key: string): Promise<void> {
    this.state.delete(key);

    await this.database.logEvent({
      timestamp: Date.now() as Timestamp,
      action: 'DELETE',
      key,
      metadata: { scriptId: this.scriptId }
    });
  }

  subscribe<T>(key: string, callback: (value: T) => void): () => void {
    if (!this.subscribers.has(key)) {
      this.subscribers.set(key, new Set());
    }
    
    this.subscribers.get(key)!.add(callback as (value: unknown) => void);
    
    // Return unsubscribe function
    return () => {
      this.subscribers.get(key)?.delete(callback as (value: unknown) => void);
    };
  }

  async getHistory(key: string): Promise<StateEvent[]> {
    return this.database.getEventsForKey(this.scriptId, key);
  }

  async createSnapshot(): Promise<StateSnapshot> {
    const snapshot: StateSnapshot = {
      scriptId: this.scriptId,
      timestamp: Date.now() as Timestamp,
      state: Object.fromEntries(this.state),
      checksum: this.calculateChecksum()
    };

    await this.database.saveSnapshot(snapshot);
    return snapshot;
  }

  async restoreFromSnapshot(snapshot: StateSnapshot): Promise<void> {
    this.state.clear();
    for (const [key, value] of Object.entries(snapshot.state)) {
      this.state.set(key, value);
    }
  }

  private applyEvent(event: StateEvent): void {
    switch (event.action) {
      case 'SET':
        this.state.set(event.key, event.value);
        break;
      case 'DELETE':
        this.state.delete(event.key);
        break;
    }
  }

  private calculateChecksum(): string {
    // Simple checksum implementation
    const stateString = JSON.stringify(Object.fromEntries(this.state));
    return require('crypto').createHash('md5').update(stateString).digest('hex');
  }
}

// =============================================
// CATEGORY-SPECIFIC EXECUTION MANAGERS
// =============================================

abstract class CategoryExecutionManager {
  constructor(protected executionEngine: ExecutionEngine) {}

  abstract initialize(): Promise<void>;
  abstract execute(script: ScriptDefinition, executionId: ProcessId): Promise<ExecutionResult>;
  
  validateScript?(script: ScriptDefinition): Promise<void>;
}

class ScheduledExecutionManager extends CategoryExecutionManager {
  private scheduledJobs = new Map<ScriptId, NodeJS.Timeout>();

  async initialize(): Promise<void> {
    // Restore scheduled jobs from database
  }

  async execute(script: ScriptDefinition, executionId: ProcessId): Promise<ExecutionResult> {
    // Direct execution for scheduled scripts
    const context = await this.createContext(script, executionId);
    const process = await this.executionEngine['processManager'].createProcess(script, context);
    
    return new Promise((resolve) => {
      process.on('exit', ({ code }: { code: number }) => {
        resolve({
          scriptId: script.id,
          processId: executionId,
          status: code === 0 ? 'completed' : 'failed',
          startTime: context.startTime,
          endTime: Date.now() as Timestamp,
          exitCode: code,
          stdout: '',
          stderr: '',
          metrics: {
            memoryPeak: 0,
            cpuTime: 0,
            duration: Date.now() - context.startTime,
            stateChanges: 0
          }
        });
      });
    });
  }

  async schedule(script: ScriptDefinition): Promise<void> {
    if (!script.config.schedule) {
      throw new Error('Scheduled script must have schedule configuration');
    }

    const interval = this.parseSchedule(script.config.schedule.expression);
    
    const job = setInterval(async () => {
      try {
        await this.execute(script, this.generateExecutionId());
      } catch (error) {
        console.error(`Scheduled execution failed for ${script.id}:`, error);
      }
    }, interval);

    this.scheduledJobs.set(script.id, job);
  }

  private parseSchedule(expression: string): number {
    // Simple interval parsing - would be more sophisticated in production
    const match = expression.match(/(\d+)\s*(minutes?|hours?|days?)/);
    if (!match) throw new Error('Invalid schedule expression');
    
    const value = parseInt(match[1]);
    const unit = match[2];
    
    switch (unit) {
      case 'minute':
      case 'minutes':
        return value * 60 * 1000;
      case 'hour':
      case 'hours':
        return value * 60 * 60 * 1000;
      case 'day':
      case 'days':
        return value * 24 * 60 * 60 * 1000;
      default:
        throw new Error('Unsupported time unit');
    }
  }

  private async createContext(script: ScriptDefinition, processId: ProcessId): Promise<ExecutionContext> {
    // Implementation would be shared with main execution engine
    throw new Error('Context creation not implemented');
  }

  private generateExecutionId(): ProcessId {
    return `sched_${Date.now()}` as ProcessId;
  }
}

class ReactiveExecutionManager extends CategoryExecutionManager {
  private watchers = new Map<ScriptId, any>();

  async initialize(): Promise<void> {
    // Initialize file system watchers
  }

  async execute(script: ScriptDefinition, executionId: ProcessId): Promise<ExecutionResult> {
    // Reactive scripts are triggered by events, not direct execution
    throw new Error('Reactive scripts cannot be executed directly');
  }

  async startWatching(script: ScriptDefinition): Promise<void> {
    if (!script.config.watchPaths) {
      throw new Error('Reactive script must have watch paths configured');
    }

    // Implementation would use chokidar or similar
    // For brevity, using a placeholder
    console.log(`Starting to watch ${script.config.watchPaths} for ${script.id}`);
  }
}

class InteractiveExecutionManager extends CategoryExecutionManager {
  async initialize(): Promise<void> {
    // No special initialization needed
  }

  async execute(script: ScriptDefinition, executionId: ProcessId): Promise<ExecutionResult> {
    // Interactive scripts run once and return results
    const context = await this.createContext(script, executionId);
    const process = await this.executionEngine['processManager'].createProcess(script, context);
    
    return this.waitForCompletion(process, context);
  }

  private async createContext(script: ScriptDefinition, processId: ProcessId): Promise<ExecutionContext> {
    // Implementation details
    throw new Error('Context creation not implemented');
  }

  private async waitForCompletion(process: ProcessHandle, context: ExecutionContext): Promise<ExecutionResult> {
    // Implementation details
    throw new Error('Completion waiting not implemented');
  }
}

class PersistentExecutionManager extends CategoryExecutionManager {
  async initialize(): Promise<void> {
    // Restore persistent scripts that should be running
  }

  async execute(script: ScriptDefinition, executionId: ProcessId): Promise<ExecutionResult> {
    // Persistent scripts run indefinitely
    const context = await this.createContext(script, executionId);
    const process = await this.executionEngine['processManager'].createProcess(script, context);
    
    // Don't wait for completion - return immediately
    return {
      scriptId: script.id,
      processId: executionId,
      status: 'running',
      startTime: context.startTime,
      stdout: '',
      stderr: '',
      metrics: {
        memoryPeak: 0,
        cpuTime: 0,
        duration: 0,
        stateChanges: 0
      }
    };
  }

  private async createContext(script: ScriptDefinition, processId: ProcessId): Promise<ExecutionContext> {
    // Implementation details
    throw new Error('Context creation not implemented');
  }
}

// =============================================
// SUPPORTING INTERFACES
// =============================================

interface ExecutionEngineConfig {
  python: {
    runtimePath: string;
    version: string;
  };
  dependencyCache: any;
  database: StateDatabase;
}

interface StateDatabase {
  initialize(): Promise<void>;
  logEvent(event: StateEvent): Promise<void>;
  getEvents(scriptId: ScriptId): Promise<StateEvent[]>;
  getEventsForKey(scriptId: ScriptId, key: string): Promise<StateEvent[]>;
  saveSnapshot(snapshot: StateSnapshot): Promise<void>;
  getLastSnapshot(scriptId: ScriptId): Promise<StateSnapshot | undefined>;
  deleteEventsBefore(timestamp: Timestamp): Promise<void>;
}

// =============================================
// LIBRARY TEMPLATE SYSTEM
// =============================================

import { z } from 'zod';
import { 
  ScriptTemplate, 
  ScriptCategory, 
  LibraryDependency,
  TemplateExample 
} from './domain-contracts';

// =============================================
// TEMPLATE REGISTRY
// =============================================

export class TemplateRegistry {
  private readonly templates = new Map<string, ScriptTemplate>();

  constructor() {
    this.registerCoreTemplates();
  }

  private registerCoreTemplates(): void {
    // Scheduled Category Templates
    this.register(ScheduleAutomationTemplate);
    this.register(EmailAutomationTemplate);
    this.register(ScheduledAnnouncementTemplate);

    // Reactive Category Templates  
    this.register(FileWatcherTemplate);
    this.register(WebScrapingTemplate);

    // Interactive Category Templates
    this.register(GUIAutomationTemplate);
    this.register(OCRProcessingTemplate);
    this.register(ExcelProcessingTemplate);

    // Persistent Category Templates
    this.register(VoiceInterfaceTemplate);
    this.register(ContinuousMonitoringTemplate);
  }

  register(template: ScriptTemplate): void {
    this.templates.set(template.id, template);
  }

  getTemplate(id: string): ScriptTemplate | undefined {
    return this.templates.get(id);
  }

  getTemplatesByCategory(category: ScriptCategory): ScriptTemplate[] {
    return Array.from(this.templates.values())
      .filter(template => template.category === category);
  }

  getAllTemplates(): ScriptTemplate[] {
    return Array.from(this.templates.values());
  }

  generateScript(templateId: string, config: unknown): string {
    const template = this.getTemplate(templateId);
    if (!template) {
      throw new Error(`Template not found: ${templateId}`);
    }

    // Validate config against schema
    const validatedConfig = template.configSchema.parse(config);

    // Generate script from template
    return this.interpolateTemplate(template.scaffold, validatedConfig);
  }

  private interpolateTemplate(scaffold: string, config: any): string {
    let result = scaffold;
    
    // Simple template interpolation - replace ${key} with config values
    for (const [key, value] of Object.entries(config)) {
      const placeholder = `\${${key}}`;
      result = result.replace(new RegExp(placeholder, 'g'), String(value));
    }

    return result;
  }
}

// =============================================
// SCHEDULED CATEGORY TEMPLATES
// =============================================

export const ScheduleAutomationTemplate: ScriptTemplate = {
  id: 'schedule-automation',
  name: 'Schedule-Based Automation',
  category: 'scheduled',
  description: 'Automate tasks to run at specific times or intervals',
  dependencies: [
    { name: 'schedule', version: '1.2.0', systemDeps: [] }
  ],
  configSchema: z.object({
    interval: z.number().min(1),
    unit: z.enum(['minutes', 'hours', 'days']),
    taskName: z.string(),
    notifyOnComplete: z.boolean().default(true)
  }),
  scaffold: `
import schedule
import time
from vibe_bridge import get_bridge

bridge = get_bridge()

def \${taskName}_task():
    """
    Your automation task goes here.
    This function will run every \${interval} \${unit}.
    """
    bridge.notify_ui("Starting \${taskName} task", "info")
    
    # TODO: Implement your task logic here
    # Example:
    # - File processing
    # - Data backups  
    # - System maintenance
    # - Report generation
    
    result = "Task completed successfully"
    bridge.set_state("last_run_result", result)
    
    if \${notifyOnComplete}:
        bridge.notify_ui(f"\${taskName} completed: {result}", "success")

def main():
    bridge.notify_ui("Scheduler started for \${taskName}", "info")
    
    # Schedule the task
    schedule.every(\${interval}).\${unit}.do(\${taskName}_task)
    
    # Keep the script running
    while True:
        schedule.run_pending()
        bridge.heartbeat()
        time.sleep(60)  # Check every minute

if __name__ == "__main__":
    main()
`,
  examples: [
    {
      name: 'Daily Backup',
      description: 'Run a backup task every day at a specific time',
      config: {
        interval: 1,
        unit: 'days',
        taskName: 'backup',
        notifyOnComplete: true
      },
      expectedOutput: 'Backup task scheduled to run daily'
    },
    {
      name: 'Hourly Health Check',
      description: 'Check system health every hour',
      config: {
        interval: 1,
        unit: 'hours',
        taskName: 'health_check',
        notifyOnComplete: false
      },
      expectedOutput: 'Health check scheduled hourly'
    }
  ]
};

export const EmailAutomationTemplate: ScriptTemplate = {
  id: 'email-automation',
  name: 'Email Automation',
  category: 'scheduled',
  description: 'Send automated emails on a schedule',
  dependencies: [
    { name: 'schedule', version: '1.2.0', systemDeps: [] }
  ],
  configSchema: z.object({
    smtpServer: z.string(),
    smtpPort: z.number().default(587),
    username: z.string().email(),
    password: z.string(),
    recipients: z.array(z.string().email()),
    subject: z.string(),
    schedule: z.string(),
    reportType: z.enum(['daily', 'weekly', 'monthly'])
  }),
  scaffold: `
import smtplib
import schedule
import time
from email.message import EmailMessage
from datetime import datetime
from vibe_bridge import get_bridge

bridge = get_bridge()

def send_automated_email():
    """Send automated email report"""
    bridge.notify_ui("Preparing \${reportType} email report", "info")
    
    try:
        # Create email message
        msg = EmailMessage()
        
        # Generate report content
        report_content = generate_report_content()
        msg.set_content(report_content)
        
        msg['Subject'] = f"\${subject} - {datetime.now().strftime('%Y-%m-%d')}"
        msg['From'] = "\${username}"
        msg['To'] = ", ".join(\${recipients})
        
        # Send email
        with smtplib.SMTP('\${smtpServer}', \${smtpPort}) as smtp:
            smtp.starttls()
            smtp.login('\${username}', '\${password}')
            smtp.send_message(msg)
        
        bridge.set_state("last_email_sent", datetime.now().isoformat())
        bridge.notify_ui("Email sent successfully", "success")
        
    except Exception as e:
        bridge.notify_ui(f"Email sending failed: {str(e)}", "error")
        raise

def generate_report_content():
    """Generate the email report content"""
    
    # Get data from state
    last_run = bridge.get_state("last_run_result", "No previous data")
    
    content = f"""
\${reportType.title()} Report - {datetime.now().strftime('%Y-%m-%d %H:%M')}

System Status: Operational
Last Task Result: {last_run}

Generated automatically by VibeCodeRehab
"""
    return content

def main():
    bridge.notify_ui("Email automation started", "info")
    
    # Parse schedule expression
    schedule.every().day.at("\${schedule}").do(send_automated_email)
    
    while True:
        schedule.run_pending()
        bridge.heartbeat()
        time.sleep(60)

if __name__ == "__main__":
    main()
`,
  examples: [
    {
      name: 'Daily Status Report',
      description: 'Send daily status emails to team',
      config: {
        smtpServer: 'smtp.gmail.com',
        smtpPort: 587,
        username: '[email protected]',
        password: 'app_password',
        recipients: ['[email protected]'],
        subject: 'Daily System Status',
        schedule: '09:00',
        reportType: 'daily'
      },
      expectedOutput: 'Daily email scheduled for 9:00 AM'
    }
  ]
};

// =============================================
// REACTIVE CATEGORY TEMPLATES
// =============================================

export const FileWatcherTemplate: ScriptTemplate = {
  id: 'file-watcher',
  name: 'File System Watcher',
  category: 'reactive',
  description: 'Monitor files and folders for changes and react automatically',
  dependencies: [
    { name: 'watchdog', version: '2.1.9', systemDeps: [] }
  ],
  configSchema: z.object({
    watchPath: z.string(),
    fileTypes: z.array(z.string()),
    actionType: z.enum(['move', 'copy', 'process', 'notify']),
    targetPath: z.string().optional(),
    recursive: z.boolean().default(true)
  }),
  scaffold: `
import os
import shutil
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
from vibe_bridge import get_bridge

bridge = get_bridge()

class FileHandler(FileSystemEventHandler):
    def __init__(self):
        super().__init__()
        self.processed_count = 0
    
    def on_created(self, event):
        if event.is_directory:
            return
            
        file_path = event.src_path
        file_name = os.path.basename(file_path)
        file_ext = os.path.splitext(file_name)[1].lower()
        
        # Check if file type matches our filter
        if file_ext in [\${fileTypes.map(t => `'${t}'`).join(', ')}]:
            bridge.notify_ui(f"New file detected: {file_name}", "info")
            self.process_file(file_path, file_name)
    
    def process_file(self, file_path, file_name):
        """Process the detected file"""
        try:
            action = "\${actionType}"
            
            if action == "move":
                self.move_file(file_path, file_name)
            elif action == "copy":
                self.copy_file(file_path, file_name)
            elif action == "process":
                self.process_file_content(file_path, file_name)
            elif action == "notify":
                self.notify_only(file_path, file_name)
            
            self.processed_count += 1
            bridge.set_state("files_processed", self.processed_count)
            
        except Exception as e:
            bridge.notify_ui(f"Error processing {file_name}: {str(e)}", "error")
    
    def move_file(self, file_path, file_name):
        """Move file to target directory"""
        target_dir = "\${targetPath}"
        if not os.path.exists(target_dir):
            os.makedirs(target_dir)
        
        target_path = os.path.join(target_dir, file_name)
        shutil.move(file_path, target_path)
        bridge.notify_ui(f"Moved {file_name} to {target_dir}", "success")
    
    def copy_file(self, file_path, file_name):
        """Copy file to target directory"""
        target_dir = "\${targetPath}"
        if not os.path.exists(target_dir):
            os.makedirs(target_dir)
        
        target_path = os.path.join(target_dir, file_name)
        shutil.copy2(file_path, target_path)
        bridge.notify_ui(f"Copied {file_name} to {target_dir}", "success")
    
    def process_file_content(self, file_path, file_name):
        """Process file content (implement your logic here)"""
        # TODO: Add your file processing logic
        # Examples:
        # - Extract data from CSV/Excel files
        # - Process images
        # - Parse log files
        # - Convert file formats
        
        bridge.notify_ui(f"Processed content of {file_name}", "success")
    
    def notify_only(self, file_path, file_name):
        """Just notify about the file"""
        bridge.notify_ui(f"File detected: {file_name} at {file_path}", "info")

def main():
    watch_path = "\${watchPath}"
    
    if not os.path.exists(watch_path):
        bridge.notify_ui(f"Watch path does not exist: {watch_path}", "error")
        return
    
    bridge.notify_ui(f"Starting file watcher on: {watch_path}", "info")
    
    event_handler = FileHandler()
    observer = Observer()
    observer.schedule(event_handler, watch_path, recursive=\${recursive})
    
    observer.start()
    bridge.notify_ui("File watcher is running", "success")
    
    try:
        while True:
            bridge.heartbeat()
            time.sleep(10)
    except KeyboardInterrupt:
        observer.stop()
        bridge.notify_ui("File watcher stopped", "info")
    
    observer.join()

if __name__ == "__main__":
    main()
`,
  examples: [
    {
      name: 'PDF Organizer',
      description: 'Automatically organize PDFs by moving them to a sorted folder',
      config: {
        watchPath: '/home/user/Downloads',
        fileTypes: ['.pdf'],
        actionType: 'move',
        targetPath: '/home/user/Documents/PDFs',
        recursive: false
      },
      expectedOutput: 'PDF files will be automatically moved to Documents/PDFs'
    }
  ]
};

export const WebScrapingTemplate: ScriptTemplate = {
  id: 'web-scraping',
  name: 'Web Content Scraper',
  category: 'reactive',
  description: 'Scrape web content on schedule or trigger',
  dependencies: [
    { name: 'requests', version: '2.28.1', systemDeps: [] },
    { name: 'beautifulsoup4', version: '4.11.1', systemDeps: [] },
    { name: 'schedule', version: '1.2.0', systemDeps: [] }
  ],
  configSchema: z.object({
    url: z.string().url(),
    selector: z.string(),
    interval: z.number().min(1),
    saveToFile: z.boolean().default(true),
    notifyOnChange: z.boolean().default(true)
  }),
  scaffold: `
import requests
import schedule
import time
import hashlib
from bs4 import BeautifulSoup
from datetime import datetime
from vibe_bridge import get_bridge

bridge = get_bridge()

def scrape_content():
    """Scrape content from the target URL"""
    url = "\${url}"
    selector = "\${selector}"
    
    try:
        bridge.notify_ui(f"Scraping content from {url}", "info")
        
        # Fetch the page
        response = requests.get(url, timeout=30)
        response.raise_for_status()
        
        # Parse with BeautifulSoup
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # Extract content using selector
        if selector:
            elements = soup.select(selector)
            content = "\\n".join([elem.get_text().strip() for elem in elements])
        else:
            content = soup.get_text().strip()
        
        # Check for changes
        content_hash = hashlib.md5(content.encode()).hexdigest()
        last_hash = bridge.get_state("last_content_hash", "")
        
        if content_hash != last_hash:
            bridge.set_state("last_content_hash", content_hash)
            bridge.set_state("last_content", content)
            bridge.set_state("last_scraped", datetime.now().isoformat())
            
            if \${saveToFile}:
                save_content_to_file(content)
            
            if \${notifyOnChange}:
                bridge.notify_ui("Content changed! New data scraped.", "success")
                
            return True
        else:
            bridge.notify_ui("No changes detected", "info")
            return False
            
    except Exception as e:
        bridge.notify_ui(f"Scraping failed: {str(e)}", "error")
        raise

def save_content_to_file(content):
    """Save scraped content to file"""
    timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
    filename = f"scraped_content_{timestamp}.txt"
    
    with open(filename, 'w', encoding='utf-8') as f:
        f.write(content)
    
    bridge.notify_ui(f"Content saved to {filename}", "success")

def main():
    bridge.notify_ui("Web scraper started", "info")
    
    # Schedule scraping
    schedule.every(\${interval}).minutes.do(scrape_content)
    
    # Run initial scrape
    scrape_content()
    
    while True:
        schedule.run_pending()
        bridge.heartbeat()
        time.sleep(60)

if __name__ == "__main__":
    main()
`,
  examples: [
    {
      name: 'News Monitor',
      description: 'Monitor news website for new headlines',
      config: {
        url: 'https://news.ycombinator.com',
        selector: '.storylink',
        interval: 30,
        saveToFile: true,
        notifyOnChange: true
      },
      expectedOutput: 'News headlines will be monitored every 30 minutes'
    }
  ]
};

// =============================================
// INTERACTIVE CATEGORY TEMPLATES  
// =============================================

export const GUIAutomationTemplate: ScriptTemplate = {
  id: 'gui-automation',
  name: 'GUI Automation',
  category: 'interactive',
  description: 'Automate GUI interactions and workflows',
  dependencies: [
    { name: 'pyautogui', version: '0.9.53', systemDeps: [] },
    { name: 'pygetwindow', version: '0.0.9', systemDeps: [] }
  ],
  configSchema: z.object({
    applicationName: z.string(),
    actionSequence: z.array(z.object({
      type: z.enum(['click', 'type', 'key', 'wait']),
      value: z.string(),
      x: z.number().optional(),
      y: z.number().optional()
    })),
    safetyDelay: z.number().default(1),
    failsafe: z.boolean().default(true)
  }),
  scaffold: `
import pyautogui
import pygetwindow as gw
import time
from vibe_bridge import get_bridge

bridge = get_bridge()

# Configure PyAutoGUI
pyautogui.FAILSAFE = \${failsafe}
pyautogui.PAUSE = \${safetyDelay}

def execute_automation():
    """Execute the GUI automation sequence"""
    app_name = "\${applicationName}"
    
    try:
        bridge.notify_ui(f"Starting GUI automation for {app_name}", "info")
        
        # Find and focus the application window
        windows = gw.getWindowsWithTitle(app_name)
        if not windows:
            bridge.notify_ui(f"Application '{app_name}' not found", "error")
            return False
        
        window = windows[0]
        window.activate()
        time.sleep(2)  # Wait for window to become active
        
        # Execute action sequence
        actions = \${JSON.stringify(actionSequence)}
        
        for i, action in enumerate(actions):
            bridge.log_progress(i + 1, len(actions), f"Executing {action['type']} action")
            
            if action['type'] == 'click':
                if 'x' in action and 'y' in action:
                    pyautogui.click(action['x'], action['y'])
                else:
                    # Click on element by image or text (simplified)
                    bridge.notify_ui(f"Clicking on {action['value']}", "info")
                    # TODO: Implement image/text recognition clicking
            
            elif action['type'] == 'type':
                pyautogui.write(action['value'])
            
            elif action['type'] == 'key':
                pyautogui.press(action['value'])
            
            elif action['type'] == 'wait':
                time.sleep(float(action['value']))
            
            time.sleep(\${safetyDelay})
        
        bridge.notify_ui("GUI automation completed successfully", "success")
        bridge.set_state("last_automation", time.time())
        return True
        
    except Exception as e:
        bridge.notify_ui(f"GUI automation failed: {str(e)}", "error")
        return False

def take_screenshot():
    """Take a screenshot for debugging"""
    timestamp = time.strftime("%Y%m%d_%H%M%S")
    filename = f"screenshot_{timestamp}.png"
    pyautogui.screenshot(filename)
    bridge.notify_ui(f"Screenshot saved: {filename}", "info")

def main():
    bridge.notify_ui("GUI automation script ready", "info")
    
    # Take initial screenshot
    take_screenshot()
    
    # Execute automation
    success = execute_automation()
    
    if success:
        bridge.notify_ui("Automation completed", "success")
    else:
        bridge.notify_ui("Automation failed", "error")

if __name__ == "__main__":
    main()
`,
  examples: [
    {
      name: 'Browser Search',
      description: 'Open browser and perform a search',
      config: {
        applicationName: 'Chrome',
        actionSequence: [
          { type: 'key', value: 'ctrl+l' },
          { type: 'type', value: 'google.com' },
          { type: 'key', value: 'enter' },
          { type: 'wait', value: '3' },
          { type: 'type', value: 'python automation' },
          { type: 'key', value: 'enter' }
        ],
        safetyDelay: 1,
        failsafe: true
      },
      expectedOutput: 'Browser will open and perform a Google search'
    }
  ]
};

export const OCRProcessingTemplate: ScriptTemplate = {
  id: 'ocr-processing',
  name: 'OCR Text Extraction',
  category: 'interactive',
  description: 'Extract text from images using OCR',
  dependencies: [
    { name: 'pytesseract', version: '0.3.10', systemDeps: ['tesseract-ocr'] },
    { name: 'Pillow', version: '9.2.0', systemDeps: [] }
  ],
  configSchema: z.object({
    inputPath: z.string(),
    outputPath: z.string(),
    language: z.string().default('eng'),
    confidence: z.number().min(0).max(100).default(50),
    preprocessImage: z.boolean().default(true)
  }),
  scaffold: `
import os
import pytesseract
from PIL import Image, ImageEnhance, ImageFilter
from vibe_bridge import get_bridge

bridge = get_bridge()

def preprocess_image(image_path):
    """Preprocess image to improve OCR accuracy"""
    bridge.notify_ui("Preprocessing image for better OCR", "info")
    
    # Open image
    img = Image.open(image_path)
    
    # Convert to grayscale
    img = img.convert('L')
    
    # Enhance contrast
    enhancer = ImageEnhance.Contrast(img)
    img = enhancer.enhance(2.0)
    
    # Apply slight blur to smooth text
    img = img.filter(ImageFilter.MedianFilter())
    
    return img

def extract_text_from_image(image_path):
    """Extract text from a single image"""
    try:
        bridge.notify_ui(f"Processing image: {os.path.basename(image_path)}", "info")
        
        # Load and preprocess image
        if \${preprocessImage}:
            img = preprocess_image(image_path)
        else:
            img = Image.open(image_path)
        
        # Configure tesseract
        config = f'--oem 3 --psm 6 -l \${language}'
        
        # Extract text
        extracted_text = pytesseract.image_to_string(img, config=config)
        
        # Get confidence scores
        data = pytesseract.image_to_data(img, output_type=pytesseract.Output.DICT)
        confidences = [int(conf) for conf in data['conf'] if int(conf) > 0]
        avg_confidence = sum(confidences) / len(confidences) if confidences else 0
        
        bridge.notify_ui(f"OCR completed with {avg_confidence:.1f}% confidence", "success")
        
        if avg_confidence < \${confidence}:
            bridge.notify_ui(f"Low confidence warning: {avg_confidence:.1f}%", "warning")
        
        return extracted_text.strip(), avg_confidence
        
    except Exception as e:
        bridge.notify_ui(f"OCR failed for {image_path}: {str(e)}", "error")
        return "", 0

def process_images():
    """Process all images in the input directory"""
    input_path = "\${inputPath}"
    output_path = "\${outputPath}"
    
    # Ensure output directory exists
    os.makedirs(output_path, exist_ok=True)
    
    # Supported image formats
    supported_formats = ('.png', '.jpg', '.jpeg', '.tiff', '.bmp', '.gif')
    
    # Process images
    processed_count = 0
    
    if os.path.isfile(input_path):
        # Single file
        images = [input_path]
    else:
        # Directory
        images = [
            os.path.join(input_path, f) 
            for f in os.listdir(input_path) 
            if f.lower().endswith(supported_formats)
        ]
    
    total_images = len(images)
    bridge.notify_ui(f"Found {total_images} images to process", "info")
    
    for i, image_path in enumerate(images):
        bridge.log_progress(i + 1, total_images, f"Processing {os.path.basename(image_path)}")
        
        text, confidence = extract_text_from_image(image_path)
        
        if text:
            # Save extracted text
            base_name = os.path.splitext(os.path.basename(image_path))[0]
            text_file = os.path.join(output_path, f"{base_name}_extracted.txt")
            
            with open(text_file, 'w', encoding='utf-8') as f:
                f.write(f"Source: {image_path}\\n")
                f.write(f"Confidence: {confidence:.1f}%\\n")
                f.write(f"Language: \${language}\\n")
                f.write("=" * 50 + "\\n\\n")
                f.write(text)
            
            processed_count += 1
            bridge.set_state(f"extracted_text_{base_name}", text)
        
    bridge.set_state("total_processed", processed_count)
    bridge.notify_ui(f"OCR processing complete: {processed_count}/{total_images} images", "success")

def main():
    bridge.notify_ui("OCR text extraction started", "info")
    
    # Verify tesseract installation
    try:
        pytesseract.get_tesseract_version()
        bridge.notify_ui("Tesseract OCR engine detected", "success")
    except Exception:
        bridge.notify_ui("Tesseract not found. Please install tesseract-ocr", "error")
        return
    
    # Process images
    process_images()
    
    bridge.notify_ui("OCR extraction completed", "success")

if __name__ == "__main__":
    main()
`,
  examples: [
    {
      name: 'Document Scanner',
      description: 'Extract text from scanned documents',
      config: {
        inputPath: '/path/to/scanned/documents',
        outputPath: '/path/to/extracted/text',
        language: 'eng',
        confidence: 60,
        preprocessImage: true
      },
      expectedOutput: 'Text will be extracted from all images and saved as .txt files'
    }
  ]
};

// =============================================
// PERSISTENT CATEGORY TEMPLATES
// =============================================

export const VoiceInterfaceTemplate: ScriptTemplate = {
  id: 'voice-interface',
  name: 'Voice Interface',
  category: 'persistent',
  description: 'Continuous voice interaction and text-to-speech',
  dependencies: [
    { name: 'pyttsx3', version: '2.90', systemDeps: ['espeak'] }
  ],
  configSchema: z.object({
    voice: z.enum(['male', 'female']).default('female'),
    rate: z.number().min(50).max(300).default(200),
    volume: z.number().min(0).max(1).default(0.9),
    announcements: z.array(z.object({
      message: z.string(),
      trigger: z.string()
    }))
  }),
  scaffold: `
import pyttsx3
import time
import threading
from datetime import datetime
from vibe_bridge import get_bridge

bridge = get_bridge()

class VoiceInterface:
    def __init__(self):
        self.engine = pyttsx3.init()
        self.setup_voice()
        self.is_running = True
        
    def setup_voice(self):
        """Configure voice settings"""
        voices = self.engine.getProperty('voices')
        
        # Select voice based on preference
        voice_type = "\${voice}"
        for voice in voices:
            if voice_type == 'female' and 'female' in voice.name.lower():
                self.engine.setProperty('voice', voice.id)
                break
            elif voice_type == 'male' and 'male' in voice.name.lower():
                self.engine.setProperty('voice', voice.id)
                break
        
        # Set rate and volume
        self.engine.setProperty('rate', \${rate})
        self.engine.setProperty('volume', \${volume})
        
        bridge.notify_ui(f"Voice configured: {voice_type}, rate: \${rate}", "success")
    
    def speak(self, text):
        """Convert text to speech"""
        try:
            self.engine.say(text)
            self.engine.runAndWait()
            bridge.set_state("last_spoken", {
                "text": text,
                "timestamp": datetime.now().isoformat()
            })
        except Exception as e:
            bridge.notify_ui(f"Speech error: {str(e)}", "error")
    
    def announce_time(self):
        """Announce current time"""
        current_time = datetime.now().strftime("%I:%M %p")
        self.speak(f"The current time is {current_time}")
    
    def process_announcements(self):
        """Process scheduled announcements"""
        announcements = \${JSON.stringify(announcements)}
        
        for announcement in announcements:
            # Simple trigger processing (could be enhanced)
            trigger = announcement['trigger']
            message = announcement['message']
            
            if trigger == 'hourly':
                if datetime.now().minute == 0:
                    self.speak(message)
            elif trigger == 'startup':
                self.speak(message)
    
    def listen_for_commands(self):
        """Listen for voice commands (simplified)"""
        # In a full implementation, this would use speech recognition
        # For now, we'll listen for state changes that trigger speech
        
        while self.is_running:
            # Check for speech requests from other scripts
            speech_request = bridge.get_state("speech_request", None)
            if speech_request:
                self.speak(speech_request)
                bridge.delete("speech_request")
            
            # Check for time announcement requests
            if bridge.get_state("announce_time", False):
                self.announce_time()
                bridge.delete("announce_time")
            
            # Process scheduled announcements
            self.process_announcements()
            
            bridge.heartbeat()
            time.sleep(10)  # Check every 10 seconds

def main():
    bridge.notify_ui("Voice interface starting", "info")
    
    try:
        voice_interface = VoiceInterface()
        
        # Initial greeting
        greeting = f"Voice interface activated at {datetime.now().strftime('%I:%M %p')}"
        voice_interface.speak(greeting)
        bridge.notify_ui(greeting, "success")
        
        # Start listening for commands
        voice_interface.listen_for_commands()
        
    except KeyboardInterrupt:
        bridge.notify_ui("Voice interface stopped", "info")
    except Exception as e:
        bridge.notify_ui(f"Voice interface error: {str(e)}", "error")

if __name__ == "__main__":
    main()
`,
  examples: [
    {
      name: 'Personal Assistant',
      description: 'Voice assistant for notifications and updates',
      config: {
        voice: 'female',
        rate: 180,
        volume: 0.8,
        announcements: [
          { message: 'Voice assistant is now active', trigger: 'startup' },
          { message: 'Hourly reminder to take a break', trigger: 'hourly' }
        ]
      },
      expectedOutput: 'Voice assistant will run continuously and make announcements'
    }
  ]
};

// Export the registry instance
export const templateRegistry = new TemplateRegistry();

// =============================================
// VIBECODREHAB MAIN APPLICATION
// =============================================

import { EventEmitter } from 'events';
import { resolve } from 'path';
import { 
  ScriptDefinition, 
  ScriptId, 
  ProcessId,
  ExecutionResult,
  SystemEvent,
  ScriptCategory 
} from './domain-contracts';
import { ExecutionEngine } from './execution-engine';
import { templateRegistry, TemplateRegistry } from './library-templates';

// =============================================
// MAIN APPLICATION CLASS
// =============================================

export class VibeCodeRehab extends EventEmitter {
  private readonly executionEngine: ExecutionEngine;
  private readonly templateRegistry: TemplateRegistry;
  private readonly scriptStorage: ScriptStorage;
  private readonly config: VibeConfig;
  private isInitialized = false;

  constructor(config: VibeConfig) {
    super();
    this.config = config;
    this.executionEngine = new ExecutionEngine({
      python: {
        runtimePath: resolve(config.pythonRuntimePath),
        version: '3.11'
      },
      dependencyCache: new FileDependencyCache(config.cacheDirectory),
      database: new SQLiteStateDatabase(config.databasePath)
    });
    this.templateRegistry = templateRegistry;
    this.scriptStorage = new FileScriptStorage(config.scriptsDirectory);
  }

  async initialize(): Promise<void> {
    if (this.isInitialized) return;

    try {
      this.emit('system.initializing');

      // Initialize core components
      await this.executionEngine.initialize();
      await this.scriptStorage.initialize();

      // Setup event forwarding
      this.executionEngine.on('script.execution', (event) => this.emit('script.execution', event));
      this.executionEngine.on('script.error', (event) => this.emit('script.error', event));
      this.executionEngine.on('system.ready', () => this.emit('system.ready'));

      this.isInitialized = true;
      this.emit('system.initialized');

    } catch (error) {
      this.emit('system.error', { error: error.message });
      throw error;
    }
  }

  // =============================================
  // SCRIPT MANAGEMENT API
  // =============================================

  async createScriptFromTemplate(
    templateId: string, 
    config: unknown, 
    metadata: Partial<ScriptMetadata>
  ): Promise<ScriptDefinition> {
    const template = this.templateRegistry.getTemplate(templateId);
    if (!template) {
      throw new Error(`Template not found: ${templateId}`);
    }

    // Generate script code from template
    const code = this.templateRegistry.generateScript(templateId, config);

    // Create script definition
    const script: ScriptDefinition = {
      id: this.generateScriptId(),
      name: metadata.name || template.name,
      category: template.category,
      code,
      dependencies: template.dependencies,
      config: {
        timeout: 300000, // 5 minutes default
        memory: 512,     // 512MB default
        restart: false,
        ...this.extractScriptConfig(config)
      },
      metadata: {
        author: metadata.author || 'User',
        description: metadata.description || template.description,
        tags: metadata.tags || [template.category],
        created: Date.now() as Timestamp,
        modified: Date.now() as Timestamp,
        version: '1.0.0'
      }
    };

    // Save script
    await this.scriptStorage.save(script);
    
    this.emit('script.created', { scriptId: script.id, templateId });
    return script;
  }

  async getScript(scriptId: ScriptId): Promise<ScriptDefinition | undefined> {
    return this.scriptStorage.get(scriptId);
  }

  async listScripts(category?: ScriptCategory): Promise<ScriptDefinition[]> {
    const scripts = await this.scriptStorage.list();
    return category ? scripts.filter(s => s.category === category) : scripts;
  }

  async updateScript(scriptId: ScriptId, updates: Partial<ScriptDefinition>): Promise<void> {
    const script = await this.scriptStorage.get(scriptId);
    if (!script) {
      throw new Error(`Script not found: ${scriptId}`);
    }

    const updatedScript = {
      ...script,
      ...updates,
      metadata: {
        ...script.metadata,
        ...updates.metadata,
        modified: Date.now() as Timestamp
      }
    };

    await this.scriptStorage.save(updatedScript);
    this.emit('script.updated', { scriptId });
  }

  async deleteScript(scriptId: ScriptId): Promise<void> {
    await this.scriptStorage.delete(scriptId);
    this.emit('script.deleted', { scriptId });
  }

  // =============================================
  // EXECUTION API
  // =============================================

  async executeScript(scriptId: ScriptId): Promise<ExecutionResult> {
    const script = await this.scriptStorage.get(scriptId);
    if (!script) {
      throw new Error(`Script not found: ${scriptId}`);
    }

    return this.executionEngine.executeScript(script);
  }

  async scheduleScript(scriptId: ScriptId): Promise<void> {
    const script = await this.scriptStorage.get(scriptId);
    if (!script) {
      throw new Error(`Script not found: ${scriptId}`);
    }

    if (script.category !== 'scheduled') {
      throw new Error('Only scheduled scripts can be scheduled');
    }

    await this.executionEngine.scheduleScript(script);
    this.emit('script.scheduled', { scriptId });
  }

  async startReactiveScript(scriptId: ScriptId): Promise<void> {
    const script = await this.scriptStorage.get(scriptId);
    if (!script) {
      throw new Error(`Script not found: ${scriptId}`);
    }

    if (script.category !== 'reactive') {
      throw new Error('Only reactive scripts can be started as reactive');
    }

    await this.executionEngine.startReactiveScript(script);
    this.emit('script.reactive.started', { scriptId });
  }

  async getExecutionStatus(processId: ProcessId): Promise<ExecutionState> {
    return this.executionEngine.getExecutionStatus(processId);
  }

  async getActiveExecutions(): Promise<ProcessHandle[]> {
    return this.executionEngine.getActiveExecutions();
  }

  // =============================================
  // TEMPLATE API
  // =============================================

  getTemplates(category?: ScriptCategory): ScriptTemplate[] {
    return category 
      ? this.templateRegistry.getTemplatesByCategory(category)
      : this.templateRegistry.getAllTemplates();
  }

  getTemplate(templateId: string): ScriptTemplate | undefined {
    return this.templateRegistry.getTemplate(templateId);
  }

  // =============================================
  // UTILITY METHODS
  // =============================================

  private generateScriptId(): ScriptId {
    return `script_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` as ScriptId;
  }

  private extractScriptConfig(templateConfig: unknown): Partial<ScriptConfig> {
    // Extract runtime configuration from template config
    const config: any = templateConfig;
    
    return {
      schedule: config.schedule ? {
        type: 'interval',
        expression: `${config.interval} ${config.unit}`
      } : undefined,
      watchPaths: config.watchPath ? [config.watchPath] : undefined
    };
  }

  async shutdown(): Promise<void> {
    this.emit('system.shutting_down');
    // Cleanup resources
    this.removeAllListeners();
    this.emit('system.shutdown');
  }
}

// =============================================
// STORAGE IMPLEMENTATIONS
// =============================================

interface ScriptStorage {
  initialize(): Promise<void>;
  save(script: ScriptDefinition): Promise<void>;
  get(scriptId: ScriptId): Promise<ScriptDefinition | undefined>;
  list(): Promise<ScriptDefinition[]>;
  delete(scriptId: ScriptId): Promise<void>;
}

class FileScriptStorage implements ScriptStorage {
  constructor(private readonly directory: string) {}

  async initialize(): Promise<void> {
    const fs = require('fs/promises');
    try {
      await fs.access(this.directory);
    } catch {
      await fs.mkdir(this.directory, { recursive: true });
    }
  }

  async save(script: ScriptDefinition): Promise<void> {
    const fs = require('fs/promises');
    const filePath = resolve(this.directory, `${script.id}.json`);
    await fs.writeFile(filePath, JSON.stringify(script, null, 2));
  }

  async get(scriptId: ScriptId): Promise<ScriptDefinition | undefined> {
    const fs = require('fs/promises');
    const filePath = resolve(this.directory, `${scriptId}.json`);
    
    try {
      const content = await fs.readFile(filePath, 'utf-8');
      return JSON.parse(content);
    } catch {
      return undefined;
    }
  }

  async list(): Promise<ScriptDefinition[]> {
    const fs = require('fs/promises');
    const files = await fs.readdir(this.directory);
    const scripts: ScriptDefinition[] = [];

    for (const file of files) {
      if (file.endsWith('.json')) {
        const scriptId = file.replace('.json', '') as ScriptId;
        const script = await this.get(scriptId);
        if (script) scripts.push(script);
      }
    }

    return scripts;
  }

  async delete(scriptId: ScriptId): Promise<void> {
    const fs = require('fs/promises');
    const filePath = resolve(this.directory, `${scriptId}.json`);
    await fs.unlink(filePath);
  }
}

// =============================================
// CONFIGURATION
// =============================================

export interface VibeConfig {
  pythonRuntimePath: string;
  scriptsDirectory: string;
  cacheDirectory: string;
  databasePath: string;
  logLevel: 'debug' | 'info' | 'warn' | 'error';
}

export const defaultConfig: VibeConfig = {
  pythonRuntimePath: './runtime/python',
  scriptsDirectory: './data/scripts',
  cacheDirectory: './data/cache',
  databasePath: './data/state.db',
  logLevel: 'info'
};

// =============================================
// USAGE EXAMPLE
// =============================================

export async function exampleUsage() {
  // Initialize VibeCodeRehab
  const vibe = new VibeCodeRehab(defaultConfig);

  // Setup event listeners
  vibe.on('system.ready', () => {
    console.log('✅ VibeCodeRehab is ready!');
  });

  vibe.on('script.execution', (event: SystemEvent) => {
    console.log(`🏃 Script execution: ${event.scriptId} - ${event.state}`);
  });

  vibe.on('script.error', (event: SystemEvent) => {
    console.log(`❌ Script error: ${event.scriptId} - ${event.metadata?.error}`);
  });

  // Initialize the system
  await vibe.initialize();

  // Example 1: Create a scheduled email automation
  const emailScript = await vibe.createScriptFromTemplate('email-automation', {
    smtpServer: 'smtp.gmail.com',
    smtpPort: 587,
    username: '[email protected]',
    password: 'app_password',
    recipients: ['[email protected]'],
    subject: 'Daily System Status',
    schedule: '09:00',
    reportType: 'daily'
  }, {
    name: 'Daily Status Email',
    description: 'Send daily status reports to the team',
    tags: ['email', 'automation', 'daily']
  });

  // Schedule the email script
  await vibe.scheduleScript(emailScript.id);
  console.log(`📧 Scheduled email automation: ${emailScript.id}`);

  // Example 2: Create a file watcher
  const fileWatcherScript = await vibe.createScriptFromTemplate('file-watcher', {
    watchPath: '/home/user/Downloads',
    fileTypes: ['.pdf', '.doc', '.docx'],
    actionType: 'move',
    targetPath: '/home/user/Documents/Organized',
    recursive: false
  }, {
    name: 'Document Organizer',
    description: 'Automatically organize downloaded documents',
    tags: ['file-management', 'automation']
  });

  // Start the reactive file watcher
  await vibe.startReactiveScript(fileWatcherScript.id);
  console.log(`📁 Started file watcher: ${fileWatcherScript.id}`);

  // Example 3: Create an OCR processing script
  const ocrScript = await vibe.createScriptFromTemplate('ocr-processing', {
    inputPath: '/home/user/scanned-docs',
    outputPath: '/home/user/extracted-text',
    language: 'eng',
    confidence: 60,
    preprocessImage: true
  }, {
    name: 'Document OCR Processor',
    description: 'Extract text from scanned documents',
    tags: ['ocr', 'text-extraction']
  });

  // Execute the OCR script (interactive)
  const result = await vibe.executeScript(ocrScript.id);
  console.log(`🔍 OCR processing result: ${result.status}`);

  // Example 4: List all scripts by category
  const scheduledScripts = await vibe.listScripts('scheduled');
  const reactiveScripts = await vibe.listScripts('reactive');
  const interactiveScripts = await vibe.listScripts('interactive');

  console.log(`\n📊 Script Summary:`);
  console.log(`Scheduled: ${scheduledScripts.length}`);
  console.log(`Reactive: ${reactiveScripts.length}`);
  console.log(`Interactive: ${interactiveScripts.length}`);

  // Example 5: Monitor active executions
  setInterval(async () => {
    const activeExecutions = await vibe.getActiveExecutions();
    if (activeExecutions.length > 0) {
      console.log(`🏃 Active executions: ${activeExecutions.length}`);
      for (const exec of activeExecutions) {
        console.log(`  - ${exec.scriptId}: ${exec.status}`);
      }
    }
  }, 30000); // Check every 30 seconds

  // Graceful shutdown
  process.on('SIGINT', async () => {
    console.log('\n🛑 Shutting down VibeCodeRehab...');
    await vibe.shutdown();
    process.exit(0);
  });

  return vibe;
}

// =============================================
// APPLICATION ENTRY POINT
// =============================================

if (require.main === module) {
  exampleUsage().catch(console.error);
}

export default VibeCodeRehab;

he user wants me to continue with the VibeCodeRehab application development. I've created the core architecture with:

  1. Domain contracts

  2. Python runtime foundation

  3. Execution engine with state management

  4. Library template system

  5. Main application orchestrator

Now I should continue with the missing pieces to make this production-ready:

  1. Testing strategy and implementation

  2. UI/Frontend architecture (TypeScript React)

  3. Error handling and recovery

  4. Performance monitoring

  5. Deployment and packaging

  6. Documentation

Let me continue with the testing strategy first, then move to the UI architecture.

// =============================================
// COMPREHENSIVE TESTING STRATEGY
// =============================================

import { describe, test, expect, beforeEach, afterEach, jest } from '@jest/globals';
import { 
  ScriptDefinition, 
  ExecutionContext, 
  ProcessHandle,
  ScriptId,
  ProcessId,
  ExecutionState 
} from '../src/domain-contracts';
import { VibeCodeRehab } from '../src/main-application';
import { ExecutionEngine } from '../src/execution-engine';
import { templateRegistry } from '../src/library-templates';

// =============================================
// CONTRACT TESTING - DOMAIN MODELS
// =============================================

describe('Domain Contract Validation', () => {
  test('ScriptDefinition contract enforces required fields', () => {
    const validScript: ScriptDefinition = {
      id: 'test-script' as ScriptId,
      name: 'Test Script',
      category: 'interactive',
      code: 'print("hello world")',
      dependencies: [],
      config: {},
      metadata: {
        author: 'Test',
        description: 'Test script',
        tags: ['test'],
        created: Date.now() as Timestamp,
        modified: Date.now() as Timestamp,
        version: '1.0.0'
      }
    };

    expect(validScript.id).toBeDefined();
    expect(validScript.category).toMatch(/^(scheduled|reactive|interactive|persistent)$/);
    expect(validScript.code.length).toBeGreaterThan(0);
  });

  test('ExecutionState transitions are valid', () => {
    const validStates: ExecutionState[] = [
      'pending', 'starting', 'running', 'paused', 
      'completed', 'failed', 'terminated', 'recovering'
    ];

    const validTransitions = new Map([
      ['pending', ['starting', 'terminated']],
      ['starting', ['running', 'failed', 'terminated']],
      ['running', ['paused', 'completed', 'failed', 'terminated']],
      ['paused', ['running', 'terminated']],
      ['completed', []],
      ['failed', ['recovering', 'terminated']],
      ['terminated', []],
      ['recovering', ['running', 'failed', 'terminated']]
    ]);

    for (const [fromState, toStates] of validTransitions) {
      expect(validStates).toContain(fromState);
      toStates.forEach(toState => {
        expect(validStates).toContain(toState);
      });
    }
  });
});

// =============================================
// UNIT TESTING - CORE COMPONENTS
// =============================================

describe('PythonRuntime Unit Tests', () => {
  let mockPythonRuntime: any;

  beforeEach(() => {
    mockPythonRuntime = {
      initialize: jest.fn(),
      executeScript: jest.fn(),
      getProcess: jest.fn(),
      terminate: jest.fn()
    };
  });

  test('should initialize embedded Python interpreter', async () => {
    mockPythonRuntime.initialize.mockResolvedValue(undefined);
    
    await mockPythonRuntime.initialize();
    
    expect(mockPythonRuntime.initialize).toHaveBeenCalledTimes(1);
  });

  test('should handle Python execution errors gracefully', async () => {
    const badScript: ScriptDefinition = createTestScript({
      code: 'import non_existent_module'
    });

    mockPythonRuntime.executeScript.mockRejectedValue(
      new Error('ModuleNotFoundError: No module named \'non_existent_module\'')
    );

    await expect(mockPythonRuntime.executeScript(badScript))
      .rejects.toThrow('ModuleNotFoundError');
  });

  test('should isolate script processes', async () => {
    const script1 = createTestScript({ code: 'import sys; sys.exit(1)' });
    const script2 = createTestScript({ code: 'print("success")' });

    mockPythonRuntime.executeScript
      .mockResolvedValueOnce({ status: 'failed', exitCode: 1 })
      .mockResolvedValueOnce({ status: 'completed', exitCode: 0 });

    const result1 = await mockPythonRuntime.executeScript(script1);
    const result2 = await mockPythonRuntime.executeScript(script2);

    expect(result1.status).toBe('failed');
    expect(result2.status).toBe('completed');
  });
});

describe('StateEngine Unit Tests', () => {
  let stateEngine: any;
  let mockDatabase: any;

  beforeEach(() => {
    mockDatabase = {
      logEvent: jest.fn(),
      getEvents: jest.fn(),
      saveSnapshot: jest.fn(),
      getLastSnapshot: jest.fn()
    };
    
    stateEngine = {
      createStatePod: jest.fn(),
      getLastSnapshot: jest.fn()
    };
  });

  test('should persist state changes', async () => {
    const scriptId = 'test-script' as ScriptId;
    const mockStatePod = {
      set: jest.fn(),
      get: jest.fn(),
      createSnapshot: jest.fn()
    };

    stateEngine.createStatePod.mockResolvedValue(mockStatePod);
    mockStatePod.set.mockResolvedValue(undefined);
    mockStatePod.get.mockResolvedValue('test-value');

    const statePod = await stateEngine.createStatePod(scriptId);
    await statePod.set('test-key', 'test-value');
    const value = await statePod.get('test-key');

    expect(mockStatePod.set).toHaveBeenCalledWith('test-key', 'test-value');
    expect(value).toBe('test-value');
  });

  test('should create snapshots for recovery', async () => {
    const scriptId = 'test-script' as ScriptId;
    const mockSnapshot = {
      scriptId,
      timestamp: Date.now() as Timestamp,
      state: { 'key1': 'value1', 'key2': 'value2' },
      checksum: 'abc123'
    };

    stateEngine.getLastSnapshot.mockResolvedValue(mockSnapshot);

    const snapshot = await stateEngine.getLastSnapshot(scriptId);
    
    expect(snapshot).toBeDefined();
    expect(snapshot.scriptId).toBe(scriptId);
    expect(snapshot.state).toHaveProperty('key1', 'value1');
  });

  test('should handle concurrent state modifications', async () => {
    const mockStatePod = {
      set: jest.fn(),
      get: jest.fn(),
      subscribers: new Map()
    };

    // Simulate concurrent modifications
    const promises = [
      mockStatePod.set('counter', 1),
      mockStatePod.set('counter', 2),
      mockStatePod.set('counter', 3)
    ];

    mockStatePod.set.mockResolvedValue(undefined);
    await Promise.all(promises);

    expect(mockStatePod.set).toHaveBeenCalledTimes(3);
  });
});

describe('TemplateRegistry Unit Tests', () => {
  test('should register and retrieve templates', () => {
    const template = templateRegistry.getTemplate('schedule-automation');
    
    expect(template).toBeDefined();
    expect(template?.category).toBe('scheduled');
    expect(template?.dependencies).toContain(
      expect.objectContaining({ name: 'schedule' })
    );
  });

  test('should generate valid scripts from templates', () => {
    const config = {
      interval: 5,
      unit: 'minutes',
      taskName: 'test_task',
      notifyOnComplete: true
    };

    const script = templateRegistry.generateScript('schedule-automation', config);
    
    expect(script).toContain('test_task_task()');
    expect(script).toContain('every(5).minutes');
    expect(script).toContain('import schedule');
  });

  test('should validate template configuration schemas', () => {
    const template = templateRegistry.getTemplate('schedule-automation');
    const validConfig = {
      interval: 10,
      unit: 'hours',
      taskName: 'backup',
      notifyOnComplete: false
    };
    const invalidConfig = {
      interval: -1,  // Invalid: negative interval
      unit: 'invalid',  // Invalid: unknown unit
      taskName: '',  // Invalid: empty task name
    };

    expect(() => template?.configSchema.parse(validConfig)).not.toThrow();
    expect(() => template?.configSchema.parse(invalidConfig)).toThrow();
  });

  test('should filter templates by category', () => {
    const scheduledTemplates = templateRegistry.getTemplatesByCategory('scheduled');
    const reactiveTemplates = templateRegistry.getTemplatesByCategory('reactive');

    expect(scheduledTemplates.length).toBeGreaterThan(0);
    expect(reactiveTemplates.length).toBeGreaterThan(0);
    
    scheduledTemplates.forEach(template => {
      expect(template.category).toBe('scheduled');
    });
    
    reactiveTemplates.forEach(template => {
      expect(template.category).toBe('reactive');
    });
  });
});

// =============================================
// INTEGRATION TESTING
// =============================================

describe('End-to-End Integration Tests', () => {
  let vibe: VibeCodeRehab;
  let testConfig: VibeConfig;

  beforeEach(async () => {
    testConfig = {
      pythonRuntimePath: './test/runtime/python',
      scriptsDirectory: './test/data/scripts',
      cacheDirectory: './test/data/cache',
      databasePath: './test/data/test.db',
      logLevel: 'debug'
    };

    vibe = new VibeCodeRehab(testConfig);
    await vibe.initialize();
  });

  afterEach(async () => {
    await vibe.shutdown();
    // Cleanup test files
    await cleanupTestEnvironment(testConfig);
  });

  test('should create, execute, and monitor script lifecycle', async () => {
    // Create script from template
    const script = await vibe.createScriptFromTemplate('schedule-automation', {
      interval: 1,
      unit: 'minutes',
      taskName: 'test_job',
      notifyOnComplete: true
    }, {
      name: 'Test Integration Script',
      description: 'End-to-end test script'
    });

    expect(script.id).toBeDefined();
    expect(script.category).toBe('scheduled');

    // Execute script
    const executionResult = await vibe.executeScript(script.id);
    
    expect(executionResult.scriptId).toBe(script.id);
    expect(['completed', 'running']).toContain(executionResult.status);

    // Monitor execution
    const activeExecutions = await vibe.getActiveExecutions();
    const thisExecution = activeExecutions.find(
      exec => exec.scriptId === script.id
    );

    if (thisExecution) {
      expect(thisExecution.status).toMatch(/^(running|completed)$/);
    }
  }, 30000); // 30 second timeout for integration test

  test('should handle script failure and recovery', async () => {
    // Create a script that will fail
    const failingScript = await vibe.createScriptFromTemplate('schedule-automation', {
      interval: 1,
      unit: 'minutes',
      taskName: 'failing_task',
      notifyOnComplete: true
    }, {
      name: 'Failing Test Script',
      description: 'Script designed to fail for testing'
    });

    // Modify script to include failing code
    await vibe.updateScript(failingScript.id, {
      code: failingScript.code + '\nraise Exception("Intentional test failure")'
    });

    // Execute and expect failure
    const result = await vibe.executeScript(failingScript.id);
    
    expect(result.status).toBe('failed');
    expect(result.exitCode).not.toBe(0);
  });

  test('should persist state across script restarts', async () => {
    // Create a script that sets state
    const script = await vibe.createScriptFromTemplate('schedule-automation', {
      interval: 1,
      unit: 'minutes',
      taskName: 'state_test',
      notifyOnComplete: true
    }, {
      name: 'State Persistence Test',
      description: 'Test state persistence'
    });

    // Modify script to set state
    const stateTestCode = `
from vibe_bridge import get_bridge
bridge = get_bridge()

# Set some state
bridge.set_state("test_counter", 42)
bridge.set_state("test_message", "Hello from script")

print("State set successfully")
`;

    await vibe.updateScript(script.id, { code: stateTestCode });

    // Execute script
    await vibe.executeScript(script.id);

    // Create a new script that reads the state
    const readerScript = await vibe.createScriptFromTemplate('schedule-automation', {
      interval: 1,
      unit: 'minutes',
      taskName: 'state_reader',
      notifyOnComplete: true
    }, {
      name: 'State Reader Test',
      description: 'Read persisted state'
    });

    const readerCode = `
from vibe_bridge import get_bridge
bridge = get_bridge()

# Read state from other script
counter = bridge.get_state("test_counter", 0)
message = bridge.get_state("test_message", "")

print(f"Counter: {counter}")
print(f"Message: {message}")

assert counter == 42, f"Expected 42, got {counter}"
assert message == "Hello from script", f"Expected message, got {message}"

print("State read successfully")
`;

    await vibe.updateScript(readerScript.id, { code: readerCode });

    // Execute reader script
    const result = await vibe.executeScript(readerScript.id);
    
    expect(result.status).toBe('completed');
    expect(result.exitCode).toBe(0);
  });
});

// =============================================
// PERFORMANCE TESTING
// =============================================

describe('Performance Tests', () => {
  let vibe: VibeCodeRehab;

  beforeEach(async () => {
    vibe = new VibeCodeRehab({
      pythonRuntimePath: './test/runtime/python',
      scriptsDirectory: './test/data/scripts',
      cacheDirectory: './test/data/cache',
      databasePath: './test/data/perf.db',
      logLevel: 'error' // Reduce logging for performance tests
    });
    await vibe.initialize();
  });

  afterEach(async () => {
    await vibe.shutdown();
  });

  test('should handle concurrent script executions', async () => {
    const startTime = Date.now();
    const scriptPromises: Promise<any>[] = [];

    // Create and execute 10 scripts concurrently
    for (let i = 0; i < 10; i++) {
      const promise = vibe.createScriptFromTemplate('schedule-automation', {
        interval: 1,
        unit: 'minutes',
        taskName: `concurrent_task_${i}`,
        notifyOnComplete: false
      }, {
        name: `Concurrent Script ${i}`,
        description: 'Performance test script'
      }).then(script => vibe.executeScript(script.id));

      scriptPromises.push(promise);
    }

    const results = await Promise.all(scriptPromises);
    const endTime = Date.now();
    const totalTime = endTime - startTime;

    // All scripts should complete
    results.forEach(result => {
      expect(['completed', 'running']).toContain(result.status);
    });

    // Should complete within reasonable time (adjust based on system)
    expect(totalTime).toBeLessThan(30000); // 30 seconds

    console.log(`Concurrent execution test completed in ${totalTime}ms`);
  }, 60000);

  test('should handle rapid state updates', async () => {
    const script = await vibe.createScriptFromTemplate('schedule-automation', {
      interval: 1,
      unit: 'minutes',
      taskName: 'rapid_state_test',
      notifyOnComplete: false
    }, {
      name: 'Rapid State Updates',
      description: 'Test rapid state modifications'
    });

    const rapidStateCode = `
from vibe_bridge import get_bridge
import time

bridge = get_bridge()

# Rapid state updates
start_time = time.time()
for i in range(1000):
    bridge.set_state(f"rapid_key_{i}", f"value_{i}")
    if i % 100 == 0:
        bridge.notify_ui(f"Progress: {i}/1000", "info")

end_time = time.time()
total_time = end_time - start_time

bridge.set_state("total_updates", 1000)
bridge.set_state("update_time", total_time)
bridge.notify_ui(f"Completed 1000 updates in {total_time:.2f}s", "success")

print(f"Rapid state updates completed: {total_time:.2f}s")
`;

    await vibe.updateScript(script.id, { code: rapidStateCode });

    const startTime = Date.now();
    const result = await vibe.executeScript(script.id);
    const endTime = Date.now();

    expect(result.status).toBe('completed');
    expect(endTime - startTime).toBeLessThan(10000); // Should complete within 10 seconds

    console.log(`Rapid state update test completed in ${endTime - startTime}ms`);
  });
});

// =============================================
// STRESS TESTING
// =============================================

describe('Stress Tests', () => {
  test('should handle memory-intensive scripts', async () => {
    // Test script that uses significant memory
    const memoryTestCode = `
import sys
from vibe_bridge import get_bridge

bridge = get_bridge()

# Allocate memory in chunks
data = []
chunk_size = 1024 * 1024  # 1MB chunks
max_chunks = 100  # 100MB total

for i in range(max_chunks):
    chunk = 'x' * chunk_size
    data.append(chunk)
    
    if i % 10 == 0:
        bridge.notify_ui(f"Allocated {i+1}MB", "info")

bridge.notify_ui(f"Memory test completed: {len(data)}MB allocated", "success")
print("Memory stress test completed")
`;

    // This test would need proper memory monitoring
    // Implementation depends on specific memory constraints
    expect(true).toBe(true); // Placeholder
  });

  test('should handle long-running scripts', async () => {
    // Test script that runs for extended period
    const longRunningCode = `
import time
from vibe_bridge import get_bridge

bridge = get_bridge()

# Run for 5 minutes (adjust for testing)
duration = 5  # seconds for testing
start_time = time.time()

while time.time() - start_time < duration:
    bridge.heartbeat()
    bridge.notify_ui(f"Running for {int(time.time() - start_time)}s", "info")
    time.sleep(1)

bridge.notify_ui("Long-running test completed", "success")
print("Long-running stress test completed")
`;

    // This test would verify script can run for extended periods
    // Implementation depends on specific requirements
    expect(true).toBe(true); // Placeholder
  });
});

// =============================================
// HELPER FUNCTIONS
// =============================================

function createTestScript(overrides: Partial<ScriptDefinition> = {}): ScriptDefinition {
  return {
    id: `test-${Date.now()}` as ScriptId,
    name: 'Test Script',
    category: 'interactive',
    code: 'print("Hello, World!")',
    dependencies: [],
    config: {},
    metadata: {
      author: 'Test',
      description: 'Test script',
      tags: ['test'],
      created: Date.now() as Timestamp,
      modified: Date.now() as Timestamp,
      version: '1.0.0'
    },
    ...overrides
  };
}

async function cleanupTestEnvironment(config: VibeConfig): Promise<void> {
  const fs = require('fs/promises');
  
  try {
    // Remove test directories
    await fs.rm(config.scriptsDirectory, { recursive: true, force: true });
    await fs.rm(config.cacheDirectory, { recursive: true, force: true });
    
    // Remove test database
    try {
      await fs.unlink(config.databasePath);
    } catch {
      // Database file might not exist
    }
  } catch (error) {
    console.warn('Cleanup warning:', error);
  }
}

// =============================================
// TEST CONFIGURATION
// =============================================

export const testConfig = {
  // Jest configuration
  testEnvironment: 'node',
  setupFilesAfterEnv: ['<rootDir>/test/setup.ts'],
  testMatch: ['**/__tests__/**/*.test.ts'],
  collectCoverageFrom: [
    'src/**/*.ts',
    '!src/**/*.d.ts',
    '!src/**/*.test.ts'
  ],
  coverageThreshold: {
    global: {
      branches: 80,
      functions: 80,
      lines: 80,
      statements: 80
    }
  },
  testTimeout: 30000, // 30 seconds for integration tests
  maxWorkers: 4, // Limit concurrent test workers
};

// Test runner script would be:
// npm test -- --coverage --verbose

// =============================================
// FRONTEND ARCHITECTURE - TYPESCRIPT REACT
// =============================================

import React, { 
  createContext, 
  useContext, 
  useReducer, 
  useEffect, 
  useState, 
  useCallback 
} from 'react';
import { 
  ScriptDefinition, 
  ProcessHandle, 
  ExecutionResult,
  ScriptCategory,
  ExecutionState,
  ScriptTemplate,
  SystemEvent
} from '../shared/domain-contracts';

// =============================================
// STATE MANAGEMENT - CONTEXT + REDUCER
// =============================================

interface AppState {
  scripts: ScriptDefinition[];
  activeExecutions: ProcessHandle[];
  templates: ScriptTemplate[];
  systemStatus: 'initializing' | 'ready' | 'error';
  notifications: NotificationMessage[];
  selectedScript: ScriptDefinition | null;
  executionHistory: ExecutionResult[];
}

interface NotificationMessage {
  id: string;
  level: 'info' | 'success' | 'warning' | 'error';
  message: string;
  timestamp: number;
  scriptId?: string;
}

type AppAction = 
  | { type: 'SYSTEM_READY' }
  | { type: 'SYSTEM_ERROR'; error: string }
  | { type: 'SCRIPTS_LOADED'; scripts: ScriptDefinition[] }
  | { type: 'SCRIPT_CREATED'; script: ScriptDefinition }
  | { type: 'SCRIPT_UPDATED'; script: ScriptDefinition }
  | { type: 'SCRIPT_DELETED'; scriptId: string }
  | { type: 'EXECUTIONS_UPDATED'; executions: ProcessHandle[] }
  | { type: 'EXECUTION_COMPLETED'; result: ExecutionResult }
  | { type: 'NOTIFICATION_ADDED'; notification: NotificationMessage }
  | { type: 'NOTIFICATION_REMOVED'; notificationId: string }
  | { type: 'SCRIPT_SELECTED'; script: ScriptDefinition | null }
  | { type: 'TEMPLATES_LOADED'; templates: ScriptTemplate[] };

const initialState: AppState = {
  scripts: [],
  activeExecutions: [],
  templates: [],
  systemStatus: 'initializing',
  notifications: [],
  selectedScript: null,
  executionHistory: []
};

function appReducer(state: AppState, action: AppAction): AppState {
  switch (action.type) {
    case 'SYSTEM_READY':
      return { ...state, systemStatus: 'ready' };
    
    case 'SYSTEM_ERROR':
      return { 
        ...state, 
        systemStatus: 'error',
        notifications: [...state.notifications, {
          id: Date.now().toString(),
          level: 'error',
          message: action.error,
          timestamp: Date.now()
        }]
      };
    
    case 'SCRIPTS_LOADED':
      return { ...state, scripts: action.scripts };
    
    case 'SCRIPT_CREATED':
      return { 
        ...state, 
        scripts: [...state.scripts, action.script],
        selectedScript: action.script
      };
    
    case 'SCRIPT_UPDATED':
      return {
        ...state,
        scripts: state.scripts.map(s => 
          s.id === action.script.id ? action.script : s
        ),
        selectedScript: state.selectedScript?.id === action.script.id 
          ? action.script 
          : state.selectedScript
      };
    
    case 'SCRIPT_DELETED':
      return {
        ...state,
        scripts: state.scripts.filter(s => s.id !== action.scriptId),
        selectedScript: state.selectedScript?.id === action.scriptId 
          ? null 
          : state.selectedScript
      };
    
    case 'EXECUTIONS_UPDATED':
      return { ...state, activeExecutions: action.executions };
    
    case 'EXECUTION_COMPLETED':
      return {
        ...state,
        executionHistory: [action.result, ...state.executionHistory.slice(0, 99)], // Keep last 100
        activeExecutions: state.activeExecutions.filter(
          exec => exec.processId !== action.result.processId
        )
      };
    
    case 'NOTIFICATION_ADDED':
      return {
        ...state,
        notifications: [action.notification, ...state.notifications.slice(0, 49)] // Keep last 50
      };
    
    case 'NOTIFICATION_REMOVED':
      return {
        ...state,
        notifications: state.notifications.filter(n => n.id !== action.notificationId)
      };
    
    case 'SCRIPT_SELECTED':
      return { ...state, selectedScript: action.script };
    
    case 'TEMPLATES_LOADED':
      return { ...state, templates: action.templates };
    
    default:
      return state;
  }
}

// =============================================
// CONTEXT PROVIDERS
// =============================================

interface AppContextValue {
  state: AppState;
  dispatch: React.Dispatch<AppAction>;
  actions: AppActions;
}

const AppContext = createContext<AppContextValue | null>(null);

export function useAppContext(): AppContextValue {
  const context = useContext(AppContext);
  if (!context) {
    throw new Error('useAppContext must be used within AppProvider');
  }
  return context;
}

// =============================================
// API CLIENT
// =============================================

class VibeAPIClient {
  private baseUrl: string;
  private eventSource: EventSource | null = null;

  constructor(baseUrl = 'http://localhost:3001') {
    this.baseUrl = baseUrl;
  }

  async getScripts(category?: ScriptCategory): Promise<ScriptDefinition[]> {
    const url = category 
      ? `${this.baseUrl}/api/scripts?category=${category}`
      : `${this.baseUrl}/api/scripts`;
    
    const response = await fetch(url);
    if (!response.ok) throw new Error('Failed to fetch scripts');
    return response.json();
  }

  async createScript(
    templateId: string, 
    config: unknown, 
    metadata: Partial<ScriptMetadata>
  ): Promise<ScriptDefinition> {
    const response = await fetch(`${this.baseUrl}/api/scripts`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ templateId, config, metadata })
    });
    
    if (!response.ok) throw new Error('Failed to create script');
    return response.json();
  }

  async updateScript(scriptId: string, updates: Partial<ScriptDefinition>): Promise<void> {
    const response = await fetch(`${this.baseUrl}/api/scripts/${scriptId}`, {
      method: 'PATCH',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(updates)
    });
    
    if (!response.ok) throw new Error('Failed to update script');
  }

  async deleteScript(scriptId: string): Promise<void> {
    const response = await fetch(`${this.baseUrl}/api/scripts/${scriptId}`, {
      method: 'DELETE'
    });
    
    if (!response.ok) throw new Error('Failed to delete script');
  }

  async executeScript(scriptId: string): Promise<ExecutionResult> {
    const response = await fetch(`${this.baseUrl}/api/scripts/${scriptId}/execute`, {
      method: 'POST'
    });
    
    if (!response.ok) throw new Error('Failed to execute script');
    return response.json();
  }

  async scheduleScript(scriptId: string): Promise<void> {
    const response = await fetch(`${this.baseUrl}/api/scripts/${scriptId}/schedule`, {
      method: 'POST'
    });
    
    if (!response.ok) throw new Error('Failed to schedule script');
  }

  async getActiveExecutions(): Promise<ProcessHandle[]> {
    const response = await fetch(`${this.baseUrl}/api/executions/active`);
    if (!response.ok) throw new Error('Failed to fetch active executions');
    return response.json();
  }

  async getTemplates(category?: ScriptCategory): Promise<ScriptTemplate[]> {
    const url = category 
      ? `${this.baseUrl}/api/templates?category=${category}`
      : `${this.baseUrl}/api/templates`;
    
    const response = await fetch(url);
    if (!response.ok) throw new Error('Failed to fetch templates');
    return response.json();
  }

  subscribeToEvents(onEvent: (event: SystemEvent) => void): () => void {
    this.eventSource = new EventSource(`${this.baseUrl}/api/events`);
    
    this.eventSource.onmessage = (event) => {
      try {
        const systemEvent = JSON.parse(event.data);
        onEvent(systemEvent);
      } catch (error) {
        console.error('Failed to parse event:', error);
      }
    };

    this.eventSource.onerror = (error) => {
      console.error('EventSource error:', error);
    };

    return () => {
      if (this.eventSource) {
        this.eventSource.close();
        this.eventSource = null;
      }
    };
  }
}

// =============================================
// APP ACTIONS
// =============================================

interface AppActions {
  loadScripts: (category?: ScriptCategory) => Promise<void>;
  createScript: (templateId: string, config: unknown, metadata: Partial<ScriptMetadata>) => Promise<void>;
  updateScript: (scriptId: string, updates: Partial<ScriptDefinition>) => Promise<void>;
  deleteScript: (scriptId: string) => Promise<void>;
  executeScript: (scriptId: string) => Promise<void>;
  scheduleScript: (scriptId: string) => Promise<void>;
  selectScript: (script: ScriptDefinition | null) => void;
  loadTemplates: (category?: ScriptCategory) => Promise<void>;
  removeNotification: (notificationId: string) => void;
}

function useAppActions(
  dispatch: React.Dispatch<AppAction>, 
  apiClient: VibeAPIClient
): AppActions {
  const addNotification = useCallback((
    level: NotificationMessage['level'], 
    message: string, 
    scriptId?: string
  ) => {
    dispatch({
      type: 'NOTIFICATION_ADDED',
      notification: {
        id: Date.now().toString(),
        level,
        message,
        timestamp: Date.now(),
        scriptId
      }
    });
  }, [dispatch]);

  return {
    loadScripts: useCallback(async (category?: ScriptCategory) => {
      try {
        const scripts = await apiClient.getScripts(category);
        dispatch({ type: 'SCRIPTS_LOADED', scripts });
      } catch (error) {
        addNotification('error', `Failed to load scripts: ${error.message}`);
      }
    }, [apiClient, dispatch, addNotification]),

    createScript: useCallback(async (templateId, config, metadata) => {
      try {
        const script = await apiClient.createScript(templateId, config, metadata);
        dispatch({ type: 'SCRIPT_CREATED', script });
        addNotification('success', `Script "${script.name}" created successfully`);
      } catch (error) {
        addNotification('error', `Failed to create script: ${error.message}`);
      }
    }, [apiClient, dispatch, addNotification]),

    updateScript: useCallback(async (scriptId, updates) => {
      try {
        await apiClient.updateScript(scriptId, updates);
        const scripts = await apiClient.getScripts();
        const updatedScript = scripts.find(s => s.id === scriptId);
        if (updatedScript) {
          dispatch({ type: 'SCRIPT_UPDATED', script: updatedScript });
          addNotification('success', 'Script updated successfully');
        }
      } catch (error) {
        addNotification('error', `Failed to update script: ${error.message}`);
      }
    }, [apiClient, dispatch, addNotification]),

    deleteScript: useCallback(async (scriptId) => {
      try {
        await apiClient.deleteScript(scriptId);
        dispatch({ type: 'SCRIPT_DELETED', scriptId });
        addNotification('success', 'Script deleted successfully');
      } catch (error) {
        addNotification('error', `Failed to delete script: ${error.message}`);
      }
    }, [apiClient, dispatch, addNotification]),

    executeScript: useCallback(async (scriptId) => {
      try {
        const result = await apiClient.executeScript(scriptId);
        addNotification('info', `Script execution started`, scriptId);
        // Execution completion will be handled by event stream
      } catch (error) {
        addNotification('error', `Failed to execute script: ${error.message}`, scriptId);
      }
    }, [apiClient, addNotification]),

    scheduleScript: useCallback(async (scriptId) => {
      try {
        await apiClient.scheduleScript(scriptId);
        addNotification('success', 'Script scheduled successfully', scriptId);
      } catch (error) {
        addNotification('error', `Failed to schedule script: ${error.message}`, scriptId);
      }
    }, [apiClient, addNotification]),

    selectScript: useCallback((script) => {
      dispatch({ type: 'SCRIPT_SELECTED', script });
    }, [dispatch]),

    loadTemplates: useCallback(async (category?: ScriptCategory) => {
      try {
        const templates = await apiClient.getTemplates(category);
        dispatch({ type: 'TEMPLATES_LOADED', templates });
      } catch (error) {
        addNotification('error', `Failed to load templates: ${error.message}`);
      }
    }, [apiClient, dispatch, addNotification]),

    removeNotification: useCallback((notificationId) => {
      dispatch({ type: 'NOTIFICATION_REMOVED', notificationId });
    }, [dispatch])
  };
}

// =============================================
// APP PROVIDER
// =============================================

interface AppProviderProps {
  children: React.ReactNode;
  apiClient?: VibeAPIClient;
}

export function AppProvider({ children, apiClient = new VibeAPIClient() }: AppProviderProps) {
  const [state, dispatch] = useReducer(appReducer, initialState);
  const actions = useAppActions(dispatch, apiClient);

  // Initialize app
  useEffect(() => {
    const initializeApp = async () => {
      try {
        // Load initial data
        await Promise.all([
          actions.loadScripts(),
          actions.loadTemplates()
        ]);

        dispatch({ type: 'SYSTEM_READY' });
      } catch (error) {
        dispatch({ type: 'SYSTEM_ERROR', error: error.message });
      }
    };

    initializeApp();
  }, [actions]);

  // Subscribe to real-time events
  useEffect(() => {
    const unsubscribe = apiClient.subscribeToEvents((event) => {
      switch (event.type) {
        case 'script.execution':
          if (event.state === 'completed' || event.state === 'failed') {
            // Refresh executions
            apiClient.getActiveExecutions().then(executions => {
              dispatch({ type: 'EXECUTIONS_UPDATED', executions });
            });
          }
          break;
        
        case 'state.change':
          // Handle state changes if needed
          break;
        
        case 'system.health':
          if (event.status !== 'healthy') {
            dispatch({
              type: 'NOTIFICATION_ADDED',
              notification: {
                id: Date.now().toString(),
                level: event.status === 'unhealthy' ? 'error' : 'warning',
                message: `System ${event.component}: ${event.message}`,
                timestamp: event.timestamp
              }
            });
          }
          break;
      }
    });

    return unsubscribe;
  }, [apiClient]);

  // Poll active executions
  useEffect(() => {
    const pollExecutions = () => {
      apiClient.getActiveExecutions().then(executions => {
        dispatch({ type: 'EXECUTIONS_UPDATED', executions });
      }).catch(error => {
        console.error('Failed to poll executions:', error);
      });
    };

    // Poll every 5 seconds
    const interval = setInterval(pollExecutions, 5000);
    
    // Initial poll
    pollExecutions();

    return () => clearInterval(interval);
  }, [apiClient]);

  const contextValue: AppContextValue = {
    state,
    dispatch,
    actions
  };

  return (
    <AppContext.Provider value={contextValue}>
      {children}
    </AppContext.Provider>
  );
}

// =============================================
// CORE COMPONENTS
// =============================================

// Dashboard Component
export function Dashboard() {
  const { state } = useAppContext();
  
  const stats = {
    totalScripts: state.scripts.length,
    activeExecutions: state.activeExecutions.length,
    scheduledScripts: state.scripts.filter(s => s.category === 'scheduled').length,
    recentExecutions: state.executionHistory.slice(0, 5)
  };

  return (
    <div className="space-y-6">
      <div className="grid grid-cols-1 md:grid-cols-3 gap-6">
        <StatCard
          title="Total Scripts"
          value={stats.totalScripts}
          icon="📝"
          color="blue"
        />
        <StatCard
          title="Active Executions"
          value={stats.activeExecutions}
          icon="🏃"
          color="green"
        />
        <StatCard
          title="Scheduled Scripts"
          value={stats.scheduledScripts}
          icon="⏰"
          color="orange"
        />
      </div>

      <div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
        <ActiveExecutionsPanel executions={state.activeExecutions} />
        <RecentActivityPanel 
          executions={state.executionHistory} 
          notifications={state.notifications}
        />
      </div>
    </div>
  );
}

// Script Library Component
export function ScriptLibrary() {
  const { state, actions } = useAppContext();
  const [selectedCategory, setSelectedCategory] = useState<ScriptCategory | 'all'>('all');
  const [searchTerm, setSearchTerm] = useState('');

  const filteredScripts = state.scripts.filter(script => {
    const matchesCategory = selectedCategory === 'all' || script.category === selectedCategory;
    const matchesSearch = script.name.toLowerCase().includes(searchTerm.toLowerCase()) ||
                         script.metadata.description.toLowerCase().includes(searchTerm.toLowerCase());
    return matchesCategory && matchesSearch;
  });

  return (
    <div className="space-y-6">
      <div className="flex flex-col md:flex-row md:items-center md:justify-between space-y-4 md:space-y-0">
        <div className="flex items-center space-x-4">
          <CategoryFilter 
            value={selectedCategory}
            onChange={setSelectedCategory}
          />
          <SearchInput
            value={searchTerm}
            onChange={setSearchTerm}
            placeholder="Search scripts..."
          />
        </div>
        <CreateScriptButton />
      </div>

      <ScriptGrid
        scripts={filteredScripts}
        onScriptSelect={actions.selectScript}
        onScriptExecute={actions.executeScript}
        onScriptSchedule={actions.scheduleScript}
        onScriptDelete={actions.deleteScript}
      />
    </div>
  );
}

// Script Editor Component
export function ScriptEditor() {
  const { state, actions } = useAppContext();
  const [isEditing, setIsEditing] = useState(false);
  const [editedScript, setEditedScript] = useState<ScriptDefinition | null>(null);

  useEffect(() => {
    setEditedScript(state.selectedScript);
    setIsEditing(false);
  }, [state.selectedScript]);

  const handleSave = async () => {
    if (editedScript) {
      await actions.updateScript(editedScript.id, editedScript);
      setIsEditing(false);
    }
  };

  if (!state.selectedScript) {
    return (
      <div className="flex items-center justify-center h-96">
        <div className="text-center">
          <div className="text-6xl mb-4">📝</div>
          <h3 className="text-xl font-semibold mb-2">No Script Selected</h3>
          <p className="text-gray-600">Select a script from the library to view or edit</p>
        </div>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <ScriptHeader 
        script={state.selectedScript}
        isEditing={isEditing}
        onEdit={() => setIsEditing(true)}
        onSave={handleSave}
        onCancel={() => setIsEditing(false)}
        onExecute={() => actions.executeScript(state.selectedScript!.id)}
      />

      <div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
        <div className="lg:col-span-2">
          <CodeEditor
            script={editedScript || state.selectedScript}
            isEditable={isEditing}
            onChange={setEditedScript}
          />
        </div>
        <div className="space-y-6">
          <ScriptMetadataPanel 
            script={editedScript || state.selectedScript}
            isEditable={isEditing}
            onChange={setEditedScript}
          />
          <ScriptConfigPanel 
            script={editedScript || state.selectedScript}
            isEditable={isEditing}
            onChange={setEditedScript}
          />
        </div>
      </div>
    </div>
  );
}

// Template Gallery Component
export function TemplateGallery() {
  const { state, actions } = useAppContext();
  const [selectedCategory, setSelectedCategory] = useState<ScriptCategory | 'all'>('all');
  const [selectedTemplate, setSelectedTemplate] = useState<ScriptTemplate | null>(null);

  const filteredTemplates = state.templates.filter(template => 
    selectedCategory === 'all' || template.category === selectedCategory
  );

  return (
    <div className="space-y-6">
      <div className="flex items-center justify-between">
        <h2 className="text-2xl font-bold">Script Templates</h2>
        <CategoryFilter 
          value={selectedCategory}
          onChange={setSelectedCategory}
        />
      </div>

      <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
        {filteredTemplates.map(template => (
          <TemplateCard
            key={template.id}
            template={template}
            onSelect={setSelectedTemplate}
          />
        ))}
      </div>

      {selectedTemplate && (
        <TemplateConfigModal
          template={selectedTemplate}
          onClose={() => setSelectedTemplate(null)}
          onCreate={actions.createScript}
        />
      )}
    </div>
  );
}

// =============================================
// UTILITY COMPONENTS
// =============================================

interface StatCardProps {
  title: string;
  value: number;
  icon: string;
  color: 'blue' | 'green' | 'orange' | 'red';
}

function StatCard({ title, value, icon, color }: StatCardProps) {
  const colorClasses = {
    blue: 'bg-blue-500 border-blue-600',
    green: 'bg-green-500 border-green-600',
    orange: 'bg-orange-500 border-orange-600',
    red: 'bg-red-500 border-red-600'
  };

  return (
    <div className={`${colorClasses[color]} border-4 border-black shadow-brutal p-6 text-white`}>
      <div className="flex items-center justify-between">
        <div>
          <p className="text-3xl font-black mb-2">{value}</p>
          <p className="font-bold uppercase tracking-wider">{title}</p>
        </div>
        <div className="text-4xl">{icon}</div>
      </div>
    </div>
  );
}

// Additional component implementations would follow...
// This provides the foundation for the complete frontend architecture

// =============================================
// ERROR HANDLING & MONITORING SYSTEM
// =============================================

import { EventEmitter } from 'events';
import { createWriteStream, WriteStream } from 'fs';
import { join } from 'path';
import { 
  VibeCodeError, 
  ScriptId, 
  ProcessId, 
  SystemEvent,
  ExecutionState,
  Timestamp 
} from './domain-contracts';

// =============================================
// ERROR CLASSIFICATION SYSTEM
// =============================================

export enum ErrorSeverity {
  LOW = 'low',
  MEDIUM = 'medium',
  HIGH = 'high',
  CRITICAL = 'critical'
}

export enum ErrorCategory {
  USER_ERROR = 'user_error',           // Script syntax, config errors
  SYSTEM_ERROR = 'system_error',       // Runtime, memory, disk issues
  DEPENDENCY_ERROR = 'dependency_error', // Missing libraries, system deps
  NETWORK_ERROR = 'network_error',     // API calls, web scraping failures
  PERMISSION_ERROR = 'permission_error', // File access, system permissions
  TIMEOUT_ERROR = 'timeout_error',     // Script execution timeouts
  RECOVERY_ERROR = 'recovery_error'    // Crash recovery failures
}

interface ErrorContext {
  readonly errorId: string;
  readonly timestamp: Timestamp;
  readonly severity: ErrorSeverity;
  readonly category: ErrorCategory;
  readonly message: string;
  readonly stack?: string;
  readonly scriptId?: ScriptId;
  readonly processId?: ProcessId;
  readonly metadata: Record<string, unknown>;
  readonly recoverable: boolean;
  readonly retryCount: number;
}

// =============================================
// ERROR RECOVERY STRATEGIES
// =============================================

interface RecoveryStrategy {
  canRecover(error: ErrorContext): boolean;
  recover(error: ErrorContext): Promise<RecoveryResult>;
  getPriority(): number;
}

interface RecoveryResult {
  success: boolean;
  message: string;
  nextRetryDelay?: number;
  preventFutureRetries?: boolean;
}

class DependencyRecoveryStrategy implements RecoveryStrategy {
  canRecover(error: ErrorContext): boolean {
    return error.category === ErrorCategory.DEPENDENCY_ERROR 
           && error.retryCount < 3;
  }

  async recover(error: ErrorContext): Promise<RecoveryResult> {
    try {
      // Attempt to reinstall missing dependencies
      const missingDep = error.metadata.dependency as string;
      
      if (missingDep) {
        // Trigger dependency reinstallation
        await this.reinstallDependency(missingDep);
        
        return {
          success: true,
          message: `Successfully reinstalled dependency: ${missingDep}`,
          nextRetryDelay: 5000 // 5 seconds
        };
      }
      
      return {
        success: false,
        message: 'Could not identify missing dependency'
      };
      
    } catch (recoveryError) {
      return {
        success: false,
        message: `Recovery failed: ${recoveryError.message}`,
        preventFutureRetries: true
      };
    }
  }

  getPriority(): number {
    return 100; // High priority
  }

  private async reinstallDependency(dependency: string): Promise<void> {
    // Implementation would trigger dependency manager
    console.log(`Reinstalling dependency: ${dependency}`);
  }
}

class ResourceRecoveryStrategy implements RecoveryStrategy {
  canRecover(error: ErrorContext): boolean {
    return error.category === ErrorCategory.SYSTEM_ERROR 
           && error.metadata.resourceType === 'memory'
           && error.retryCount < 2;
  }

  async recover(error: ErrorContext): Promise<RecoveryResult> {
    try {
      // Clear caches and reduce memory usage
      await this.freeMemoryResources();
      
      // Reduce script resource limits
      const newMemoryLimit = (error.metadata.memoryLimit as number) * 0.8;
      
      return {
        success: true,
        message: `Reduced memory limit to ${newMemoryLimit}MB`,
        nextRetryDelay: 10000 // 10 seconds
      };
      
    } catch (recoveryError) {
      return {
        success: false,
        message: `Memory recovery failed: ${recoveryError.message}`
      };
    }
  }

  getPriority(): number {
    return 80; // Medium-high priority
  }

  private async freeMemoryResources(): Promise<void> {
    // Force garbage collection if available
    if (global.gc) {
      global.gc();
    }
    
    // Clear internal caches
    // Implementation would clear various caches
  }
}

class TimeoutRecoveryStrategy implements RecoveryStrategy {
  canRecover(error: ErrorContext): boolean {
    return error.category === ErrorCategory.TIMEOUT_ERROR 
           && error.retryCount < 1;
  }

  async recover(error: ErrorContext): Promise<RecoveryResult> {
    const currentTimeout = error.metadata.timeout as number;
    const newTimeout = Math.min(currentTimeout * 1.5, 600000); // Max 10 minutes
    
    return {
      success: true,
      message: `Increased timeout from ${currentTimeout}ms to ${newTimeout}ms`,
      nextRetryDelay: 2000 // 2 seconds
    };
  }

  getPriority(): number {
    return 60; // Medium priority
  }
}

// =============================================
// ERROR MONITORING & RECOVERY ENGINE
// =============================================

export class ErrorMonitoringEngine extends EventEmitter {
  private readonly recoveryStrategies: RecoveryStrategy[];
  private readonly errorHistory: Map<string, ErrorContext[]> = new Map();
  private readonly recoveryAttempts: Map<string, number> = new Map();
  private readonly logStream: WriteStream;

  constructor(private readonly config: MonitoringConfig) {
    super();
    
    this.recoveryStrategies = [
      new DependencyRecoveryStrategy(),
      new ResourceRecoveryStrategy(),
      new TimeoutRecoveryStrategy()
    ].sort((a, b) => b.getPriority() - a.getPriority());

    this.logStream = createWriteStream(
      join(config.logsDirectory, 'errors.log'),
      { flags: 'a' }
    );
  }

  async handleError(
    error: Error | VibeCodeError, 
    context: Partial<ErrorContext> = {}
  ): Promise<void> {
    const errorContext = this.createErrorContext(error, context);
    
    // Log the error
    await this.logError(errorContext);
    
    // Store in history
    this.addToHistory(errorContext);
    
    // Emit monitoring event
    this.emit('error.detected', errorContext);
    
    // Attempt recovery if applicable
    if (errorContext.recoverable) {
      await this.attemptRecovery(errorContext);
    }
    
    // Check for error patterns
    this.analyzeErrorPatterns(errorContext);
  }

  private createErrorContext(
    error: Error | VibeCodeError, 
    context: Partial<ErrorContext>
  ): ErrorContext {
    const isVibeError = error instanceof VibeCodeError;
    
    return {
      errorId: this.generateErrorId(),
      timestamp: Date.now() as Timestamp,
      severity: this.determineSeverity(error, context),
      category: this.categorizeError(error, context),
      message: error.message,
      stack: error.stack,
      scriptId: context.scriptId,
      processId: context.processId,
      metadata: {
        ...context.metadata,
        errorType: error.constructor.name,
        ...(isVibeError && { vibeErrorCode: error.code })
      },
      recoverable: isVibeError ? error.recoverable : this.isRecoverable(error, context),
      retryCount: this.getRetryCount(context.scriptId, context.processId),
      ...context
    };
  }

  private determineSeverity(
    error: Error | VibeCodeError, 
    context: Partial<ErrorContext>
  ): ErrorSeverity {
    // Critical: System-wide failures
    if (error.message.includes('ENOSPC') || error.message.includes('out of memory')) {
      return ErrorSeverity.CRITICAL;
    }
    
    // High: Process crashes, data corruption
    if (error.message.includes('SEGFAULT') || 
        error.message.includes('corruption') ||
        context.metadata?.cascadeFailure) {
      return ErrorSeverity.HIGH;
    }
    
    // Medium: Script failures, dependency issues
    if (error instanceof VibeCodeError || 
        error.message.includes('ModuleNotFoundError')) {
      return ErrorSeverity.MEDIUM;
    }
    
    // Low: User configuration errors
    return ErrorSeverity.LOW;
  }

  private categorizeError(
    error: Error | VibeCodeError, 
    context: Partial<ErrorContext>
  ): ErrorCategory {
    const message = error.message.toLowerCase();
    
    if (message.includes('modulenotfound') || 
        message.includes('import') ||
        message.includes('dependency')) {
      return ErrorCategory.DEPENDENCY_ERROR;
    }
    
    if (message.includes('timeout') || 
        message.includes('timed out')) {
      return ErrorCategory.TIMEOUT_ERROR;
    }
    
    if (message.includes('permission') || 
        message.includes('access denied') ||
        message.includes('eacces')) {
      return ErrorCategory.PERMISSION_ERROR;
    }
    
    if (message.includes('network') || 
        message.includes('connection') ||
        message.includes('fetch')) {
      return ErrorCategory.NETWORK_ERROR;
    }
    
    if (message.includes('memory') || 
        message.includes('disk') ||
        message.includes('enospc')) {
      return ErrorCategory.SYSTEM_ERROR;
    }
    
    if (message.includes('syntax') || 
        message.includes('invalid') ||
        context.metadata?.userGenerated) {
      return ErrorCategory.USER_ERROR;
    }
    
    return ErrorCategory.SYSTEM_ERROR; // Default
  }

  private isRecoverable(error: Error, context: Partial<ErrorContext>): boolean {
    const nonRecoverablePatterns = [
      'SEGFAULT',
      'out of memory',
      'disk full',
      'permission denied'
    ];
    
    return !nonRecoverablePatterns.some(pattern => 
      error.message.toLowerCase().includes(pattern.toLowerCase())
    );
  }

  private async attemptRecovery(errorContext: ErrorContext): Promise<void> {
    for (const strategy of this.recoveryStrategies) {
      if (strategy.canRecover(errorContext)) {
        try {
          this.emit('recovery.attempting', { 
            errorId: errorContext.errorId, 
            strategy: strategy.constructor.name 
          });
          
          const result = await strategy.recover(errorContext);
          
          if (result.success) {
            this.emit('recovery.success', { 
              errorId: errorContext.errorId, 
              strategy: strategy.constructor.name,
              message: result.message 
            });
            
            // Schedule retry if applicable
            if (result.nextRetryDelay && errorContext.scriptId) {
              setTimeout(() => {
                this.emit('retry.scheduled', {
                  scriptId: errorContext.scriptId,
                  delay: result.nextRetryDelay
                });
              }, result.nextRetryDelay);
            }
            
            return; // Recovery successful, stop trying other strategies
          } else {
            this.emit('recovery.failed', { 
              errorId: errorContext.errorId, 
              strategy: strategy.constructor.name,
              message: result.message 
            });
            
            if (result.preventFutureRetries) {
              break; // Stop all recovery attempts
            }
          }
          
        } catch (recoveryError) {
          this.emit('recovery.error', { 
            errorId: errorContext.errorId, 
            strategy: strategy.constructor.name,
            error: recoveryError.message 
          });
        }
      }
    }
  }

  private async logError(errorContext: ErrorContext): Promise<void> {
    const logEntry = {
      timestamp: new Date(errorContext.timestamp).toISOString(),
      errorId: errorContext.errorId,
      severity: errorContext.severity,
      category: errorContext.category,
      message: errorContext.message,
      scriptId: errorContext.scriptId,
      processId: errorContext.processId,
      metadata: errorContext.metadata,
      stack: errorContext.stack
    };
    
    this.logStream.write(JSON.stringify(logEntry) + '\n');
    
    // Also log to console in development
    if (this.config.environment === 'development') {
      console.error('VibeCodeRehab Error:', logEntry);
    }
  }

  private addToHistory(errorContext: ErrorContext): void {
    const key = errorContext.scriptId || 'system';
    
    if (!this.errorHistory.has(key)) {
      this.errorHistory.set(key, []);
    }
    
    const history = this.errorHistory.get(key)!;
    history.unshift(errorContext);
    
    // Keep only last 100 errors per script
    if (history.length > 100) {
      history.splice(100);
    }
  }

  private analyzeErrorPatterns(errorContext: ErrorContext): void {
    const key = errorContext.scriptId || 'system';
    const history = this.errorHistory.get(key) || [];
    
    // Check for rapid failure pattern (5 failures in 5 minutes)
    const recentErrors = history.filter(e => 
      e.timestamp > Date.now() - 300000 // 5 minutes
    );
    
    if (recentErrors.length >= 5) {
      this.emit('pattern.rapid_failure', {
        scriptId: errorContext.scriptId,
        errorCount: recentErrors.length,
        timeWindow: '5m'
      });
    }
    
    // Check for recurring error pattern (same error type 3+ times)
    const sameTypeErrors = history.filter(e => 
      e.category === errorContext.category &&
      e.message === errorContext.message
    ).slice(0, 10); // Check last 10 errors
    
    if (sameTypeErrors.length >= 3) {
      this.emit('pattern.recurring_error', {
        scriptId: errorContext.scriptId,
        errorCategory: errorContext.category,
        occurrences: sameTypeErrors.length
      });
    }
  }

  private generateErrorId(): string {
    return `err_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
  }

  private getRetryCount(scriptId?: ScriptId, processId?: ProcessId): number {
    const key = processId || scriptId || 'unknown';
    return this.recoveryAttempts.get(key) || 0;
  }

  getErrorHistory(scriptId?: ScriptId): ErrorContext[] {
    if (scriptId) {
      return this.errorHistory.get(scriptId) || [];
    }
    
    // Return all errors
    const allErrors: ErrorContext[] = [];
    for (const errors of this.errorHistory.values()) {
      allErrors.push(...errors);
    }
    
    return allErrors.sort((a, b) => b.timestamp - a.timestamp);
  }

  getErrorStats(): ErrorStats {
    const allErrors = this.getErrorHistory();
    const last24h = allErrors.filter(e => 
      e.timestamp > Date.now() - 86400000 // 24 hours
    );
    
    const bySeverity = {
      [ErrorSeverity.CRITICAL]: last24h.filter(e => e.severity === ErrorSeverity.CRITICAL).length,
      [ErrorSeverity.HIGH]: last24h.filter(e => e.severity === ErrorSeverity.HIGH).length,
      [ErrorSeverity.MEDIUM]: last24h.filter(e => e.severity === ErrorSeverity.MEDIUM).length,
      [ErrorSeverity.LOW]: last24h.filter(e => e.severity === ErrorSeverity.LOW).length
    };
    
    const byCategory = Object.values(ErrorCategory).reduce((acc, category) => {
      acc[category] = last24h.filter(e => e.category === category).length;
      return acc;
    }, {} as Record<ErrorCategory, number>);
    
    const recoveryRate = allErrors.length > 0 
      ? (allErrors.filter(e => e.recoverable).length / allErrors.length) * 100
      : 100;
    
    return {
      totalErrors: allErrors.length,
      last24h: last24h.length,
      bySeverity,
      byCategory,
      recoveryRate: Math.round(recoveryRate * 100) / 100
    };
  }

  async shutdown(): Promise<void> {
    return new Promise((resolve) => {
      this.logStream.end(() => {
        this.removeAllListeners();
        resolve();
      });
    });
  }
}

// =============================================
// HEALTH MONITORING SYSTEM
// =============================================

export class HealthMonitor extends EventEmitter {
  private healthChecks: Map<string, HealthCheck> = new Map();
  private healthStatus: Map<string, HealthStatus> = new Map();
  private monitoringInterval?: NodeJS.Timeout;

  constructor(private readonly config: HealthConfig) {
    super();
    this.setupCoreHealthChecks();
  }

  private setupCoreHealthChecks(): void {
    // System resource health check
    this.addHealthCheck({
      name: 'system_resources',
      description: 'Monitor CPU, memory, and disk usage',
      interval: 30000, // 30 seconds
      check: async () => {
        const usage = await this.getSystemResourceUsage();
        
        if (usage.memory > 90 || usage.cpu > 95 || usage.disk > 95) {
          return {
            healthy: false,
            message: `High resource usage: CPU ${usage.cpu}%, Memory ${usage.memory}%, Disk ${usage.disk}%`,
            details: usage
          };
        }
        
        return {
          healthy: true,
          message: `Resources normal: CPU ${usage.cpu}%, Memory ${usage.memory}%, Disk ${usage.disk}%`,
          details: usage
        };
      }
    });

    // Python runtime health check
    this.addHealthCheck({
      name: 'python_runtime',
      description: 'Verify Python interpreter is functional',
      interval: 60000, // 1 minute
      check: async () => {
        try {
          // Test Python interpreter
          const testResult = await this.testPythonRuntime();
          return {
            healthy: testResult.success,
            message: testResult.message,
            details: testResult
          };
        } catch (error) {
          return {
            healthy: false,
            message: `Python runtime check failed: ${error.message}`,
            details: { error: error.message }
          };
        }
      }
    });

    // Database health check
    this.addHealthCheck({
      name: 'database',
      description: 'Check database connectivity and performance',
      interval: 45000, // 45 seconds
      check: async () => {
        try {
          const dbHealth = await this.checkDatabaseHealth();
          return {
            healthy: dbHealth.responsive && dbHealth.queryTime < 1000,
            message: dbHealth.responsive 
              ? `Database responsive (${dbHealth.queryTime}ms)`
              : 'Database not responding',
            details: dbHealth
          };
        } catch (error) {
          return {
            healthy: false,
            message: `Database health check failed: ${error.message}`,
            details: { error: error.message }
          };
        }
      }
    });
  }

  addHealthCheck(healthCheck: HealthCheck): void {
    this.healthChecks.set(healthCheck.name, healthCheck);
    this.healthStatus.set(healthCheck.name, {
      name: healthCheck.name,
      healthy: true,
      lastCheck: Date.now() as Timestamp,
      message: 'Health check added',
      details: {}
    });
  }

  start(): void {
    if (this.monitoringInterval) {
      return; // Already running
    }

    this.monitoringInterval = setInterval(async () => {
      await this.runHealthChecks();
    }, this.config.checkInterval);

    // Run initial health checks
    this.runHealthChecks();

    this.emit('monitoring.started');
  }

  stop(): void {
    if (this.monitoringInterval) {
      clearInterval(this.monitoringInterval);
      this.monitoringInterval = undefined;
    }

    this.emit('monitoring.stopped');
  }

  private async runHealthChecks(): Promise<void> {
    const promises = Array.from(this.healthChecks.values()).map(async (check) => {
      try {
        const result = await check.check();
        const status: HealthStatus = {
          name: check.name,
          healthy: result.healthy,
          lastCheck: Date.now() as Timestamp,
          message: result.message,
          details: result.details
        };

        const previousStatus = this.healthStatus.get(check.name);
        this.healthStatus.set(check.name, status);

        // Emit status change events
        if (!previousStatus || previousStatus.healthy !== status.healthy) {
          this.emit('health.status_change', {
            name: check.name,
            healthy: status.healthy,
            previouslyHealthy: previousStatus?.healthy,
            message: status.message
          });
        }

      } catch (error) {
        const status: HealthStatus = {
          name: check.name,
          healthy: false,
          lastCheck: Date.now() as Timestamp,
          message: `Health check error: ${error.message}`,
          details: { error: error.message }
        };

        this.healthStatus.set(check.name, status);
        
        this.emit('health.check_error', {
          name: check.name,
          error: error.message
        });
      }
    });

    await Promise.all(promises);
  }

  getOverallHealth(): OverallHealth {
    const statuses = Array.from(this.healthStatus.values());
    const unhealthyChecks = statuses.filter(s => !s.healthy);
    
    let status: 'healthy' | 'degraded' | 'unhealthy';
    
    if (unhealthyChecks.length === 0) {
      status = 'healthy';
    } else if (unhealthyChecks.length <= statuses.length * 0.3) {
      status = 'degraded';
    } else {
      status = 'unhealthy';
    }

    return {
      status,
      totalChecks: statuses.length,
      healthyChecks: statuses.length - unhealthyChecks.length,
      unhealthyChecks: unhealthyChecks.length,
      lastUpdate: Math.max(...statuses.map(s => s.lastCheck)),
      checks: Object.fromEntries(
        statuses.map(s => [s.name, s])
      )
    };
  }

  private async getSystemResourceUsage(): Promise<SystemResourceUsage> {
    // Implementation would use appropriate system monitoring library
    // For now, returning mock data
    return {
      cpu: Math.random() * 100,
      memory: Math.random() * 100,
      disk: Math.random() * 100,
      timestamp: Date.now()
    };
  }

  private async testPythonRuntime(): Promise<PythonRuntimeTest> {
    // Implementation would test Python interpreter
    // For now, returning mock data
    return {
      success: true,
      message: 'Python runtime operational',
      version: '3.11.0',
      testDuration: 150
    };
  }

  private async checkDatabaseHealth(): Promise<DatabaseHealth> {
    // Implementation would check database
    // For now, returning mock data
    return {
      responsive: true,
      queryTime: Math.random() * 500,
      connectionCount: 5,
      diskUsage: Math.random() * 100
    };
  }
}

// =============================================
// INTERFACES & TYPES
// =============================================

interface MonitoringConfig {
  logsDirectory: string;
  environment: 'development' | 'production';
  retentionDays: number;
}

interface HealthConfig {
  checkInterval: number;
  alertThresholds: {
    cpu: number;
    memory: number;
    disk: number;
  };
}

interface HealthCheck {
  name: string;
  description: string;
  interval: number;
  check: () => Promise<HealthCheckResult>;
}

interface HealthCheckResult {
  healthy: boolean;
  message: string;
  details: Record<string, unknown>;
}

interface HealthStatus {
  name: string;
  healthy: boolean;
  lastCheck: Timestamp;
  message: string;
  details: Record<string, unknown>;
}

interface OverallHealth {
  status: 'healthy' | 'degraded' | 'unhealthy';
  totalChecks: number;
  healthyChecks: number;
  unhealthyChecks: number;
  lastUpdate: Timestamp;
  checks: Record<string, HealthStatus>;
}

interface ErrorStats {
  totalErrors: number;
  last24h: number;
  bySeverity: Record<ErrorSeverity, number>;
  byCategory: Record<ErrorCategory, number>;
  recoveryRate: number;
}

interface SystemResourceUsage {
  cpu: number;
  memory: number;
  disk: number;
  timestamp: number;
}

interface PythonRuntimeTest {
  success: boolean;
  message: string;
  version: string;
  testDuration: number;
}

interface DatabaseHealth {
  responsive: boolean;
  queryTime: number;
  connectionCount: number;
  diskUsage: number;
}

# =============================================
# PRODUCTION DEPLOYMENT CONFIGURATION
# =============================================

# Multi-stage Dockerfile for VibeCodeRehab

# Stage 1: Build embedded Python runtime
FROM python:3.11-slim as python-builder

WORKDIR /python-build

# Install system dependencies for Python libraries
RUN apt-get update && apt-get install -y \
    build-essential \
    tesseract-ocr \
    tesseract-ocr-eng \
    espeak \
    portaudio19-dev \
    gcc \
    g++ \
    && rm -rf /var/lib/apt/lists/*

# Create portable Python installation
RUN python -m venv /opt/vibe-python
ENV PATH="/opt/vibe-python/bin:$PATH"

# Install core Python dependencies
COPY requirements.txt .
RUN pip install --upgrade pip && \
    pip install -r requirements.txt

# Stage 2: Build Node.js frontend
FROM node:18-alpine as frontend-builder

WORKDIR /app

# Copy package files
COPY package*.json ./
COPY tsconfig.json ./
COPY tailwind.config.js ./
COPY postcss.config.js ./

# Install dependencies
RUN npm ci --only=production

# Copy source code
COPY src/ ./src/
COPY public/ ./public/

# Build frontend
RUN npm run build

# Stage 3: Build TypeScript backend
FROM node:18-alpine as backend-builder

WORKDIR /app

# Copy package files
COPY package*.json ./
COPY tsconfig.json ./

# Install dependencies including dev dependencies for build
RUN npm ci

# Copy source code
COPY src/ ./src/

# Build backend
RUN npm run build:backend

# Stage 4: Production runtime
FROM ubuntu:22.04

LABEL maintainer="VibeCodeRehab Team"
LABEL version="1.0.0"
LABEL description="Python automation platform with embedded runtime"

# Install system dependencies
RUN apt-get update && apt-get install -y \
    curl \
    tesseract-ocr \
    tesseract-ocr-eng \
    espeak \
    portaudio19-dev \
    sqlite3 \
    supervisor \
    nginx \
    && rm -rf /var/lib/apt/lists/* \
    && apt-get clean

# Install Node.js
RUN curl -fsSL https://deb.nodesource.com/setup_18.x | bash - \
    && apt-get install -y nodejs

# Create application user
RUN groupadd -r vibe && useradd -r -g vibe vibe

# Set up application directories
WORKDIR /app
RUN mkdir -p /app/data/{scripts,cache,logs,state} \
    && mkdir -p /app/runtime \
    && chown -R vibe:vibe /app

# Copy embedded Python runtime
COPY --from=python-builder /opt/vibe-python /app/runtime/python

# Copy built backend
COPY --from=backend-builder /app/dist /app/dist
COPY --from=backend-builder /app/node_modules /app/node_modules

# Copy built frontend
COPY --from=frontend-builder /app/build /app/public

# Copy configuration files
COPY docker/nginx.conf /etc/nginx/nginx.conf
COPY docker/supervisord.conf /etc/supervisor/conf.d/supervisord.conf
COPY docker/entrypoint.sh /entrypoint.sh

# Copy application configuration
COPY config/ /app/config/

# Set permissions
RUN chmod +x /entrypoint.sh \
    && chown -R vibe:vibe /app

# Expose ports
EXPOSE 3000 3001

# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# Switch to application user
USER vibe

# Set environment variables
ENV NODE_ENV=production
ENV VIBE_CONFIG_PATH=/app/config/production.json
ENV PYTHONPATH=/app/runtime/python/lib/python3.11/site-packages

ENTRYPOINT ["/entrypoint.sh"]
CMD ["supervisord", "-c", "/etc/supervisor/conf.d/supervisord.conf"]

# =============================================
# DOCKER COMPOSE CONFIGURATION
# =============================================

---
# docker-compose.yml
version: '3.8'

services:
  vibe-app:
    build:
      context: .
      dockerfile: Dockerfile
    container_name: vibe-codrehab
    restart: unless-stopped
    ports:
      - "3000:3000"
      - "3001:3001"
    volumes:
      - vibe-data:/app/data
      - vibe-logs:/app/logs
      - /var/run/docker.sock:/var/run/docker.sock:ro  # For container management
    environment:
      - NODE_ENV=production
      - VIBE_LOG_LEVEL=info
      - VIBE_MAX_MEMORY=2048
      - VIBE_MAX_SCRIPTS=100
    labels:
      - "traefik.enable=true"
      - "traefik.http.routers.vibe.rule=Host(`vibe.yourdomain.com`)"
      - "traefik.http.routers.vibe.tls=true"
      - "traefik.http.routers.vibe.tls.certresolver=letsencrypt"
    depends_on:
      - redis
      - postgres
    networks:
      - vibe-network

  postgres:
    image: postgres:15-alpine
    container_name: vibe-postgres
    restart: unless-stopped
    environment:
      POSTGRES_DB: vibecodrehab
      POSTGRES_USER: vibe
      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}
    volumes:
      - postgres-data:/var/lib/postgresql/data
      - ./sql/init.sql:/docker-entrypoint-initdb.d/init.sql
    networks:
      - vibe-network

  redis:
    image: redis:7-alpine
    container_name: vibe-redis
    restart: unless-stopped
    command: redis-server --appendonly yes --requirepass ${REDIS_PASSWORD}
    volumes:
      - redis-data:/data
    networks:
      - vibe-network

  traefik:
    image: traefik:v3.0
    container_name: vibe-traefik
    restart: unless-stopped
    command:
      - "--api.dashboard=true"
      - "--providers.docker=true"
      - "--providers.docker.exposedbydefault=false"
      - "--entrypoints.web.address=:80"
      - "--entrypoints.websecure.address=:443"
      - "--certificatesresolvers.letsencrypt.acme.email=admin@yourdomain.com"
      - "--certificatesresolvers.letsencrypt.acme.storage=/letsencrypt/acme.json"
      - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
    ports:
      - "80:80"
      - "443:443"
      - "8080:8080"
    volumes:
      - /var/run/docker.sock:/var/run/docker.sock:ro
      - traefik-ssl:/letsencrypt
    networks:
      - vibe-network

volumes:
  vibe-data:
    driver: local
  vibe-logs:
    driver: local
  postgres-data:
    driver: local
  redis-data:
    driver: local
  traefik-ssl:
    driver: local

networks:
  vibe-network:
    driver: bridge

# =============================================
# KUBERNETES DEPLOYMENT
# =============================================

---
# k8s/namespace.yaml
apiVersion: v1
kind: Namespace
metadata:
  name: vibecodrehab

---
# k8s/configmap.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: vibe-config
  namespace: vibecodrehab
data:
  production.json: |
    {
      "server": {
        "port": 3000,
        "host": "0.0.0.0"
      },
      "python": {
        "runtimePath": "/app/runtime/python",
        "maxProcesses": 50,
        "timeout": 300000
      },
      "database": {
        "type": "sqlite",
        "path": "/app/data/state.db"
      },
      "monitoring": {
        "enabled": true,
        "logLevel": "info",
        "healthCheckInterval": 30000
      },
      "security": {
        "scriptSandbox": true,
        "maxMemoryPerScript": 512,
        "allowedNetworkAccess": false
      }
    }

---
# k8s/deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vibe-app
  namespace: vibecodrehab
  labels:
    app: vibe-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: vibe-app
  template:
    metadata:
      labels:
        app: vibe-app
    spec:
      containers:
      - name: vibe-app
        image: vibecodrehab/app:latest
        ports:
        - containerPort: 3000
        - containerPort: 3001
        env:
        - name: NODE_ENV
          value: "production"
        - name: VIBE_CONFIG_PATH
          value: "/app/config/production.json"
        volumeMounts:
        - name: app-data
          mountPath: /app/data
        - name: config-volume
          mountPath: /app/config
        resources:
          requests:
            memory: "1Gi"
            cpu: "500m"
          limits:
            memory: "2Gi"
            cpu: "1000m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /ready
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5
      volumes:
      - name: app-data
        persistentVolumeClaim:
          claimName: vibe-data-pvc
      - name: config-volume
        configMap:
          name: vibe-config

---
# k8s/service.yaml
apiVersion: v1
kind: Service
metadata:
  name: vibe-service
  namespace: vibecodrehab
spec:
  selector:
    app: vibe-app
  ports:
  - name: web
    port: 80
    targetPort: 3000
  - name: api
    port: 3001
    targetPort: 3001
  type: ClusterIP

---
# k8s/ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: vibe-ingress
  namespace: vibecodrehab
  annotations:
    kubernetes.io/ingress.class: nginx
    cert-manager.io/cluster-issuer: letsencrypt-prod
    nginx.ingress.kubernetes.io/ssl-redirect: "true"
spec:
  tls:
  - hosts:
    - vibe.yourdomain.com
    secretName: vibe-tls
  rules:
  - host: vibe.yourdomain.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: vibe-service
            port:
              number: 80

---
# k8s/pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: vibe-data-pvc
  namespace: vibecodrehab
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi

# =============================================
# ENVIRONMENT CONFIGURATION
# =============================================

# .env.production
NODE_ENV=production
VIBE_LOG_LEVEL=info
VIBE_CONFIG_PATH=/app/config/production.json

# Database
POSTGRES_PASSWORD=your-secure-postgres-password
REDIS_PASSWORD=your-secure-redis-password

# Security
JWT_SECRET=your-jwt-secret-key
ENCRYPTION_KEY=your-encryption-key

# Monitoring
SENTRY_DSN=your-sentry-dsn
METRICS_ENABLED=true

# Resource Limits
VIBE_MAX_MEMORY=2048
VIBE_MAX_SCRIPTS=100
VIBE_MAX_EXECUTION_TIME=600000

# Network
ALLOWED_ORIGINS=https://vibe.yourdomain.com
CORS_ENABLED=true

# =============================================
# BUILD SCRIPTS
# =============================================

#!/bin/bash
# scripts/build.sh

set -e

echo "🏗️ Building VibeCodeRehab for production..."

# Clean previous builds
echo "🧹 Cleaning previous builds..."
rm -rf dist/ build/

# Install dependencies
echo "📦 Installing dependencies..."
npm ci --only=production

# Build TypeScript backend
echo "🔧 Building backend..."
npm run build:backend

# Build React frontend
echo "⚛️ Building frontend..."
npm run build:frontend

# Create embedded Python runtime
echo "🐍 Preparing Python runtime..."
python3 -m venv runtime/python
source runtime/python/bin/activate
pip install --upgrade pip
pip install -r requirements.txt

# Package for distribution
echo "📦 Creating distribution package..."
mkdir -p dist/
cp -r build/ dist/public/
cp -r runtime/ dist/
cp package.json dist/
cp -r node_modules/ dist/

echo "✅ Build completed successfully!"

#!/bin/bash
# scripts/deploy.sh

set -e

ENVIRONMENT=${1:-production}
VERSION=${2:-latest}

echo "🚀 Deploying VibeCodeRehab to $ENVIRONMENT..."

case $ENVIRONMENT in
  "docker")
    echo "🐳 Building Docker image..."
    docker build -t vibecodrehab/app:$VERSION .
    docker-compose up -d
    ;;
    
  "kubernetes")
    echo "☸️ Deploying to Kubernetes..."
    kubectl apply -f k8s/
    kubectl set image deployment/vibe-app vibe-app=vibecodrehab/app:$VERSION -n vibecodrehab
    kubectl rollout status deployment/vibe-app -n vibecodrehab
    ;;
    
  "production")
    echo "🌐 Deploying to production server..."
    ./scripts/build.sh
    
    # Upload to server
    rsync -avz --delete dist/ user@production-server:/opt/vibecodrehab/
    
    # Restart services
    ssh user@production-server "sudo systemctl restart vibecodrehab"
    ;;
    
  *)
    echo "❌ Unknown environment: $ENVIRONMENT"
    echo "Usage: $0 [docker|kubernetes|production] [version]"
    exit 1
    ;;
esac

echo "✅ Deployment to $ENVIRONMENT completed!"

# =============================================
# MONITORING & LOGGING
# =============================================

# docker/nginx.conf
events {
    worker_connections 1024;
}

http {
    include /etc/nginx/mime.types;
    default_type application/octet-stream;

    log_format main '$remote_addr - $remote_user [$time_local] "$request" '
                    '$status $body_bytes_sent "$http_referer" '
                    '"$http_user_agent" "$http_x_forwarded_for"';

    access_log /app/logs/nginx-access.log main;
    error_log /app/logs/nginx-error.log;

    sendfile on;
    tcp_nopush on;
    tcp_nodelay on;
    keepalive_timeout 65;
    types_hash_max_size 2048;

    gzip on;
    gzip_vary on;
    gzip_proxied any;
    gzip_comp_level 6;
    gzip_types
        text/plain
        text/css
        text/xml
        text/javascript
        application/json
        application/javascript
        application/xml+rss
        application/atom+xml;

    upstream backend {
        server localhost:3001;
    }

    server {
        listen 3000;
        server_name _;

        root /app/public;
        index index.html;

        # Frontend static files
        location / {
            try_files $uri $uri/ /index.html;
            add_header Cache-Control "public, max-age=31536000" always;
        }

        # API routes
        location /api/ {
            proxy_pass http://backend;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
            proxy_cache_bypass $http_upgrade;
        }

        # WebSocket support for real-time events
        location /api/events {
            proxy_pass http://backend;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header X-Forwarded-Proto $scheme;
        }

        # Health check
        location /health {
            proxy_pass http://backend/health;
        }
    }
}

# docker/supervisord.conf
[supervisord]
nodaemon=true
user=vibe

[program:nginx]
command=nginx -g "daemon off;"
autostart=true
autorestart=true
user=root
stdout_logfile=/app/logs/nginx-stdout.log
stderr_logfile=/app/logs/nginx-stderr.log

[program:vibe-backend]
command=node /app/dist/server.js
directory=/app
autostart=true
autorestart=true
user=vibe
environment=NODE_ENV="production",VIBE_CONFIG_PATH="/app/config/production.json"
stdout_logfile=/app/logs/backend-stdout.log
stderr_logfile=/app/logs/backend-stderr.log

# docker/entrypoint.sh
#!/bin/bash
set -e

# Initialize data directories
mkdir -p /app/data/{scripts,cache,logs,state}
mkdir -p /app/logs

# Initialize database if it doesn't exist
if [ ! -f /app/data/state.db ]; then
    echo "Initializing database..."
    node /app/dist/scripts/init-db.js
fi

# Set proper permissions
chown -R vibe:vibe /app/data /app/logs

# Start supervisord
exec "$@"

# =============================================
# CI/CD PIPELINE
# =============================================

# .github/workflows/deploy.yml
name: Deploy VibeCodeRehab

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  test:
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Setup Node.js
      uses: actions/setup-node@v3
      with:
        node-version: '18'
        cache: 'npm'
    
    - name: Setup Python
      uses: actions/setup-python@v4
      with:
        python-version: '3.11'
    
    - name: Install dependencies
      run: |
        npm ci
        pip install -r requirements.txt
    
    - name: Run tests
      run: |
        npm run test:unit
        npm run test:integration
        npm run test:e2e
    
    - name: Code coverage
      run: npm run test:coverage
    
    - name: Upload coverage to Codecov
      uses: codecov/codecov-action@v3

  build:
    needs: test
    runs-on: ubuntu-latest
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Set up Docker Buildx
      uses: docker/setup-buildx-action@v2
    
    - name: Login to DockerHub
      uses: docker/login-action@v2
      with:
        username: ${{ secrets.DOCKERHUB_USERNAME }}
        password: ${{ secrets.DOCKERHUB_TOKEN }}
    
    - name: Build and push
      uses: docker/build-push-action@v4
      with:
        context: .
        platforms: linux/amd64,linux/arm64
        push: true
        tags: |
          vibecodrehab/app:latest
          vibecodrehab/app:${{ github.sha }}

  deploy:
    needs: build
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/main'
    
    steps:
    - uses: actions/checkout@v3
    
    - name: Deploy to production
      run: |
        echo "Deploying to production..."
        # Add your deployment commands here

Summary

I've completed the VibeCodeRehab architecture and provided a comprehensive foundation for production-ready Python automation platform.

What We've Built

Complete Architecture spanning:

  • Domain contracts with full TypeScript type safety

  • Embedded Python runtime with dependency management

  • Process isolation with IPC communication bridge

  • Event-sourced state management for crash recovery

  • 8 automation library templates covering all major use cases

  • Production deployment with Docker, Kubernetes, and CI/CD

  • Error monitoring with automated recovery strategies

The Key Insight

Execution isolation is the primary constraint that solves Python automation reliability. Every design decision flows from this: embedded runtime eliminates dependency conflicts, process-per-script contains failures, event sourcing enables recovery.

Critical Path Forward

Week 1: Implement IPC bridge between TypeScript ↔ Python
Week 2-4: Build core runtime with process management
Week 5-6: Integrate template system
Week 7-12: Frontend, monitoring, and production hardening

The Leverage Point

The template system multiplies capability exponentially. Each new template adds automation patterns that compound user value. Users think in workflows, not technical implementation.

Result: A constraint-driven architecture that transforms unreliable Python scripting into a production automation platform.

The foundation is architected. Time to build the runtime.

User Question:

Questions -- Should the rest of this development take place in the IDE or a containerized environment vs claude.ai chat/artifacts? 1. Implement vibe_bridge.py Python module 2. Build TypeScript IPC message parser 3. Create basic process spawn and communication test Please explain the vibe_bride.py Python module and the TypeScript IPC message parser to me?

Great questions. Let me think through this systematically:

  1. Development Environment Question: This is a critical decision point. The user is asking whether to continue development in a traditional IDE/containerized environment vs continuing in Claude.ai chat/artifacts.

For the next phase of development (implementing the core runtime), we need to consider:

  • Artifacts limitations: No real file system access, no process spawning, no actual Python execution

  • IDE advantages: Real debugging, actual Python execution, proper TypeScript compilation, git integration

  • Containerized advantages: Consistent environment, embedded Python setup, dependency management

The IPC bridge and process management are core system-level operations that need real execution environments. Artifacts are great for architecture and UI components, but not for the deep runtime work.

  1. vibe_bridge.py explanation: This is the Python-side communication module that gets injected into every user script. It handles:

  • State persistence calls

  • UI notifications

  • Progress reporting

  • Heartbeat signals

  • Communication with the TypeScript runtime

  1. TypeScript IPC parser: This parses structured messages from Python stdout to enable bidirectional communication between isolated Python processes and the main TypeScript application.

Let me explain these clearly and recommend the right development approach.

Development Environment Recommendation

Switch to IDE/Containerized Environment for the next phase.

Why:

  • IPC bridge requires real process spawning - can't test in browser sandbox

  • Python execution needs actual interpreter - artifacts can't run Python

  • File system operations - state persistence, script storage, logs

  • Debugging process communication - need real stdout/stderr streams

Recommended Setup:

bash

# Containerized development environment
docker-compose -f docker-compose.dev.yml up

Keep using Claude for:

  • Architecture decisions and system design

  • Code review and optimization suggestions

  • Complex debugging when you hit constraint issues

  • UI component development (React artifacts work great)


The vibe_bridge.py Python Module Explained

This is the communication lifeline between isolated Python scripts and the TypeScript runtime.

The Constraint It Solves

Python scripts run in isolated processes. They need to:

  • Store persistent state that survives crashes

  • Send progress updates to the UI

  • Report errors and status

  • Receive commands from the main application

How It Works

python

# vibe_bridge.py - Gets injected into every script
class VibeBridge:
    def __init__(self, script_id: str):
        self.script_id = script_id
        # No sockets, no files - just stdout communication
    
    def set_state(self, key: str, value: Any) -> None:
        """Persist data that survives script restarts"""
        self._send_ipc('STATE_SET', {'key': key, 'value': value})
    
    def notify_ui(self, message: str, level: str = 'info') -> None:
        """Send notification to user interface"""
        self._send_ipc('UI_NOTIFY', {
            'message': message, 
            'level': level,
            'timestamp': datetime.now().isoformat()
        })
    
    def _send_ipc(self, command: str, data: dict) -> None:
        """The magic: structured messages via stdout"""
        message = {
            'script_id': self.script_id,
            'command': command,
            'data': data,
            'timestamp': datetime.now().isoformat()
        }
        
        # Special markers for TypeScript to parse
        print(f"__VIBE_IPC__{json.dumps(message)}__END_IPC__", flush=True)

User Script Example

python

# User's automation script
from vibe_bridge import get_bridge

bridge = get_bridge()

# Script can now communicate with the system
bridge.notify_ui("Starting file processing", "info")

for i, file in enumerate(files):
    # Process file
    result = process_file(file)
    
    # Store results persistently
    bridge.set_state(f"processed_file_{i}", result)
    
    # Update UI with progress
    bridge.log_progress(i + 1, len(files), f"Processed {file}")

bridge.notify_ui("All files processed successfully", "success")

TypeScript IPC Message Parser Explained

This is the message decoder that extracts structured communication from Python stdout.

The Challenge

Python scripts output both:

  • Regular stdout (print statements, library output)

  • IPC messages (bridge communication)

We need to separate these streams without breaking either.

The Solution

typescript

class ProcessManager {
    private setupProcessMonitoring(childProcess: ChildProcess): void {
        childProcess.stdout?.on('data', (data) => {
            this.handleStdout(data.toString());
        });
    }

    private handleStdout(data: string): void {
        // The regex magic: find our special markers
        const ipcRegex = /__VIBE_IPC__(.+?)__END_IPC__/g;
        let match;
        let cleanOutput = data;

        // Extract all IPC messages
        while ((match = ipcRegex.exec(data)) !== null) {
            try {
                const message = JSON.parse(match[1]);
                this.handleIPCMessage(message);
                
                // Remove IPC message from regular output
                cleanOutput = cleanOutput.replace(match[0], '');
            } catch (error) {
                console.error('Failed to parse IPC message:', error);
            }
        }

        // Send clean output to logs (user's print statements)
        if (cleanOutput.trim()) {
            this.emit('stdout', cleanOutput);
        }
    }

    private handleIPCMessage(message: IPCMessage): void {
        switch (message.command) {
            case 'STATE_SET':
                // Store in database via StatePod
                this.statePod.set(message.data.key, message.data.value);
                break;
                
            case 'UI_NOTIFY':
                // Send to frontend via WebSocket
                this.emit('notification', {
                    scriptId: message.script_id,
                    level: message.data.level,
                    message: message.data.message,
                    timestamp: message.timestamp
                });
                break;
                
            case 'PROGRESS_UPDATE':
                // Update execution progress
                this.emit('progress', {
                    scriptId: message.script_id,
                    current: message.data.current,
                    total: message.data.total,
                    percentage: message.data.percentage
                });
                break;
        }
    }
}

Message Flow Example

  1. Python script calls: bridge.set_state("counter", 42)

  2. Python stdout outputs: Regular log message __VIBE_IPC__{"script_id":"script_123","command":"STATE_SET","data":{"key":"counter","value":42}}__END_IPC__ More log output

  3. TypeScript parser:

    • Extracts IPC message with regex

    • Calls statePod.set("counter", 42)

    • Sends clean output to logs: Regular log message More log output


Implementation Strategy

Week 1 Development Approach

Day 1: Environment Setup

bash

# Create development container
mkdir vibecodrehab-dev && cd vibecodrehab-dev
# Set up embedded Python in container
# Configure TypeScript development environment

Day 2: Bridge Module

  • Implement vibe_bridge.py with basic IPC functions

  • Test message formatting and JSON serialization

  • Verify stdout doesn't interfere with normal output

Day 3: IPC Parser

  • Build TypeScript regex parser for IPC messages

  • Test with mock Python output containing IPC + regular output

  • Implement message routing (state, notifications, progress)

Day 4: Process Integration

  • Combine bridge injection with process spawning

  • Test bidirectional communication

  • Verify message isolation and parsing

Day 5: First Working Script

  • Execute simple Python script with bridge communication

  • Verify state persistence across script runs

  • Test error handling and process cleanup

Critical Success Criteria

  • Python script can store/retrieve persistent state

  • UI receives real-time notifications from script

  • Regular Python output (print statements) still works

  • Process isolation prevents one script from affecting others

The IPC bridge is the foundational constraint - everything else builds on reliable process communication. Get this right, and the rest follows naturally.

Ready to move to IDE/container development?

Retry

JS

User Quesion --

The user is asking about two specific things:

  1. Podman vs Docker differences for their setup

  2. IDE/development environment choice between Windows (WSL2 + VS Code + Claude Code), Windows (Kimi K2 Code), or Mac (Claude Code)

Let me think through these:

Podman vs Docker

Podman is designed to be a drop-in replacement for Docker, but there are some key differences:

  1. Rootless by default - Podman runs without root privileges

  2. No daemon - Docker runs a daemon, Podman doesn't

  3. Pod concept - Podman has native pod support (like Kubernetes pods)

  4. Systemd integration - Better systemd integration

  5. Compose compatibility - podman-compose works with docker-compose files, but there can be subtle differences

For our VibeCodeRehab project, the main considerations:

  • Process spawning: Python processes need to be spawned from within containers

  • File system access: Need to mount volumes for persistent state

  • IPC communication: stdout/stderr capture between processes

  • Resource limits: Memory/CPU limits per script process

IDE Environment Analysis

Windows WSL2 + VS Code + Claude Code

Pros:

  • Excellent Docker/Podman integration through WSL2

  • Native Linux environment for Python development

  • Claude Code works great in Linux environment

  • VS Code has excellent remote development support

  • File system performance is good in WSL2

  • Can test both Windows and Linux deployment scenarios

Cons:

  • Some overhead from WSL2 layer

  • Occasional file system sync issues between Windows/WSL2

  • Resource usage slightly higher

Windows + Kimi K2 Code

Pros:

  • Native Windows performance

  • Direct access to Windows Python if needed

  • No virtualization overhead

  • Familiar Windows development environment

Cons:

  • Python subprocess spawning behaves differently on Windows

  • Path handling differences (Windows vs Unix paths)

  • Container integration becomes more intricate

  • Process isolation requires specialized configuration

  • IPC bridging needs targeted Windows-specific testing

Mac + Claude Code

Pros:

  • Unix-like environment mirrors production Linux setup

  • Superior container performance

  • Robust signal handling and process management

  • Ideal for deepening Unix/Linux system administration skills

  • Claude Code integrates seamlessly

  • Production environment most closely replicated

Cons:

  • Potential learning curve for Mac-unfamiliar developers

  • Unique package management approach (brew vs apt)

  • Occasional library compatibility challenges, especially with audio processing libraries

The core project challenge centers on intricate process isolation and inter-process communication. Critical technical considerations involve sophisticated subprocess management, including real-time output parsing, nuanced signal handling, and comprehensive resource control mechanisms. Windows introduces significant architectural variations in process management, requiring careful cross-platform adaptation strategies. The Linux-based production environment underscores the importance of developing in a Unix-like ecosystem to minimize potential deployment complexities.

Podman vs Docker Changes

Good news: Minimal changes needed. Podman is designed as a drop-in replacement.

Key Differences for Our Project

yaml

# docker-compose.yml → podman-compose.yml (same file)
version: '3.8'
services:
  vibe-app:
    build: .
    # Podman handles rootless containers better
    user: "1000:1000"  # Add explicit user mapping
    security_opt:
      - "label=disable"  # SELinux compatibility

Podman-Specific Advantages

  • Rootless by default - Better security for script execution

  • No daemon - Lower resource overhead

  • Systemd integration - Better for production deployment

  • Pod concepts - Natural fit for our isolated script processes

Commands Stay the Same

bash

# These work identically
podman-compose up -d
podman-compose build
podman-compose logs

One Important Change

bash

# Add to your development setup
podman system service --time=0 unix:///tmp/podman.sock &
export DOCKER_HOST=unix:///tmp/podman.sock

IDE Environment Recommendation: Mac + Claude Code

Why Mac is the Strategic Choice

Critical Constraint: Our production environment is Linux. The closer your development environment matches production, the fewer surprises you'll encounter.

Development Implications Analysis

AspectWindows + WSL2Windows + KimiMac + Claude CodeProcess ManagementGood (Linux-like)Complex (Windows semantics)Excellent (Unix native)Signal HandlingGood (POSIX)Limited (Windows signals)Excellent (POSIX native)Container IntegrationGood (through WSL2)Complex (Windows containers)Excellent (native)Python SubprocessGood (Linux behavior)Different (Windows behavior)Excellent (Unix behavior)File Path HandlingMixed (WSL2 vs Windows)Windows-specificUnix-consistentProduction SimilarityHigh (Linux in WSL2)Low (Windows-specific)Highest (Unix-like)

The IPC Bridge Constraint

Our core constraint - Python ↔ TypeScript communication - depends heavily on:

python

# This works differently across platforms
import subprocess
import signal
import os

# Unix signals (Mac/Linux)
process.send_signal(signal.SIGTERM)  # Graceful shutdown
process.send_signal(signal.SIGKILL)  # Force kill

# Windows equivalent is different
# Requires different process management code

Mac Development Setup Strategy

Learning Path to Minimize Friction:

bash

# Day 1: Basic Mac setup
brew install podman podman-compose
brew install node [email protected]
brew install --cask visual-studio-code

# Day 2: Claude Code setup
# Install Claude Code CLI
# Configure development environment

# Day 3: Container development
podman-compose up -f docker-compose.dev.yml

Mac-Specific Advantages for Our Project

  1. Native Unix Process Model

    • fork() and exec() work as expected

    • Signal handling matches Linux production

    • Process groups and session management identical

  2. Python Library Compatibility

    • Libraries like tesseract, espeak install similarly to Linux

    • Audio/GUI automation libraries behave consistently

    • Dependency management closer to production

  3. Container Performance

    • No virtualization layer (unlike WSL2)

    • Native Docker socket communication

    • Better file system performance

  4. Production Debugging

    • Same shell commands and utilities

    • Identical path structures and permissions

    • Similar networking and process behavior

Overcoming Mac Learning Curve

Essential Mac Commands for This Project:

bash

# Package management (replaces apt-get)
brew install <package>
brew services start <service>

# File system (same as Linux)
ls -la, cd, mkdir, chmod, chown

# Process management (identical to Linux)
ps aux, kill -9, jobs, bg, fg

# Development tools
code .  # VS Code
which python3  # Find Python path

Recommended Learning Approach:

  1. Day 1: Basic navigation and Homebrew

  2. Day 2: Terminal and command line tools

  3. Day 3: Development environment setup

  4. Week 2: Advanced Unix concepts as needed

Alternative: WSL2 Compromise

If Mac learning curve is too steep initially:

WSL2 + VS Code gives you:

  • Linux development environment

  • Windows familiarity

  • Excellent Claude Code integration

  • Easy transition to Mac later

But you'll need to handle:

  • File system sync between Windows/WSL2

  • Slightly different container behavior

  • Some performance overhead


Recommendation: Start with Mac

Why This Constraint Drives Everything

The process isolation and IPC communication is the hardest technical challenge. Getting it working smoothly on Mac means:

  • It will work identically in Linux production

  • No platform-specific bugs to debug later

  • Learning Unix/Linux skills that compound over time

Risk Mitigation

If Mac proves too challenging in first week:

  • Fallback to WSL2 immediately

  • All architecture and code transfers directly

  • Switch back to Mac later when more comfortable

The Learning Investment

Short-term cost: 2-3 days learning Mac basics Long-term benefit: Unix expertise that applies to:

  • Linux server management

  • Production debugging

  • DevOps and deployment

  • Most development environments

Bottom Line: The constraint-driven architecture we've built is Unix-centric. Developing in the target environment eliminates a whole class of platform-specific issues.