Imported from janipasanen/opencode-swift (
AGENTS.md). Install upstream withnpx skills add janipasanen/opencode-swift. Copyright stays with the author.
OpenCode Swift Rewrite AGENTS
Purpose
This repository is a clean-room Swift rewrite of the terminal-focused OpenCode experience from https://github.com/anomalyco/opencode.
The target is a macOS 10.15-compatible, Swift 5.3 terminal application that preserves the core OpenCode TUI workflow:
- interactive chat in the terminal
- session/history management
- agent selection and routing
- file reading, patching, and command execution tools
- permission prompts and safety gates
- LSP-assisted code navigation
- configurable AI provider backends
- status, logs, diffs, file picker, and command palette UI
This is not a desktop GUI rewrite. It must remain terminal-first.
Hard Constraints
- Minimum OS: macOS 10.15
- Language: Swift 5.3
- Build system: Swift Package Manager
- Runtime model: synchronous Swift 5.3 / callback-driven / DispatchQueue-based
- Avoid Swift concurrency features unavailable in Swift 5.3
- Avoid APIs introduced after macOS 10.15
- Prefer Foundation, Dispatch, and AppKit only where terminal integration requires it
- Preserve a CLI/TUI architecture, not SwiftUI-based desktop UI
Primary Design Goal
Match the terminal experience of OpenCode as closely as practical while staying compatible with Catalina.
The highest-value user flows to reproduce are:
- start the app in a terminal
- select or create a session
- type and edit prompts in a rich multiline editor
- display streaming assistant output
- execute shell commands through permission-gated tool calls
- inspect file contents and diffs
- switch agents/models/providers
- browse logs, sessions, and files from the TUI
Source Repo Features To Mirror
Use the upstream OpenCode behavior as the product reference, especially these areas from the original repo:
internal/tuifor terminal interaction patternsinternal/llmfor provider, agent, and tool orchestrationinternal/lspfor workspace language intelligenceinternal/sessionandinternal/historyfor session persistenceinternal/dbfor structured storage of sessions/messages/files/logsinternal/permissionfor approval gatinginternal/llm/toolsfor shell, file, search, diff, patch, and LSP actions
Suggested Swift Module Layout
Keep the package small and explicit. Use modules or nested folders along these lines:
App/- startup, argument parsing, app lifecycle, dependency wiring
Terminal/- raw mode, alternate screen, key handling, mouse handling if needed
TUI/- root screen, layout, panes, focus management, rendering
Editor/- multiline prompt editor, history navigation, autocomplete hooks
Session/- sessions, messages, transcripts, persistence, restore
Agent/- model/agent routing, tool call execution, streaming response handling
Tools/- filesystem, shell, grep, glob, patch, view, write, batch, LSP actions
Providers/- OpenAI-compatible, Anthropic-compatible, Google-compatible, local/mock adapters
LSP/- workspace indexing, diagnostics, symbols, references, code actions
Storage/- SQLite wrapper or equivalent persistence layer
Config/- config file parsing, environment variables, defaults
UI/- theme, colors, layout primitives, status bar, dialogs, file picker, logs, diff viewer
Initial Product Scope
Implement in this order:
- terminal shell and screen management
- prompt editor with history and basic autocomplete
- session persistence and replay
- assistant streaming and message rendering
- shell command tool with approval prompts
- file view/edit/patch tools
- diff rendering
- logs and session browser
- LSP support
- provider adapters and model selection
Terminal Requirements
The app should support:
- alternate screen buffer
- raw input mode
- arrow key navigation
- tab-based focus switching
- multiline editing
- prompt submission
- escape/cancel semantics
- scrollable panels
- selectable lists and dialogs
- inline status area
- optional mouse support if it does not complicate Catalina compatibility
Rendering Requirements
The TUI should render:
- main chat panel
- session sidebar
- command or tool output panel
- status/footer area
- permission dialogs
- model/agent pickers
- file picker / file tree
- logs and diff views
ANSI rendering is acceptable for the first version, but the code should be structured so a richer renderer can be added later.
Tooling Model
Treat tools as first-class execution units with structured inputs and outputs.
Minimum tool set:
read_filewrite_filepatch_filelist_filesglobgreprun_shell_commandopen_diffquery_lspfetch_urlonly if network use is explicitly enabled
Each tool invocation should:
- be serializable
- record output in session history
- respect permission rules
- surface failures clearly in the UI
Permission Model
Any destructive or potentially sensitive action should be gated.
At minimum prompt before:
- shell execution
- file writes
- patch application
- network access
- commands outside the project root
Support allow/deny/remember decisions in session state or config.
Persistence Model
Use a durable local store for:
- sessions
- messages
- tool events
- permissions
- file snapshots or references
- logs
SQLite is the simplest long-term choice, but any local store is acceptable if it is reliable on macOS 10.15 and can preserve sessions across restarts.
Provider Abstraction
Keep provider-specific code isolated.
The provider layer should support:
- request/response streaming
- tool-call envelopes
- model metadata
- cancellation
- retries and error mapping
- provider-specific auth via env vars and config file
If a provider is not implemented yet, use a stub that fails clearly rather than leaking provider details into the UI layer.
LSP Model
LSP support should be workspace-oriented and optional.
It should support:
- workspace discovery
- server launch and restart
- document sync
- diagnostics
- references
- symbols
- definitions
- code actions
Do not block the terminal UI while indexing. Run long-lived work on background queues.
Coding Conventions
- Keep public APIs small
- Separate rendering from state management
- Prefer explicit state machines over hidden side effects
- Prefer value types where practical
- Keep protocol boundaries narrow
- Add tests for parser, state, persistence, and tool dispatch logic
- Do not use platform APIs newer than macOS 10.15
Build Expectations
The package manifest should remain Swift 5.3 compatible.
Expected developer workflow:
swift buildswift testswift run opencode-swift
If native dependencies are added, document how they are built on Catalina.
Development Workflow
- Work in small, reviewable implementation tasks.
- For each task, add or update tests, run the relevant test suite, and fix failures before moving on.
- Commit completed tasks before starting the next one.
- Keep a running implementation backlog in
docs/implementation-tasks.mdand update it whenever scope changes or a task is completed.
Non-Goals For The First Pass
- No full desktop app
- No SwiftUI rewrite
- No plugin marketplace
- No remote workspace orchestration beyond what is needed for local TUI use
- No attempt to preserve every upstream implementation detail
Implementation Note
Treat the upstream repository as behavioral reference, not as a code dependency. The rewrite should preserve user-facing workflow, not source structure.