import React, { useState, useEffect, useRef } from 'react'; import { Command, Shield, Zap, Layout, Settings, ChevronRight, Play, CheckCircle2, Circle, AlertCircle, FileText, X, Terminal, Smartphone, HardDrive, Cpu, MoreHorizontal, ArrowRight, Clock, Menu, Download, Folder, Plus, Trash2, LogOut, RefreshCcw, Package, Globe, ChevronDown, FolderPlus, Check, Search, Box, BrainCircuit, Wrench, History, Sparkles, LayoutTemplate, Loader2, MessageSquare, ArrowUp } from 'lucide-react'; // --- Mock Data & Types --- const MOCK_TEMPLATES = [ { id: 't1', title: "Understand this workspace", description: "Explains local vs global tools", icon: "help-circle", prompt: "Explain how this workspace is configured and what tools are available locally." }, { id: 't2', title: "Create a new skill", description: "Guide to adding capabilities", icon: "sparkles", prompt: "I want to create a new skill for this workspace. Guide me through it." }, { id: 't3', title: "Run a scheduled task", description: "Demo of the scheduler plugin", icon: "clock", prompt: "Show me how to schedule a task to run every morning." }, { id: 't4', title: "Turn task into template", description: "Save workflow for later", icon: "save", prompt: "Help me turn the last task into a reusable template." }, ]; const MOCK_SESSIONS = [ { id: 104, title: "Create 'Data Cleaner' Skill", status: "running", date: "2 mins ago", workspaceId: 'starter' }, { id: 101, title: "Update Dependencies", status: "completed", date: "1 hour ago", workspaceId: 'starter' }, { id: 102, title: "Fix CSS Bug", status: "failed", date: "Yesterday", workspaceId: 'proj_alpha' }, { id: 103, title: "Deploy to Prod", status: "waiting", date: "Yesterday", workspaceId: 'personal_blog' }, ]; const MOCK_WORKSPACES = [ { id: 'starter', name: 'My First Workspace', path: '~/Documents/OpenWork/MyWorkspace', type: 'starter', icon: Zap }, { id: 'proj_alpha', name: 'Project Alpha', path: '~/Documents/Code/alpha', type: 'custom', icon: Folder }, { id: 'personal_blog', name: 'Personal Blog', path: '~/Github/blog', type: 'custom', icon: Globe }, ]; const MOCK_EXTENSIONS = { plugins: [ { id: 'p1', name: 'OpenCode Scheduler', version: '0.9.0', description: 'Run tasks on a cron schedule.', scope: 'workspace', status: 'active' }, { id: 'p2', name: 'Browser Automation', version: '1.2.0', description: 'Headless browser control.', scope: 'global', status: 'active' }, { id: 'p3', name: 'Python Runtime', version: '3.11.0', description: 'Execute Python scripts locally.', scope: 'workspace', status: 'active' }, ], skills: [ { id: 's1', name: 'Workspace Guide', description: 'Teaches you how to use this workspace.', scope: 'workspace', status: 'active' }, { id: 's2', name: 'Meeting Summarizer', description: 'Extracts action items from transcripts.', scope: 'global', status: 'active' }, ] }; // --- Components --- const OpenWorkLogo = ({ size = 24, className = "" }) => ( ); const Button = ({ children, variant = "primary", className = "", onClick, disabled }) => { const baseStyle = "px-4 py-2.5 rounded-xl font-medium transition-all duration-200 flex items-center justify-center gap-2 active:scale-95 text-sm"; const variants = { primary: "bg-white text-black hover:bg-gray-100 shadow-lg shadow-white/5", secondary: "bg-zinc-800 text-zinc-100 hover:bg-zinc-700 border border-zinc-700/50", ghost: "bg-transparent text-zinc-400 hover:text-white hover:bg-zinc-800/50", danger: "bg-red-500/10 text-red-400 hover:bg-red-500/20 border border-red-500/20", outline: "border border-zinc-700 text-zinc-300 hover:border-zinc-500 bg-transparent", }; return ( ); }; const StatusBadge = ({ status }) => { const styles = { completed: "bg-emerald-500/10 text-emerald-400 border-emerald-500/20", running: "bg-blue-500/10 text-blue-400 border-blue-500/20 animate-pulse", waiting: "bg-amber-500/10 text-amber-400 border-amber-500/20", failed: "bg-red-500/10 text-red-400 border-red-500/20", stopped: "bg-zinc-500/10 text-zinc-400 border-zinc-500/20", }; return ( {status.charAt(0).toUpperCase() + status.slice(1)} ); }; // --- Workspace Components --- const WorkspaceChip = ({ activeWorkspace, onClick }) => { const Icon = activeWorkspace.icon || Folder; return ( ); }; const WorkspacePicker = ({ isOpen, onClose, workspaces, activeWorkspaceId, onSelect, onCreateNew }) => { if (!isOpen) return null; return (
e.stopPropagation()}>
Active
{workspaces.map(ws => { const Icon = ws.icon; return ( ); })}
); }; const CreateWorkspaceModal = ({ isOpen, onClose, onConfirm }) => { const [step, setStep] = useState(1); const [template, setTemplate] = useState('starter'); if (!isOpen) return null; return (

Create Workspace

Initialize a new folder-based workspace.

1
Select Folder
= 1 ? 'opacity-100' : 'opacity-40'}`}>
2
Choose Preset
{[ { id: 'starter', name: 'Starter', desc: 'Pre-configured with Scheduler & Core Tools. Best for general use.' }, { id: 'automation', name: 'Automation', desc: 'Optimized for background tasks and scripting.' }, { id: 'minimal', name: 'Minimal', desc: 'Empty project. Connects only to core engine.' } ].map(t => (
setTemplate(t.id)} className={`p-4 rounded-xl border cursor-pointer transition-all ${template === t.id ? 'bg-indigo-500/10 border-indigo-500/50' : 'bg-zinc-900 border-zinc-800 hover:border-zinc-700'}`} >
{t.name}
{t.desc}
{template === t.id && }
))}
); }; const SettingsModal = ({ isOpen, onClose, currentMode, onSwitchMode, onClearPreference }) => { if (!isOpen) return null; return (

Settings

{currentMode === 'host' ? : }
{currentMode} Mode
); }; // --- Main Views --- const ExtensionsView = ({ activeWorkspace, onCreateSkill }) => { const [tab, setTab] = useState('skills'); // 'plugins' | 'skills' return (

Extensions

Capabilities available to your sessions.

{/* Skills Tab */} {tab === 'skills' && (

Create a Custom Skill

Teaches OpenCode how to perform a specific workflow in plain English.

{MOCK_EXTENSIONS.skills.map(skill => (
{skill.name}
{skill.description}
{skill.scope === 'workspace' && ( WORKSPACE )}
))}
)} {/* Plugins Tab */} {tab === 'plugins' && (

Plugins provide low-level capabilities (engine primitives). They are configured in opencode.json.

{MOCK_EXTENSIONS.plugins.map(plugin => (
{plugin.name}
{plugin.description}
{plugin.scope === 'workspace' && ( WORKSPACE )} {plugin.scope === 'global' && ( GLOBAL )}
))}
)}
); }; const SessionsListView = ({ onOpenSession, sessions = MOCK_SESSIONS }) => { return (

Global Sessions

Your history of tasks across all workspaces.

{sessions.map((s, i) => (
onOpenSession(s)} key={s.id} className={`p-4 flex items-center justify-between hover:bg-zinc-800/50 transition-colors cursor-pointer ${i !== sessions.length - 1 ? 'border-b border-zinc-800/50' : ''}`}>
#{s.id}
{s.title}
{s.date} {MOCK_WORKSPACES.find(w => w.id === s.workspaceId)?.name}
))}
) } const OnboardingView = ({ onComplete }) => { const [step, setStep] = useState('mode-select'); // mode-select | create-workspace | initializing const [mode, setMode] = useState(null); const [initStage, setInitStage] = useState(0); const handleModeSelect = (selectedMode) => { setMode(selectedMode); if (selectedMode === 'host') { setStep('create-workspace'); } else { onComplete(selectedMode); } }; const handleCreateWorkspace = () => { setStep('initializing'); // Simulate staging setTimeout(() => setInitStage(1), 800); setTimeout(() => setInitStage(2), 1600); setTimeout(() => setInitStage(3), 2400); setTimeout(() => setInitStage(4), 3200); }; if (step === 'create-workspace') { return (

Create your first workspace

A workspace is just a folder with its own skills, plugins, and tasks.

~/Documents/OpenWork/
); } if (step === 'initializing') { return (

Setting up workspace...

Populating your folder with superpowers

= 1 ? 'bg-zinc-900/50 border-zinc-800 opacity-100' : 'border-transparent opacity-50'}`}> {initStage >= 1 ? : } Installing Scheduler Plugin (Workspace-local)
= 2 ? 'bg-zinc-900/50 border-zinc-800 opacity-100' : 'border-transparent opacity-50'}`}> {initStage >= 2 ? : (initStage === 1 ? : )} Adding "Workspace Guide" Skill
= 3 ? 'bg-zinc-900/50 border-zinc-800 opacity-100' : 'border-transparent opacity-50'}`}> {initStage >= 3 ? : (initStage === 2 ? : )} Generating Starter Templates
= 4 ? 'opacity-100 translate-y-0' : 'opacity-0 translate-y-4'}`}>
); } return (

OpenWork

How would you like to run OpenWork today?

); }; const SessionView = ({ initialSession, onBack, activeWorkspace, injectedPrompt }) => { const [messages, setMessages] = useState([]); const [input, setInput] = useState(''); const [formRequest, setFormRequest] = useState(null); // Special modal state const messagesEndRef = useRef(null); useEffect(() => { if (injectedPrompt) { // Auto-send the template prompt if provided setMessages([{ id: Date.now(), role: 'user', content: injectedPrompt }]); // Mock Response logic based on prompt setTimeout(() => { let response = "I can help with that."; if (injectedPrompt.includes("create a new skill")) { response = "I'll help you create a new skill for this workspace. I need a few details to get started."; setTimeout(() => { setFormRequest({ id: 'form_1', title: 'New Skill Details', fields: [ { name: 'name', label: 'Skill Name', placeholder: 'e.g. daily-summarizer' }, { name: 'description', label: 'What does it do?', placeholder: 'Summarizes daily logs...' } ] }); }, 1500); } else if (injectedPrompt.includes("configured")) { response = `I'm running inside **${activeWorkspace.name}**. This workspace is a folder located at \`${activeWorkspace.path}\`\n\n**Locally Installed:**\n- Scheduler Plugin\n- Python Runtime\n- Workspace Guide Skill\n\nSessions here are part of your global history but tagged to this workspace.`; } setMessages(prev => [...prev, { id: Date.now() + 1, role: 'assistant', content: response }]); }, 800); } else if (initialSession) { // Existing session loaded if (initialSession.id === 'onboarding-1') { // ... existing onboarding logic if needed ... } } }, [initialSession, activeWorkspace, injectedPrompt]); const handleSend = () => { if (!input.trim()) return; setMessages(prev => [...prev, { id: Date.now(), role: 'user', content: input }]); setInput(''); // Mock response setTimeout(() => { setMessages(prev => [...prev, { id: Date.now()+1, role: 'assistant', content: "I'm working on that..." }]); }, 1000); }; const handleFormSubmit = (data) => { setFormRequest(null); setMessages(prev => [ ...prev, { id: Date.now(), role: 'system', content: `Tool Output: ${JSON.stringify(data)}`, type: 'audit' }, { id: Date.now()+1, role: 'assistant', content: `Great. I'm creating the skill "${data.name}". I've generated the SKILL.md and config files.` } ]); }; return (

