OpenCode
OpenCode is a first-class Observal harness integration. Observal can install OpenCode agents, configure MCP servers, expose skills, install hook plugins, and collect OpenCode session telemetry.
Overview
OpenCode agent profiles are Markdown files. Project agents live in .opencode/agents/. User agents live in ~/.config/opencode/agents/.
OpenCode session telemetry uses an in-process TypeScript plugin. The plugin is installed by observal auth login or observal doctor patch. Agent pulls write agent profiles and update the Observal lockfile, but they do not embed the telemetry plugin in each agent file.
The plugin listens to OpenCode session and message events, reads message data through the OpenCode client API, converts new messages into Observal session lines, and sends them to Observal.
Supported capabilities
Agent profiles
Project and user scope
Hook bridge
OpenCode plugin
Plugin events
session.created, session.idle, message.updated
MCP servers
opencode.json and ~/.config/opencode/opencode.json
Agent prompt
Registry prompts are written into the generated OpenCode agent profile
Skills
.opencode/skills/{name}/SKILL.md and ~/.config/opencode/skills/{name}/SKILL.md
Session parsing
OpenCode plugin exports JSONL-compatible session lines
Telemetry
OpenCode session transcripts delivered through the plugin and reconciliation
Model selection
Registry-backed OpenCode model catalog
Setup
1. Install the Observal CLI
2. Authenticate
This writes credentials to ~/.observal/config.json. If OpenCode is detected, login can install the Observal plugin.
3. Pull an agent into OpenCode
OpenCode's default scope is user scope. By default, the agent is written to ~/.config/opencode/agents/{name}.md.
To install into the current project:
Project agents are written to .opencode/agents/{name}.md.
4. Install or refresh the OpenCode plugin
This installs or updates observal-plugin.ts when the plugin is missing, stale, or different from the bundled source.
Config paths
Agent profile
.opencode/agents/{name}.md
~/.config/opencode/agents/{name}.md
MCP config
opencode.json
~/.config/opencode/opencode.json
Skill definition
.opencode/skills/{name}/SKILL.md
~/.config/opencode/skills/{name}/SKILL.md
Plugin hooks
.opencode/plugins/{name}.ts
~/.config/opencode/plugins/{name}.ts
Observal plugin
.opencode/plugins/observal-plugin.ts
~/.config/opencode/plugins/observal-plugin.ts
Observal credentials
~/.observal/config.json
~/.observal/config.json
Observal lockfile
~/.observal/lockfile.json
~/.observal/lockfile.json
OpenCode MCP configs use the mcp key.
Plugin spec
Observal installs a TypeScript plugin named observal-plugin.ts. The plugin subscribes to OpenCode runtime events:
session.created
Capture the active OpenCode agent name for the session
message.updated
Mark the session as having new data to push
session.idle
Fetch new messages and send them to Observal
session.updated
Refresh active agent tracking when emitted by OpenCode
session.next.agent.switched
Refresh active agent tracking when the active agent changes
The bundled spec version is checked by doctor patch, along with the plugin content hash, so stale local copies are replaced.
Attribution
OpenCode exposes the active agent name in session events, not an Observal UUID. The Observal lockfile maps that OpenCode agent name back to the registry agent id and installed version.
observal agent pullwrites the OpenCode agent profile and records the agent name, id, version, scope, and project directory in~/.observal/lockfile.json.The OpenCode plugin receives
session.createdor agent switch events and reads the active OpenCode agent name.Built-in OpenCode agents such as
build,plan,general,explore,scout,compaction,title, andsummaryare ignored.The plugin selects the configured server URL under
registriesin~/.observal/lockfile.json, then searches that registry'sopencodeharness for an entry whosenameoridmatches the active agent.If multiple entries match, a project-scoped entry for the current directory wins, then a user-scoped entry, then the first match.
The session payload is sent with the resolved
agent_idandagent_version.If no lockfile match exists, the plugin skips attribution for that session instead of guessing.
Session push behavior
The OpenCode plugin implements the same acknowledged delivery contract as Python harnesses:
Load
~/.observal/config.jsonand resolve the active agent through~/.observal/lockfile.json.On
session.idle, recover missing, stale, or quarantined local state from the server's contiguous checkpoint.Retry any durable pending batch before reading new messages.
Fetch messages from
client.session.messagesand convert each message into one stable JSONL-compatible source record.Atomically persist the pending indexed batch under
~/.observal/opencode_session_outbox/before network delivery.Retry the same batch idempotently until the server returns a contiguous acknowledgement covering it.
Advance the persisted source line only after that acknowledgement; a crash after server commit safely retries the batch.
On finalization, compare a SHA-256 audit manifest and replay from the server-requested repair range when needed.
Acknowledged state is retained for seven days to avoid unnecessary replay. Capacity errors fail closed without discarding pending records. Corrupt state is quarantined and rebuilt from the authenticated server checkpoint plus the OpenCode message source.
Agent profile format
OpenCode agents are Markdown files. Observal writes the agent prompt into the profile selected by scope:
Caveats
The plugin is shared per OpenCode install. It is installed by auth login or doctor patch, not by each agent pull.
Attribution depends on the lockfile. If an agent profile is copied by hand without running observal agent pull, the plugin may see the OpenCode agent name but have no Observal id or version to send.
Built-in OpenCode agents are ignored. Sessions for built-in agents are not attributed to registry agents.
MCP config is OpenCode-specific. OpenCode uses opencode.json and the mcp key, not Kiro or Claude Code MCP paths.
Last updated
Was this helpful?