Composer & Lexical Editor
Relevant source files
The following files were used as context for generating this wiki page:
The Composer is the primary interaction interface in OpenWork, allowing users to draft prompts, attach files, and trigger agentic workflows. It leverages the Lexical framework to provide a rich-text editing experience that supports specialized tokens such as mentions (@), slash commands (/), and collapsed paste chips.
The system is designed with a "local-first" philosophy, orchestrating local and remote agent workflows while providing precise control over model selection and behavior. It integrates deeply with the OpenCode engine to manage skills, MCP (Model Context Protocol) tools, and complex task execution.
Sources: AGENTS.md, README.md, apps/app/src/react-app/domains/session/surface/composer/composer.tsx:244-245
Architecture and Components
The composer architecture is split between a high-level React wrapper (ReactSessionComposer) and a specialized editor core (LexicalPromptEditor).
Core Components
- ReactSessionComposer: Manages the surrounding UI, including tool menus, attachment lists, agent/model selection, and submission logic.
- LexicalPromptEditor: A custom Lexical implementation that handles input serialization, mention/command detection, and specialized node rendering.
- Actions Store: Orchestrates the communication between the UI and the OpenCode SDK, handling session creation and prompt submission.
Lexical Editor Implementation
The editor uses custom Lexical nodes to represent interactive entities within the text flow. These nodes are atomic and immutable from the user's perspective during standard typing.
Specialized Nodes
| Node Type | Trigger / Prefix | Purpose |
|---|---|---|
ComposerMentionNode | @ | Mentions files or agents. |
ComposerSlashCommandNode | / | Triggers specific slash commands (e.g., /review, /compact). |
ComposerSkillNode | [skill ...] | References an installed skill. |
ComposerPastedTextNode | N/A | Collapses large pasted text into an interactive chip. |
Sources: apps/app/src/react-app/domains/session/surface/composer/editor.tsx:55-256
Input Serialization
The editor does not store raw HTML. Instead, it serializes the document tree into a specific draft string format for the backend. It uses a custom serializePromptFromRoot function to ensure newlines are preserved correctly, avoiding Lexical's default double-newline behavior for paragraph nodes.
Sources: apps/app/src/react-app/domains/session/surface/composer/editor.tsx:327-333
Submission and Execution Flow
The composer handles submission differently based on the agent's current state (busy vs. idle).
Tool Menus and Extensions
The composer features a multi-tabbed "Tools" menu allowing users to discover and insert commands, skills, extensions, and MCP apps.
- Slash Commands: Fetched from the OpenCode engine; filtered via
fuzzysortas the user types/. - Skills: Managed under
.opencode/skills/. Skills can be created directly in the chat using the/skill-creatortemplate. - MCP Servers: Exposes tools from connected apps like Notion, Linear, or custom local commands.
Sources: apps/app/src/react-app/domains/session/surface/composer/composer.tsx:142-230, apps/app/src/app/data/skill-creator.md:12-18
Attachment Handling
The system supports file and image attachments with a default limit of 8MB.
Image Optimization
Large images are automatically scaled and compressed before being uploaded to prevent payload bloat. The system targets a maximum dimension of 2048px and converts images to JPEG at 0.82 quality if they exceed approximately 1.5MB.
Paste Logic and Collapse Policy
To maintain a clean editing surface, the composer implements a collapse policy for large text pastes.
- Trigger: Pastes exceeding 3 lines OR 200 characters.
- Behavior: The raw text is intercepted and replaced with a
ComposerPastedTextNode(amber chip). - Resolution: When the prompt is sent, the
ActionsStoreresolves the full text content from the internal draft mapping before sending it to the model.
Sources: apps/app/src/react-app/domains/session/surface/composer/editor.tsx:406-410, evals/react-session-flows.md:653-660
Conclusion
The Composer & Lexical Editor system provides a high-fidelity interface for human-agent collaboration. By combining the rich-text capabilities of Lexical with a structured actions store and deep OpenCode integration, it enables complex agentic tasks while remaining accessible to non-technical users. The use of specialized nodes for commands and mentions ensures that user intent is captured accurately and rendered intuitively.