13 KiB
OpenWork Product Requirements Document (PRD)
Summary
OpenWork is an open-source native GUI (Tauri) that makes OpenCode feel like a polished consumer app for non-technical people.
- OpenCode is the engine.
- OpenWork is the experience: onboarding, safety, permissions, progress, artifacts, and a premium-feeling UI.
OpenWork competes directly with Anthropic’s Cowork conceptually, but stays open, local-first, and standards-based.
Goals
- Deliver a premium, extremely slick user experience (desktop + mobile).
- Make OpenCode usable without a terminal.
- Launch/attach to an OpenCode instance automatically when OpenWork starts.
- Expose OpenCode primitives (sessions, messages, tools, permissions, files) in a non-technical UI.
- Provide long-running tasks with resumability.
- Provide explicit, understandable permissions and auditing.
- Work with only the folders the user authorizes.
- Treat plugins + skills as the primary extensibility system.
Non-Goals
- Replacing OpenCode’s CLI/TUI.
- Shipping a hosted SaaS in v1.
- Creating bespoke “magic” capabilities that don’t map to OpenCode APIs.
Target Users
- Non-technical knowledge worker: “Do this for me” workflows with guardrails.
- Mobile-first user: start/monitor tasks from phone.
- Power user: wants UI parity + speed + inspection.
- Admin/host: manages a shared machine + profiles.
Success Metrics
- < 5 minutes to first successful task on fresh install.
-
80% task success without terminal fallback.
- Permission prompts understood/accepted (low confusion + low deny-by-accident).
- UI performance: 60fps; <100ms interaction latency; no jank.
Principles
- Parity: UI actions map to OpenCode server APIs.
- Transparency: plans, steps, tool calls, permissions are visible.
- Least privilege: only user-authorized folders + explicit approvals.
- Prompt is the workflow: product logic lives in prompts, rules, and skills.
- Graceful degradation: if access is missing, guide the user.
Core Architecture
OpenWork is a Tauri application with two runtime modes:
Mode A — Host (Desktop)
- OpenWork runs on a desktop/laptop and starts OpenCode locally.
- The OpenCode server runs on loopback (default
127.0.0.1:4096). - OpenWork UI connects via the official SDK and listens to events.
Mode B — Client (Mobile)
- OpenWork runs on iOS/Android as a remote controller.
- It connects to an already-running OpenCode server hosted by a trusted device.
- Pairing uses a QR code / one-time token and a secure transport (LAN or tunneled).
This split makes mobile “first-class” without requiring the full engine to run on-device.
OpenCode Integration (Exact SDK + APIs)
OpenWork uses the official JavaScript/TypeScript SDK:
- Package:
@opencode-ai/sdk/v2(UI should import@opencode-ai/sdk/v2/clientto avoid Node-only server code) - Purpose: type-safe client generated from OpenAPI spec
Engine Lifecycle
Start server + client (Host mode)
Use createOpencode() to launch the OpenCode server and create a client.
import { createOpencode } from "@opencode-ai/sdk/v2";
const opencode = await createOpencode({
hostname: "127.0.0.1",
port: 4096,
timeout: 5000,
config: {
model: "anthropic/claude-3-5-sonnet-20241022",
},
});
const { client } = opencode;
// opencode.server.url is available
Connect to an existing server (Client mode)
import { createOpencodeClient } from "@opencode-ai/sdk/v2/client";
const client = createOpencodeClient({
baseUrl: "http://localhost:4096",
directory: "/path/to/project",
});
Health + Version
client.global.health()- Used for startup checks, compatibility warnings, and diagnostics.
Event Streaming (Real-time UI)
OpenWork must be real-time. It subscribes to SSE events:
client.event.subscribe()
The UI uses these events to drive:
- streaming assistant responses
- step-level tool execution timeline
- permission prompts
- session lifecycle changes
Sessions (Primary Primitive)
OpenWork maps a “Task Run” to an OpenCode Session.
Core methods:
client.session.create()client.session.list()client.session.get()client.session.messages()client.session.prompt()client.session.abort()client.session.summarize()
Files + Search
OpenWork’s file browser and “what changed” UI are powered by:
client.find.text()client.find.files()client.find.symbols()client.file.read()client.file.status()
Permissions
OpenWork must surface permission requests clearly and respond explicitly.
- Permission response API:
client.permission.reply({ requestID, reply })(wherereplyisonce|always|reject)
OpenWork UI should:
- Show what is being requested (scope + reason).
- Provide choices (allow once / allow for session / deny).
- Post the response to the server.
- Record the decision in the run’s audit log.
Config + Providers
OpenWork’s settings pages use:
client.config.get()client.config.providers()client.auth.set()(optional flow to store keys)
Extensibility — Skills + Plugins
OpenWork exposes two extension surfaces:
-
Skills (OpenPackage)
- Installed into
.opencode/skill/*. - OpenWork can run
opkg installto pull packages from the registry or GitHub.
- Installed into
-
Plugins (OpenCode)
- Plugins are configured via
opencode.jsonin the workspace. - The format is the same as OpenCode CLI uses today.
- OpenWork should show plugin status and instructions; a native plugin manager is planned.
- Plugins are configured via
OpenPackage Registry (Current + Future)
- Today, OpenWork only supports curated lists + manual sources.
- Publishing to the official registry currently requires authentication (
opkg push+opkg configure). - Future goals:
- in-app registry search
- curated list sync (e.g. Awesome Claude Skills)
- frictionless publishing without signup (pending registry changes)
When it comes to design
use the design from ./design.ts that is your core reference for building the entire ui
Projects + Path
client.project.list()/client.project.current()client.path.get()
OpenWork conceptually treats “workspace” as the current project/path.
Optional TUI Control (Advanced)
The SDK exposes client.tui.* methods. OpenWork can optionally provide a “Developer Mode” screen to:
- append/submit prompt
- open help/sessions/themes/models
- show toast
This is optional and not required for non-technical MVP.
Folder Authorization Model
OpenWork enforces folder access through two layers:
-
OpenWork UI authorization
- user explicitly selects allowed folders via native picker
- OpenWork remembers allowed roots per profile
-
OpenCode server permissions
- OpenCode requests permissions as needed
- OpenWork intercepts requests via events and displays them
Rules:
- Default deny for anything outside allowed roots.
- “Allow once” never expands persistent scope.
- “Allow for session” applies only to the session ID.
- “Always allow” (if offered) must be explicit and reversible.
Product Primitives (What OpenWork Exposes)
OpenWork must feel like “OpenCode, but for everyone.”
1) Tasks
- A Task = a user-described outcome.
- A Run = an OpenCode session + event stream.
2) Plans / Todo Lists
OpenWork provides a first-class plan UI:
- Plan is generated before execution (editable).
- Plan is updated during execution (step status + timestamps).
- Plan is stored as a structured artifact attached to the session (JSON) so it’s reconstructable.
Implementation detail:
- The plan is represented in OpenCode as structured
parts(or a dedicated “plan message”) and mirrored in OpenWork.
3) Steps
- Each tool call becomes a step row with:
- tool name
- arguments summary
- permission state
- start/end time
- output preview
4) Artifacts
Artifacts are user-visible outputs:
- files created/modified
- generated documents/spreadsheets/presentations
- exported logs and summaries
OpenWork lists artifacts per run and supports open/share/download.
5) Audit Log
Every run provides an exportable audit log:
- prompts
- plan
- tool calls
- permission decisions
- outputs
UI/UX Requirements (Slick as a Core Goal)
Design Targets
- premium, calm, high-contrast
- subtle motion, springy transitions
- zero “developer vibes” in default mode
Performance Targets
- 60fps animations
- <100ms input-to-feedback
- no blocking spinners (always show progress state)
Mobile-first Interaction
- bottom navigation
- swipe gestures (dismiss, approve, cancel)
- haptics for major events
- adaptive layouts (phone/tablet)
Accessibility
- WCAG 2.1 AA
- reduced motion mode
- screen-reader labels for steps + permissions
Functional Requirements
Onboarding
- Host vs Client selection
- workspace selection (Host)
- connect to host (Client)
- provider/model setup
- first-run “hello world” task
Task Execution
- create task
- plan preview and edit
- run with streaming updates
- pause/resume/cancel
- show artifacts and summaries
Permissions
- clear prompts with “why”
- allow once/session
- audit of decisions
Templates
- save a task as template
- variables + quick run
Scheduling (Future)
- schedule template runs
- notify on completion
User Flow Map (Exhaustive)
0. Install & Launch
- User installs OpenWork.
- App launches.
- App shows “Choose mode: Host / Client”.
- Host: start local OpenCode via SDK.
- Client: connect flow to an existing host.
1. First-Run Onboarding (Host)
- Welcome + safety overview.
- Workspace folder selection.
- Allowed folders selection (can be multiple).
- Provider/model configuration.
global.health()check.- Run a test session using
session.create()+session.prompt(). - Success + sample templates.
2. Pairing Onboarding (Client / Mobile)
- User selects “Client”.
- UI explains it connects to a trusted host.
- User scans QR code shown on host device.
- Client verifies connection with
global.health(). - Client can now list sessions and monitor runs.
3. Runtime Health & Recovery
- UI pings
global.health(). - If unhealthy:
- Host: attempt restart via
createOpencode(). - Client: show reconnect + diagnostics.
- Host: attempt restart via
4. Quick Task Flow
- User types goal.
- OpenWork generates plan (structured).
- User approves.
- Create session:
session.create(). - Send prompt:
session.prompt(). - Subscribe to events:
event.subscribe(). - Render streaming output + steps.
- Show artifacts.
5. Guided Task Flow
- Wizard collects goal, constraints, outputs.
- Plan preview with “risky step” highlights.
- Run execution with progress UI.
6. File-Driven Task Flow
- User attaches files.
- OpenWork injects context into session.
- Execute prompt.
7. Permissions Flow (Any)
- Event indicates permission request.
- UI modal shows request.
- User chooses allow/deny.
- UI calls
client.permission.reply({ requestID, reply }). - Run continues or fails gracefully.
8. Cancel / Abort
- User clicks “Stop”.
- UI calls
client.session.abort({ sessionID }). - UI marks run stopped.
9. Summarize
- User taps “Summarize”.
- UI calls
client.session.summarize({ sessionID }). - Summary displayed as an artifact.
10. Run History
- UI calls
session.list(). - Tap a session to load
session.messages(). - UI reconstructs plan and steps.
11. File Explorer + Search
- User searches:
find.text(). - Open file:
file.read(). - Show changed files:
file.status().
12. Templates
- Save a plan + prompt as a template.
- Re-run template creates a new session.
13. Multi-user (Future)
- separate profiles
- separate allowed folders
- separate providers/keys
Security & Privacy
- Local-first by default.
- No secrets in git.
- Use OS keychain for credentials.
- Clear, explicit permissions.
- Exportable audit logs.
Open Questions
- Best packaging strategy for Host mode engine (bundled vs user-installed Node/runtime).
- Best remote transport for mobile client (LAN only vs optional tunnel).
- Scheduling API surface (native in OpenCode server vs OpenWork-managed scheduler).
Milestones
v0.1 — Engine + Client
- Host mode: start OpenCode via
createOpencode(). - Client mode: connect via
createOpencodeClient(). - Health screen + basic sessions list.
v0.2 — Full Run Loop
- create session
- send prompt
- stream events
- display step timeline
- permission prompts
v0.3 — Premium UX
- micro-interactions and animations
- mobile layouts + gestures
- templates
v1.0 — Public Open Source Release
- strong onboarding
- multi-device pairing
- audit/export
- docs + examples