{initialSession?.title || 'New Session'}

{activeWorkspace.name}
{messages.map((msg) => (
{msg.type === 'audit' ? (
{msg.content}
) : ( <>
{msg.content.split('\n').map((line, i) => (

0 ? "mt-3" : ""}`}>{line}

))}
)}
))}
setInput(e.target.value)} onKeyDown={(e) => e.key === 'Enter' && handleSend()} placeholder="Message OpenWork..." className="w-full bg-zinc-900 border border-zinc-800 rounded-xl py-3.5 pl-4 pr-12 text-white placeholder-zinc-500 focus:outline-none focus:border-zinc-700 transition-colors shadow-sm" />

OpenWork can make mistakes. Check important info.

{/* Tool Form Modal */} {formRequest && (
{formRequest.title}
{formRequest.fields.map(field => (
))}
)}
); }; const DashboardView = ({ onStartTask, isHost, onOpenSettings, activeWorkspace, onChangeWorkspace, onNavigate, onViewChange, sessions, onTemplateClick }) => { const [showWorkspacePicker, setShowWorkspacePicker] = useState(false); const [showCreateWorkspace, setShowCreateWorkspace] = useState(false); const [workspaces, setWorkspaces] = useState(MOCK_WORKSPACES); return (
setShowWorkspacePicker(true)} />

How can I help you today?

{MOCK_TEMPLATES.slice(0, 4).map((t) => ( ))}
setShowWorkspacePicker(false)} workspaces={workspaces} activeWorkspaceId={activeWorkspace.id} onSelect={onChangeWorkspace} onCreateNew={() => setShowCreateWorkspace(true)} /> setShowCreateWorkspace(false)} onConfirm={() => {}} />
); }; // --- Main App Controller --- export default function App() { const [view, setView] = useState('loading'); const [mode, setMode] = useState(null); const [activeWorkspaceId, setActiveWorkspaceId] = useState('starter'); const [workspaces, setWorkspaces] = useState(MOCK_WORKSPACES); const [currentSession, setCurrentSession] = useState(null); const [sessions, setSessions] = useState(MOCK_SESSIONS); const [injectedPrompt, setInjectedPrompt] = useState(null); const activeWorkspace = workspaces.find(w => w.id === activeWorkspaceId) || workspaces[0]; useEffect(() => { const pref = localStorage.getItem('openwork_mode_pref'); if (pref) { setTimeout(() => { setMode(pref); setView('dashboard'); }, 800); } else { setView('onboarding'); } }, []); const handleOnboardingComplete = (selectedMode) => { setMode(selectedMode); setView('dashboard'); // Go to dashboard, don't auto-start session }; const handleStartTask = (prompt = null) => { const newSession = { id: Date.now(), title: prompt ? prompt.slice(0, 20) + '...' : 'New Task', workspaceId: activeWorkspaceId }; setCurrentSession(newSession); setSessions([newSession, ...sessions]); setInjectedPrompt(prompt); // Pass prompt to session view setView('session'); }; const handleCreateSkill = (title, prompt) => { handleStartTask(prompt); }; const handleOpenSession = (s) => { setCurrentSession(s); setInjectedPrompt(null); setView('session'); }; const handleTemplateClick = (template) => { handleStartTask(template.prompt); }; return (
{view === 'onboarding' && } {view === 'dashboard' && ( handleStartTask()} isHost={mode === 'host'} activeWorkspace={activeWorkspace} onChangeWorkspace={setActiveWorkspaceId} onViewChange={setView} sessions={sessions} onNavigate={handleOpenSession} onTemplateClick={handleTemplateClick} /> )} {/* Global Sidebar Wrapper for Non-Dashboard Views */} {['skills', 'plugins', 'sessions'].includes(view) && (
{view === 'skills' && } {view === 'plugins' && } {view === 'sessions' && }
)} {view === 'session' && ( setView('dashboard')} activeWorkspace={activeWorkspace} injectedPrompt={injectedPrompt} /> )}
); }