npm package: @firesystem/workspace
Description: Multi-project workspace manager for Firesystem with support for multiple sources
Author: Anderson D. Rosa
Latest version: 1.0.8

# @firesystem/workspace

**Revolutionary Multi-Project Workspace Manager** - The first file system workspace that enables **multiple projects running simultaneously in parallel**, breaking the traditional "one project = one filesystem" paradigm. Unlike IDEs that switch between projects, Firesystem Workspace keeps ALL projects active and accessible at once.

[![npm version](https://badge.fury.io/js/@firesystem%2Fworkspace.svg)](https://badge.fury.io/js/@firesystem%2Fworkspace)
[![TypeScript](https://img.shields.io/badge/TypeScript-5.0-blue.svg)](https://www.typescriptlang.org/)
[![License](https://img.shields.io/badge/license-MIT-green.svg)](https://opensource.org/licenses/MIT)
[![Tests](https://img.shields.io/badge/tests-373%20passed-brightgreen.svg)](/)

## 🚀 Why This Changes Everything

Traditional development environments work with **one active project at a time**:

```typescript
// ❌ Traditional approach (VSCode, etc.)
await closeProject("frontend");     // Lost from memory
await openProject("backend");       // Only this is accessible
await closeProject("backend");      // Lost from memory  
await openProject("database");      // Only this is accessible
```

**Firesystem Workspace revolutionizes this:**

```typescript
// ✅ Revolutionary approach - ALL PROJECTS ACTIVE SIMULTANEOUSLY
const frontend = workspace.getProject("frontend");     // Always accessible
const backend = workspace.getProject("backend");       // Always accessible  
const database = workspace.getProject("database");     // Always accessible

// Cross-project operations without switching context
const config = await backend.fs.readFile("/config/database.json");
await database.fs.writeFile("/import/backend-config.json", config);
await frontend.fs.writeFile("/src/api-config.json", config);

// One project focused for UI, but ALL remain active
workspace.setActiveProject("frontend"); // Just changes UI focus
```

## 🌟 Revolutionary Features

### 🔥 **Multi-Project Parallelism**
- **Multiple file systems active simultaneously** - not just "open tabs"
- **Cross-project operations** - copy/sync data between different storage types
- **Zero context switching** - all projects remain in memory and accessible
- **Focus vs Active** - UI shows one project, but all remain operational

### 🧩 **Provider-Agnostic Architecture**
- **Workspace knows NOTHING about specific implementations** 
- **Completely extensible** - anyone can create providers for any storage
- **Zero dependencies** - workspace has no file system implementations
- **Capability-aware** - each provider declares what it can/cannot do

### ⚡ **Intelligent Resource Management**  
- **Hot enable/disable** - pause projects for performance without losing config
- **Automatic cleanup** - orphaned references removed on startup
- **Memory optimization** - smart resource management for hundreds of projects
- **Persistent state** - everything survives restarts

### 🗑️ **Advanced Project Lifecycle**
- **Complete deletion support** - remove projects with optional data cleanup
- **Provider-aware deletion** - knows which providers store local vs remote data
- **Confirmation events** - intercept and cancel deletions programmatically
- **Storage estimation** - see how much space will be freed before deleting

## 📦 Installation

```bash
npm install @firesystem/workspace @firesystem/core
# or
yarn add @firesystem/workspace @firesystem/core  
# or
pnpm add @firesystem/workspace @firesystem/core
```

## 🚀 Quick Start

### Basic Multi-Project Setup

```typescript
import { WorkspaceFileSystem } from "@firesystem/workspace";
import { memoryProvider } from "@firesystem/memory/provider";
import { indexedDBProvider } from "@firesystem/indexeddb/provider";

// Create workspace and register providers
const workspace = new WorkspaceFileSystem();
workspace.registerProvider(memoryProvider);
workspace.registerProvider(indexedDBProvider);

// Initialize (restores previous state automatically)
await workspace.initialize();

// Load multiple projects simultaneously
const devProject = await workspace.loadProject({
  id: "dev-env",
  name: "Development Environment",
  source: {
    type: "memory",
    config: {
      initialData: {
        "/src/app.ts": { content: "console.log('dev');" },
        "/config/dev.json": { content: JSON.stringify({ env: "development" }) }
      }
    }
  }
});

const prodBackup = await workspace.loadProject({
  id: "prod-backup", 
  name: "Production Backup",
  source: {
    type: "indexeddb",
    config: { dbName: "production-backup" }
  }
});

// ALL PROJECTS ARE NOW ACTIVE AND ACCESSIBLE!
console.log("Active projects:", workspace.getProjects().length); // 2

// Cross-project operations (the revolutionary part!)
const prodConfig = await prodBackup.fs.readFile("/config/production.json");
await devProject.fs.writeFile("/config/prod-copy.json", prodConfig.content);

// Work with the focused project transparently
workspace.setActiveProject("dev-env");
await workspace.writeFile("/test.js", "// This goes to dev-env");

// But other projects remain accessible
await prodBackup.fs.writeFile("/logs/import.log", "Config copied to dev");
```

## 🎯 Core Concepts

### 1. **Multi-Project Parallelism**

Unlike traditional workspaces that handle one project at a time:

```typescript
// Traditional: Only one project accessible
const currentProject = getCurrentProject(); // Only this exists

// Firesystem: All projects accessible simultaneously  
const projects = workspace.getProjects(); // All active projects
const dev = workspace.getProject("dev");
const staging = workspace.getProject("staging");  
const prod = workspace.getProject("prod");

// Work with all at once
const devConfig = await dev.fs.readFile("/config.json");
const stagingData = await staging.fs.glob("**/*.log");
await prod.fs.writeFile("/backup/dev-config.json", devConfig.content);
```

### 2. **Focus vs Active States**

- **Active Projects**: Loaded in memory, consuming resources, ready for operations
- **Focused Project**: The project shown in UI (File Explorer), receives direct operations  
- **Disabled Projects**: Configuration preserved but not loaded, zero resource usage

```typescript
// Load multiple projects - all become active
await workspace.loadProject({ id: "app", source: { type: "memory" } });
await workspace.loadProject({ id: "docs", source: { type: "indexeddb" } });
await workspace.loadProject({ id: "assets", source: { type: "s3" } });

// Set focus for UI - others remain active
await workspace.setActiveProject("app");  // File Explorer shows "app"

// Direct access to any project
const docs = workspace.getProject("docs");
const assets = workspace.getProject("assets");

// Proxy operations go to focused project
await workspace.writeFile("/test.txt", "content"); // Goes to "app"

// Direct operations go to specific project
await docs.fs.writeFile("/readme.md", "# Documentation");
await assets.fs.writeFile("/logo.png", imageData);
```

### 3. **Performance Optimization**

```typescript
// Disable projects for performance (keeps config)
await workspace.disableProject("large-dataset"); // Frees memory, keeps config

// Re-enable when needed
await workspace.enableProject("large-dataset");   // Reconstructs from config

// Batch operations
await workspace.disableProjects(["old-1", "old-2", "old-3"]);
await workspace.enableProjects(["needed-1", "needed-2"]);

// Auto-optimization settings
const workspace = new WorkspaceFileSystem({
  settings: {
    maxActiveProjects: 5,              // Auto-disable least recently used
    autoDisableAfter: 30 * 60 * 1000,  // 30 minutes of inactivity
    keepFocusedActive: true            // Never auto-disable focused project
  }
});
```

### 4. **Project Deletion**

Delete projects with full control over data cleanup:

```typescript
// Delete project configuration only (preserves data)
await workspace.deleteProject("temp-project");

// Delete project AND its data
await workspace.deleteProject("old-project", {
  deleteData: true
});

// With confirmation event
workspace.events.on("project:delete-confirm", (event) => {
  if (!confirm(`Delete ${event.project.name}?`)) {
    event.cancelled = true; // Cancel deletion
  }
});

// Skip confirmation for automation
await workspace.deleteProject("temp-project", {
  skipConfirmation: true,
  deleteData: true
});
```

## 🔌 Provider System

The workspace is **completely agnostic** about file systems. Providers encapsulate all implementation knowledge:

### Available Providers

| Provider | Package | Type | Description |
|----------|---------|------|-------------|
| Memory | `@firesystem/memory/provider` | `"memory"` | In-memory, fast iteration |
| IndexedDB | `@firesystem/indexeddb/provider` | `"indexeddb"` | Browser persistent storage |
| S3* | `@firesystem/s3/provider` | `"s3"` | AWS S3 cloud storage |
| GitHub* | `@firesystem/github/provider` | `"github"` | GitHub repository |
| API* | `@firesystem/api/provider` | `"api"` | REST API backend |

*Coming soon

### Registering Providers

```typescript
import { WorkspaceFileSystem } from "@firesystem/workspace";
import { memoryProvider } from "@firesystem/memory/provider";
import { indexedDBProvider } from "@firesystem/indexeddb/provider";

const workspace = new WorkspaceFileSystem();

// Register only what you need
workspace.registerProvider(memoryProvider);
workspace.registerProvider(indexedDBProvider);

// Provider capabilities are automatically detected
const memoryCapabilities = workspace.getProvider("memory")?.getCapabilities();
console.log(memoryCapabilities.supportsWatch); // true
console.log(memoryCapabilities.readonly); // false
```

### Creating Custom Providers

```typescript
import type { SourceProvider } from "@firesystem/workspace";
import { withEvents } from "@firesystem/core";

class DropboxProvider implements SourceProvider {
  readonly scheme = "dropbox";
  readonly displayName = "Dropbox Storage";
  
  async createFileSystem(config: DropboxConfig) {
    const baseFs = new DropboxFileSystem(config);
    return withEvents(baseFs); // Add reactive events
  }
  
  getCapabilities() {
    return {
      readonly: false,
      caseSensitive: false,
      atomicRename: true,
      supportsWatch: false,     // Dropbox limitation
      supportsMetadata: true,
      maxFileSize: 150 * 1024 * 1024 // 150MB
    };
  }
  
  async validateConfiguration(config: any) {
    const errors = [];
    if (!config.accessToken) errors.push("Access token required");
    return { valid: errors.length === 0, errors };
  }
  
  // Optional: Data management methods
  deleteProjectData?(config: DropboxConfig): Promise<void> {
    // Remove Dropbox app folder if needed
  }
  
  hasLocalData(): boolean {
    return false; // Dropbox is cloud storage
  }
  
  async estimateDataSize(config: DropboxConfig): Promise<number | null> {
    // Could query Dropbox API for folder size
    return null;
  }
}

// Register and use
workspace.registerProvider(new DropboxProvider());
await workspace.loadProject({
  id: "my-dropbox",
  name: "Dropbox Files", 
  source: {
    type: "dropbox",
    config: { accessToken: "...", path: "/projects" }
  }
});
```

## 🔄 Cross-Project Operations

The revolutionary feature that enables true multi-project workflows:

### Copy Files Between Projects

```typescript
// Load different storage types
const memory = await workspace.loadProject({
  id: "temp",
  source: { type: "memory", config: {} }
});

const persistent = await workspace.loadProject({
  id: "storage", 
  source: { type: "indexeddb", config: { dbName: "app-data" } }
});

// Copy files between different storage types
await workspace.copyFiles(
  "temp",           // Source project
  "/work/*.json",   // Source pattern
  "storage",        // Target project  
  "/backup/"        // Target directory
);
```

### Sync Projects

```typescript
// Sync entire project from S3 to local IndexedDB
await workspace.syncProjects("s3-backup", "local-cache", {
  direction: "source-to-target",
  deleteOrphaned: false,
  skipExisting: true
});
```

### Compare Projects

```typescript
const diff = await workspace.compareProjects("dev", "staging");
console.log(diff.added);     // Files in staging not in dev
console.log(diff.removed);   // Files in dev not in staging  
console.log(diff.modified);  // Files that differ
```

### Real-Time Data Pipeline

```typescript
// Set up multi-stage data pipeline
const rawData = await workspace.loadProject({
  id: "s3-raw",
  source: { type: "s3", config: { bucket: "raw-data" } }
});

const processing = await workspace.loadProject({
  id: "memory-work", 
  source: { type: "memory", config: {} }
});

const results = await workspace.loadProject({
  id: "indexeddb-cache",
  source: { type: "indexeddb", config: { dbName: "results" } }
});

// Process: S3 → Memory → IndexedDB
const files = await rawData.fs.glob("batch-*.json");
for (const file of files) {
  // 1. Read from S3
  const data = await rawData.fs.readFile(file);
  
  // 2. Process in memory (fast)
  const processed = await processData(JSON.parse(data.content));
  await processing.fs.writeFile(`/work${file}`, JSON.stringify(processed));
  
  // 3. Save results to IndexedDB (persistent)
  await results.fs.writeFile(`/final${file}`, JSON.stringify(processed));
}
```

## 📡 Event System

Unified events across all projects with rich context:

```typescript
// Project lifecycle events
workspace.events.on("project:loaded", ({ project }) => {
  console.log(`✅ ${project.name} loaded (${project.source.type})`);
});

workspace.events.on("project:activated", ({ projectId, previousId }) => {
  console.log(`🔄 Switched from ${previousId} to ${projectId}`);
});

// File operations with project context
workspace.events.on("project:file:written", ({ projectId, path, size }) => {
  console.log(`📝 ${path} written in ${projectId} (${size} bytes)`);
});

// Cross-project operations
workspace.events.on("workspace:sync:completed", ({ sourceId, targetId, stats }) => {
  console.log(`🔄 Synced ${stats.files} files from ${sourceId} to ${targetId}`);
});

// Performance events with enhanced data
workspace.events.on("project:disabled", ({ projectId, hasLocalData, reason }) => {
  console.log(`💤 ${projectId} disabled`);
  console.log(`   Has local data: ${hasLocalData}`);
  console.log(`   Reason: ${reason}`);
});

workspace.events.on("project:enabled", ({ projectId }) => {
  console.log(`⚡ ${projectId} re-enabled`);
});

// Deletion events
workspace.events.on("project:deleted", ({ projectId, deletedData }) => {
  console.log(`🗑️ ${projectId} deleted${deletedData ? ' with data' : ''}`);
});
```

## 💾 Persistent State & Auto-Recovery

### Automatic State Management

```typescript
const workspace = new WorkspaceFileSystem();
await workspace.initialize(); // Automatically restores:
// - All previously loaded projects
// - Active project selection  
// - Project configurations
// - Settings and preferences

// State is automatically saved when:
// - Projects are loaded/unloaded
// - Active project changes
// - Settings are modified
// - Projects are enabled/disabled
```

### Smart Cleanup (v1.0.3+)

The workspace automatically handles corrupted state:

```typescript
// Before v1.0.3: Could crash with "NotFoundError"
// v1.0.3+: Automatically cleans up orphaned references

await workspace.initialize(); // Always succeeds

// Console output:
// ⚠️  Removing orphaned activeProjectId: deleted-project-123
// ⚠️  Removing orphaned recentProjectId: missing-project-456  
// ℹ️  Workspace state cleaned: removed orphaned project references
```

### Project Discovery

```typescript
// Discover existing IndexedDB projects
const discovered = await workspace.discoverIndexedDBProjects();
console.log("Found projects:", discovered.map(p => p.name));

// Load discovered projects
for (const project of discovered) {
  await workspace.loadProject(project);
}

// Get all disabled projects (async now)
const disabledProjects = await workspace.getDisabledProjects();
console.log(`${disabledProjects.length} projects are disabled`);
```

## 🔐 Security & Credentials

### Environment-Based Credentials

```bash
# S3 credentials
FIRESYSTEM_S3_ACCESS_KEY_ID=your_access_key
FIRESYSTEM_S3_SECRET_ACCESS_KEY=your_secret_key
FIRESYSTEM_S3_REGION=us-east-1

# GitHub token
FIRESYSTEM_GITHUB_TOKEN=ghp_xxxxxxxxxxxx

# API credentials
FIRESYSTEM_API_API_KEY=your_api_key
```

### Interactive Credential Management

```typescript
// Credentials requested when needed
const s3Project = await workspace.loadProject({
  id: "cloud-files",
  source: {
    type: "s3", 
    config: { bucket: "my-bucket" }
    // No credentials in config - resolved from environment
  }
});

// Custom credential providers
workspace.registerCredentialProvider("s3", new InteractiveCredentialProvider({
  prompt: async (message, secure) => {
    return await showCredentialDialog(message, secure);
  }
}));
```

### Export Security

```typescript
// Exports are automatically sanitized
const exportData = await workspace.exportWorkspace({
  includeFiles: true,
  includeCredentials: false  // Never exports credentials
});

// Safe for sharing/version control
await workspace.exportToGitHubGist({
  token: "ghp_...",
  description: "Team Workspace Configuration",
  public: false
});
```

## ⚛️ Framework Integration

### React + Zustand

```typescript
import { create } from "zustand";
import { WorkspaceFileSystem } from "@firesystem/workspace";

interface WorkspaceStore {
  workspace: WorkspaceFileSystem | null;
  projects: Project[];
  activeProject: Project | null;
  
  initWorkspace: () => Promise<void>;
  createProject: (name: string, type: string) => Promise<void>;
  switchProject: (projectId: string) => Promise<void>;
  deleteProject: (projectId: string, deleteData?: boolean) => Promise<void>;
}

const useWorkspaceStore = create<WorkspaceStore>((set, get) => ({
  workspace: null,
  projects: [],
  activeProject: null,

  async initWorkspace() {
    const workspace = new WorkspaceFileSystem();
    await workspace.initialize(); // Auto-restores state
    
    // Setup reactive events
    workspace.events.on("project:loaded", ({ project }) => {
      set(state => ({
        projects: [...state.projects, project]
      }));
    });
    
    workspace.events.on("project:activated", ({ projectId }) => {
      const project = workspace.getProject(projectId);
      set({ activeProject: project });
    });
    
    workspace.events.on("project:deleted", ({ projectId }) => {
      set(state => ({
        projects: state.projects.filter(p => p.id !== projectId),
        activeProject: state.activeProject?.id === projectId ? null : state.activeProject
      }));
    });
    
    set({ 
      workspace, 
      projects: workspace.getProjects(),
      activeProject: workspace.getActiveProject()
    });
  },

  async createProject(name: string, type: string) {
    const { workspace } = get();
    if (!workspace) return;
    
    const project = await workspace.loadProject({
      id: `project-${Date.now()}`,
      name,
      source: { type, config: {} }
    });
    
    await workspace.setActiveProject(project.id);
  },

  async switchProject(projectId: string) {
    const { workspace } = get();
    if (!workspace) return;
    
    await workspace.setActiveProject(projectId);
  },
  
  async deleteProject(projectId: string, deleteData = false) {
    const { workspace } = get();
    if (!workspace) return;
    
    await workspace.deleteProject(projectId, { deleteData });
  }
}));

// React component
function MultiProjectIDE() {
  const { 
    workspace, 
    projects, 
    activeProject,
    initWorkspace,
    createProject,
    switchProject,
    deleteProject
  } = useWorkspaceStore();
  
  useEffect(() => {
    initWorkspace();
  }, []);
  
  return (
    <div className="ide-container">
      {/* Project tabs - all remain active */}
      <div className="project-tabs">
        {projects.map(project => (
          <button 
            key={project.id}
            onClick={() => switchProject(project.id)}
            className={activeProject?.id === project.id ? 'active' : ''}
          >
            {project.name} 
            <span className="type">({project.source.type})</span>
          </button>
        ))}
      </div>
      
      {/* File explorer for active project */}
      {activeProject && (
        <FileExplorer project={activeProject} />
      )}
      
      {/* Cross-project operations */}
      <CrossProjectPanel 
        projects={projects}
        onCopyFiles={(source, target, pattern) => 
          workspace?.copyFiles(source, pattern, target, "/")
        }
        onSyncProjects={(source, target) =>
          workspace?.syncProjects(source, target)
        }
      />
    </div>
  );
}
```

### Vue 3 Composition API

```typescript
import { ref, reactive, onMounted } from 'vue';
import { WorkspaceFileSystem } from '@firesystem/workspace';

export function useWorkspace() {
  const workspace = ref<WorkspaceFileSystem | null>(null);
  const projects = ref<Project[]>([]);
  const activeProject = ref<Project | null>(null);
  
  const initWorkspace = async () => {
    workspace.value = new WorkspaceFileSystem();
    await workspace.value.initialize();
    
    workspace.value.events.on('project:loaded', ({ project }) => {
      projects.value.push(project);
    });
    
    workspace.value.events.on('project:activated', ({ projectId }) => {
      activeProject.value = workspace.value!.getProject(projectId);
    });
    
    workspace.value.events.on('project:deleted', ({ projectId }) => {
      projects.value = projects.value.filter(p => p.id !== projectId);
      if (activeProject.value?.id === projectId) {
        activeProject.value = null;
      }
    });
    
    projects.value = workspace.value.getProjects();
    activeProject.value = workspace.value.getActiveProject();
  };
  
  const createProject = async (name: string, type: string) => {
    if (!workspace.value) return;
    
    const project = await workspace.value.loadProject({
      id: `project-${Date.now()}`,
      name,
      source: { type, config: {} }
    });
      
    await workspace.value.setActiveProject(project.id);
  };
  
  const deleteProject = async (projectId: string, deleteData = false) => {
    if (!workspace.value) return;
    
    await workspace.value.deleteProject(projectId, { deleteData });
  };
  
  return {
    workspace,
    projects,
    activeProject,
    initWorkspace,
    createProject,
    deleteProject
  };
}
```

## 🌍 Real-World Use Cases

### 1. Multi-Environment Development

```typescript
class DevelopmentWorkspace {
  async setup() {
    // Load all environments simultaneously
    const local = await workspace.loadProject({
      id: "local-dev",
      source: { type: "memory", config: {} }
    });
    
    const staging = await workspace.loadProject({
      id: "staging-mirror", 
      source: { type: "indexeddb", config: { dbName: "staging-cache" } }
    });
    
    const production = await workspace.loadProject({
      id: "prod-readonly",
      source: { type: "s3", config: { bucket: "prod-backup" } }
    });
    
    // Copy production config to development
    const prodConfig = await production.fs.readFile("/config/app.json");
    await local.fs.writeFile("/config/prod-like.json", prodConfig.content);
    
    // Sync staging data for testing
    await workspace.syncProjects("staging-mirror", "local-dev", {
      include: ["data/**/*.json"],
      exclude: ["data/sensitive/**"]
    });
  }
}
```

### 2. Content Management Pipeline

```typescript
class ContentPipeline {
  async processContent() {
    // Multiple content sources active simultaneously
    const cms = await workspace.loadProject({
      id: "cms-api",
      source: { type: "api", config: { baseUrl: "https://cms.example.com" } }
    });
    
    const assets = await workspace.loadProject({
      id: "cdn-assets",
      source: { type: "s3", config: { bucket: "cdn-assets" } }
    });
    
    const cache = await workspace.loadProject({
      id: "local-cache",
      source: { type: "indexeddb", config: { dbName: "content-cache" } }
    });
    
    // Process content across all sources
    const articles = await cms.fs.glob("/articles/*.json");
    for (const article of articles) {
      const content = await cms.fs.readFile(article);
      const processed = await this.processArticle(content);
      
      // Cache processed content
      await cache.fs.writeFile(article, processed);
      
      // Upload assets
      if (processed.images) {
        for (const image of processed.images) {
          await assets.fs.writeFile(`/images/${image.name}`, image.data);
        }
      }
    }
  }
}
```

### 3. Data Analysis Workspace

```typescript
class DataAnalysisWorkspace {
  async analyzeData() {
    // Load datasets from different sources
    const rawData = await workspace.loadProject({
      id: "data-lake",
      source: { type: "s3", config: { bucket: "analytics-data" } }
    });
    
    const processing = await workspace.loadProject({
      id: "analysis-memory",
      source: { type: "memory", config: {} }
    });
    
    const results = await workspace.loadProject({
      id: "results-db", 
      source: { type: "indexeddb", config: { dbName: "analysis-results" } }
    });
    
    // Cross-dataset analysis
    const datasets = await rawData.fs.glob("datasets/**/*.csv");
    const analysis = {
      totalRows: 0,
      correlations: {},
      summaries: {}
    };
    
    // Process each dataset in memory for speed
    for (const dataset of datasets) {
      const data = await rawData.fs.readFile(dataset);
      const processed = await this.analyzeDataset(data.content);
      
      // Store intermediate results in memory
      await processing.fs.writeFile(`/processed/${dataset}`, processed);
      
      // Aggregate analysis
      analysis.totalRows += processed.rows;
      analysis.summaries[dataset] = processed.summary;
    }
    
    // Save final results
    await results.fs.writeFile("/analysis/summary.json", JSON.stringify(analysis));
  }
}
```

## 📊 Performance & Best Practices

### Memory Management

```typescript
// Configure auto-optimization
const workspace = new WorkspaceFileSystem({
  settings: {
    maxActiveProjects: 5,              // Auto-disable oldest
    autoDisableAfter: 30 * 60 * 1000,  // 30 minutes inactive
    keepFocusedActive: true,           // Never disable focused
    memoryThreshold: 500 * 1024 * 1024 // 500MB threshold
  }
});

// Manual optimization
const stats = await workspace.getProjectStats();
console.log(stats);
// {
//   total: 15,
//   active: 5, 
//   disabled: 10,
//   memoryUsage: "245MB",
//   connections: { s3: 2, api: 1 }
// }

// Optimize when needed
if (stats.memoryUsage > threshold) {
  await workspace.optimizeMemoryUsage();
}
```

### Efficient File Operations

```typescript
// Batch operations across projects
const operations = [
  { project: "dev", operation: () => dev.fs.writeFile("/a.txt", "content") },
  { project: "staging", operation: () => staging.fs.writeFile("/b.txt", "content") },
  { project: "prod", operation: () => prod.fs.readFile("/config.json") }
];

await Promise.all(operations.map(op => op.operation()));

// Use project capabilities efficiently
const provider = workspace.getProvider("s3");
if (provider?.getCapabilities().supportsGlob) {
  const files = await s3Project.fs.glob("**/*.log");
} else {
  // Fallback for providers without glob
  const files = await this.manualGlob(s3Project, "**/*.log");
}
```

### Error Handling

```typescript
// Robust multi-project error handling
async function robustOperation() {
  const results = { success: [], failed: [] };
  
  for (const project of workspace.getProjects()) {
    try {
      await project.fs.writeFile("/health-check.txt", new Date().toISOString());
      results.success.push(project.id);
    } catch (error) {
      console.warn(`Health check failed for ${project.id}:`, error.message);
      results.failed.push({ project: project.id, error: error.message });
      
      // Auto-disable problematic projects
      if (error.message.includes("network") || error.message.includes("credentials")) {
        await workspace.disableProject(project.id);
      }
    }
  }
  
  return results;
}
```

## 🧪 Testing

The workspace includes comprehensive test coverage with a focus on core functionality:

```bash
# Run all tests
pnpm test

# Core functionality tests
pnpm test tests/core/

# Specific test suites
pnpm test tests/core/ProjectManagement.test.ts     # Load/unload/delete
pnpm test tests/core/ProjectStateManagement.test.ts # Enable/disable  
pnpm test tests/core/CrossProjectOperations.test.ts # Multi-project ops
pnpm test tests/core/FileSystemProxy.test.ts        # Transparent proxy
pnpm test tests/core/ProviderValidation.test.ts     # Provider system
```

### Test Philosophy

- **Unit Tests**: Core workspace logic with mocked providers (fast, deterministic)
- **Integration Tests**: Real provider implementations (in individual packages)  
- **Mocked Providers**: Complete FileSystem mocks with configurable capabilities
- **Edge Cases**: Orphaned references, capability limitations, error scenarios

## 📚 Documentation

Explore our comprehensive guides to master Firesystem Workspace:

- **[Project Lifecycle Management](./docs/01-project-lifecycle.md)** - Complete guide to loading, enabling/disabling, and deleting projects
- **[Event System Guide](./docs/02-event-system.md)** - Master the reactive event system for real-time updates
- **[Provider System Guide](./docs/03-provider-system.md)** - Learn how to work with providers and create custom storage implementations
- **[Cross-Project Operations](./docs/04-cross-project-operations.md)** - Unlock the power of multi-project workflows
- **[React Integration Guide](./docs/05-react-integration.md)** - Build modern React apps with Firesystem Workspace

For code examples, check out the [examples directory](./examples/).

## 📚 API Reference

### WorkspaceFileSystem

```typescript
class WorkspaceFileSystem implements IReactiveFileSystem {
  // Project Management
  async loadProject(config: ProjectConfig): Promise<Project>
  async unloadProject(projectId: string): Promise<void>
  getProject(projectId: string): Project | null
  getProjects(): Project[]
  async setActiveProject(projectId: string): Promise<void>
  getActiveProject(): Project | null
  
  // Project Lifecycle
  async deleteProject(projectId: string, options?: DeleteProjectOptions): Promise<void>
  async disableProject(projectId: string): Promise<void>
  async enableProject(projectId: string): Promise<void>
  async disableProjects(projectIds: string[]): Promise<void>
  async enableProjects(projectIds: string[]): Promise<void>
  isProjectEnabled(projectId: string): boolean
  async getDisabledProjects(): Promise<StoredProject[]>
  
  // Cross-Project Operations
  async copyFiles(sourceId: string, pattern: string, targetId: string, targetPath: string): Promise<void>
  async syncProjects(sourceId: string, targetId: string, options?: SyncOptions): Promise<void>
  async compareProjects(projectId1: string, projectId2: string): Promise<ProjectDiff>
  
  // Provider Management
  registerProvider(provider: SourceProvider): void
  unregisterProvider(scheme: string): void
  getProvider(scheme: string): SourceProvider | undefined
  getRegisteredProviders(): SourceProvider[]
  
  // Performance & Statistics
  async getProjectStats(): Promise<WorkspaceStats>
  async getProjectMetrics(projectId: string): Promise<ProjectMetrics>
  async optimizeMemoryUsage(): Promise<OptimizationReport>
  
  // Discovery & Persistence
  async discoverIndexedDBProjects(): Promise<ProjectConfig[]>
  async exportWorkspace(options?: ExportOptions): Promise<WorkspaceExport>
  async importFromUrl(url: string): Promise<void>
  
  // All IReactiveFileSystem methods (proxied to active project)
  async readFile(path: string): Promise<FileEntry>
  async writeFile(path: string, content: any): Promise<FileEntry>
  // ... (all file system operations)
  
  // Event System
  readonly events: TypedEventEmitter<WorkspaceEventPayloads>
  
  // Lifecycle
  async initialize(config?: WorkspaceConfig): Promise<void>
  async clear(): Promise<void>
  async close(): Promise<void>
}
```

### Key Interfaces

```typescript
interface Project {
  id: string
  name: string
  source: ProjectSource
  fs: IReactiveFileSystem
  metadata: ProjectMetadata
  state: "loading" | "loaded" | "error" | "disabled"
  lastAccessed: Date
  accessCount: number
  memoryUsage: number
}

interface ProjectSource {
  type: "memory" | "indexeddb" | "s3" | "github" | "api" | "json-url"
  config: any
  auth?: SourceAuth
}

interface DeleteProjectOptions {
  deleteData?: boolean      // Also delete project data (provider-specific)
  skipConfirmation?: boolean // Skip confirmation event
}

interface SourceProvider {
  readonly scheme: string
  readonly displayName: string
  createFileSystem(config: any): Promise<IReactiveFileSystem>
  getCapabilities(): IFileSystemCapabilities
  validateConfiguration?(config: any): Promise<{ valid: boolean; errors?: string[] }>
  dispose?(fs: IReactiveFileSystem): Promise<void>
  
  // Optional data management methods
  deleteProjectData?(config: any): Promise<void>
  hasLocalData?(): boolean
  estimateDataSize?(config: any): Promise<number | null>
}

interface WorkspaceSettings {
  maxActiveProjects?: number      // Auto-disable when exceeded
  autoDisableAfter?: number       // Ms of inactivity before auto-disable
  keepFocusedActive?: boolean     // Never auto-disable focused project
  autoSave?: boolean
  autoSaveInterval?: number
  memoryThreshold?: number        // Bytes before optimization
}
```

## 🔧 Configuration

### Environment Variables

```bash
# S3 Configuration
FIRESYSTEM_S3_ACCESS_KEY_ID=your_access_key
FIRESYSTEM_S3_SECRET_ACCESS_KEY=your_secret_key
FIRESYSTEM_S3_REGION=us-east-1

# GitHub Configuration  
FIRESYSTEM_GITHUB_TOKEN=ghp_xxxxxxxxxxxx
GITHUB_TOKEN=ghp_xxxxxxxxxxxx  # Fallback

# API Configuration
FIRESYSTEM_API_API_KEY=your_api_key
FIRESYSTEM_API_BASE_URL=https://api.example.com
```

### Workspace Settings

```typescript
const workspace = new WorkspaceFileSystem({
  settings: {
    maxActiveProjects: 10,         // Keep 10 projects active max
    autoDisableAfter: 1800000,     // 30 minutes
    keepFocusedActive: true,       // Protect focused project
    autoSave: true,                // Auto-save state changes
    autoSaveInterval: 60000,       // Save every minute
    memoryThreshold: 512 * 1024 * 1024 // 512MB threshold
  }
});
```

## 🚨 Migration Guide

### From Traditional Single-Project Tools

```typescript
// Before: Single project at a time
class OldWorkflow {
  async switchToProject(projectId: string) {
    await this.closeCurrentProject();     // Lost from memory
    await this.openProject(projectId);    // Load from scratch
  }
  
  async copyToOtherProject(file: string, targetProject: string) {
    const content = await this.readFile(file);
    await this.closeCurrentProject();     // Lose current context
    await this.openProject(targetProject);
    await this.writeFile(file, content);
    await this.closeCurrentProject();     // Lose target context
    await this.openOriginalProject();     // Reload original
  }
}

// After: Multi-project simultaneous access
class NewWorkflow {
  async switchToProject(projectId: string) {
    await workspace.setActiveProject(projectId); // Just change focus
    // All other projects remain active and accessible!
  }
  
  async copyToOtherProject(file: string, targetProjectId: string) {
    const source = workspace.getActiveProject();
    const target = workspace.getProject(targetProjectId);
    
    const content = await source.fs.readFile(file);
    await target.fs.writeFile(file, content);
    // Both projects remain active, no context loss!
  }
}
```

### Version History

| Version | Release Date | Key Features |
|---------|-------------|--------------|
| **v1.0.7** | 2025-07-02 | 🗑️ Complete deleteProject, provider data management |
| **v1.0.4** | 2025-06-30 | 🧪 Comprehensive test suite, robust validation |
| **v1.0.3** | 2025-06-30 | 🧹 Auto-cleanup, empty-by-design, robust validation |
| **v1.0.2** | 2025-06-30 | 🚀 Complete workspace system with persistence |
| **v1.0.1** | 2025-06-30 | 📦 Initial release with multi-project support |

## 🤝 Contributing

We welcome contributions! Please see our [Contributing Guide](CONTRIBUTING.md) for details.

### Development Setup

```bash
# Clone the repository
git clone https://github.com/firesystem/firesystem.git
cd firesystem/packages/workspace

# Install dependencies
pnpm install

# Run tests
pnpm test

# Type checking
pnpm typecheck

# Build
pnpm build
```

## 📋 Roadmap

### v1.1.0 - Enhanced Cloud Support
- [ ] Native S3FileSystem implementation
- [ ] Google Drive source provider
- [ ] Azure Blob Storage support
- [ ] Enhanced GitHub integration with commit/push

### v1.2.0 - Advanced Operations
- [ ] Project templates and scaffolding
- [ ] Advanced sync strategies
- [ ] Workspace-level search across all projects
- [ ] Project dependency management

### v1.3.0 - Performance & Scale
- [ ] Virtual file system for large projects
- [ ] Streaming file operations
- [ ] Background sync and preloading
- [ ] Advanced caching strategies

### v2.0.0 - Collaboration Features
- [ ] Real-time collaboration protocol
- [ ] Multi-user workspace sharing
- [ ] Role-based access control
- [ ] Audit logging and analytics

## 📄 License

MIT © Anderson D. Rosa

## 🙏 Acknowledgments

- Built on top of the robust [@firesystem/core](../core) foundation
- Inspired by VSCode's multi-root workspace concept, but taken to the next level
- Thanks to the TypeScript team for excellent type system
- IndexedDB API for reliable browser persistence
- The open source community for continuous inspiration

---

**🔥 Transform your development workflow with true multi-project parallelism!**