6 min readcode

Build Your AI Development Workspace with OpenCode and OpenSpec

Give an AI coding agent context, a clear change, and reusable ways to work

Build Your AI Development Workspace with OpenCode and OpenSpec

An AI coding agent can edit files and run tests within minutes. That speed is useful, but it also makes a familiar mistake faster: implementing a reasonable answer to a question nobody has properly defined. The agent may know the language and framework while knowing very little about your repository, the behavior you promised users, or the checks your team expects before a change is done.

My starting point is a small development workspace with five distinct parts: OpenCode to work in the repository, AGENTS.md to explain the repository, OpenSpec to make a change reviewable, and custom agents and skills for work that benefits from a repeatable role or procedure. You do not need to configure every part on day one. It helps to understand what question each one answers.

PieceQuestion it answersExample
OpenCodeWho can inspect and change this repository with me?Explore the API, edit code, run tests
AGENTS.mdWhat should any agent know about this project?Architecture, commands, conventions
OpenSpecWhat behavior are we agreeing to change?A named change with scenarios and tasks
Custom agentWho should take a specialized role?A reviewer with no edit permission
SkillHow do we repeat a particular procedure?A checklist for reviewing API compatibility

These are different layers, not competing ways to write a longer prompt. Let's assemble them around a small example: an existing task API needs an optional status filter on GET /tasks.

Start with repository context

Install OpenCode using one of the methods in its official setup guide. For a Node-based setup, the documented command is:

npm install -g opencode-ai
cd path/to/your-project
opencode

Connect a model provider using OpenCode's setup flow. Before asking it to implement the filter, let it inspect the project: “Where is GET /tasks implemented, and which tests define its current behavior?” A useful answer should point to actual files and acknowledge uncertainty. If it invents an endpoint, stop there; adding more roles will not repair missing context.

OpenCode can create a starter AGENTS.md with /init. Review what it writes. This file is durable project context, so it should contain facts and working rules that future sessions need, rather than a transcript of today's task. OpenCode's rules documentation recommends project-specific instructions such as build commands, architecture, and conventions. A compact example:

# Task API

- Routes live in `src/http`; persistence lives in `src/repositories`.
- Preserve the response shape of existing endpoints.
- Run `npm test` for behavior changes and `npm run build` before handoff.
- Do not modify database migrations that have already been applied.
- Record API contract changes in `openapi.yaml`.

The exact paths and commands must match your repository. If your actual check is ./gradlew test, write that instead. Treat this file like code: review it, keep it short, and update it when the project changes. It should help an agent avoid avoidable mistakes; it cannot guarantee correctness.

Give the change a contract with OpenSpec

The request “add a status filter” still leaves questions. Which statuses are valid? What happens when the parameter is omitted? Is an unknown status an empty result or a client error? Does filtering happen before pagination? Those decisions affect clients, so I want them visible before implementation.

OpenSpec can be installed and initialized from the terminal. Its installation guide documents the Node requirement and setup commands:

npm install -g @fission-ai/openspec@latest
openspec init --tools opencode

Run openspec init at the project root. The --tools opencode option selects the OpenCode integration without an interactive picker. OpenSpec will create its planning directory and the workflow files for that integration. Check the generated files rather than assuming that every tool exposes the same slash-command names; OpenSpec's tool reference describes those differences.

In OpenCode, the OpenSpec integration currently provides /opsx-propose for this step. Start a named change in the chat:

/opsx-propose add-task-status-filter

Give it the context the command needs:

Propose a change to add an optional status filter to GET /tasks.
Inspect the current endpoint and tests first. Define the behavior when the
parameter is absent, when it is valid, and when it is invalid. Do not
implement the change until we have reviewed the proposal and scenarios.

The generated command is part of the OpenSpec workflow installed for OpenCode; check the names printed by openspec init if your installation differs. In the default spec-driven structure, a proposal explains why, a spec describes observable behavior, a design captures technical decisions when needed, and tasks track implementation. A scenario might say:

### Requirement: Filter tasks by status
The API MUST allow clients to filter tasks by a supported status.

#### Scenario: No filter
- **WHEN** a client calls GET /tasks without a status parameter
- **THEN** the existing unfiltered behavior is preserved

#### Scenario: Unsupported status
- **WHEN** a client requests a status the API does not support
- **THEN** the API returns the documented validation error

That is only an example contract. Your API may deliberately handle invalid values differently. Decide it with the people who own the API, then write the chosen behavior down. For a deeper walkthrough of proposals, scenarios, and design trade-offs, see my OpenSpec article.

Add a specialist only when it has a clear job

Once the change is implemented, a second perspective can help. OpenCode supports custom primary agents and subagents. A custom agent has a role and its own permissions; it is not a second specification. For this example, a review subagent should read the diff and contract, question edge cases, and report findings without editing files.

Create .opencode/agents/api-reviewer.md:

---
description: Reviews API changes against their contract and existing clients
mode: subagent
permission:
  edit: deny
  bash: ask
---

Review the proposed API change and its tests. Compare the implementation
with the OpenSpec scenarios and the existing endpoint behavior. Look for
compatibility changes, pagination mistakes, invalid input handling, and
missing tests. Cite the files and lines behind each finding. Do not edit.

You can invoke that subagent by mentioning @api-reviewer in OpenCode. It cannot edit files, and it must ask before running a shell command such as git diff. Those permissions make its role explicit. They do not make its analysis infallible: the engineer still decides whether each finding is correct and whether the implementation satisfies the contract. OpenCode's permissions guide is worth reading before giving a specialist shell or editing access.

Do you need separate “backend”, “tester”, “architect”, and “reviewer” agents for this endpoint? Probably not. Start with the general agent and add a specialist when you can name a recurring job, its inputs, its output, and the permissions it needs. More agents can also create more handoffs and inconsistent assumptions.

Capture a procedure as a skill

A skill is different from an agent. It packages instructions for how to do a recurring task, and OpenCode loads it when relevant. For instance, the API reviewer's role is “review this change”; an api-compatibility skill could define the checks the reviewer should apply across many API changes.

Create .opencode/skills/api-compatibility/SKILL.md:

---
name: api-compatibility
description: Check an API change for client-visible compatibility risks
---

## Use this skill when

An endpoint, request, response, or documented error behavior changes.

## Procedure

1. Read the current API contract and at least one existing client call.
2. Compare old and new request and response shapes.
3. Check defaults, invalid input, pagination, and error status codes.
4. Identify changes that require clients to deploy at the same time.
5. Report each risk with evidence and a compatible migration option.

OpenCode's skill documentation describes this directory structure and the required name and description frontmatter. Keep the description specific: it helps the agent decide whether to load the skill. A skill should carry a procedure that survives one task. If it merely repeats today's prompt, it probably belongs in the conversation instead.

You can ask the reviewer to use api-compatibility, or let the agent discover it when the task matches its description. For a small project, you might not need this file yet. Write it when you notice yourself repeating the same review steps across changes.

Run one complete change

With those pieces in place, the loop is straightforward:

  1. Ask OpenCode to inspect the current endpoint and tests.
  2. Use OpenSpec to propose the filter and review its scenarios. Resolve ambiguous client behavior before coding.
  3. Use /opsx-apply to implement the approved change, then run the repository checks from AGENTS.md.
  4. Ask @api-reviewer to compare the result with the spec and apply the compatibility procedure.
  5. Read the diff, run the checks yourself or inspect their output, and correct any mismatch. Update the spec if a decision legitimately changed during implementation. Archive the change with /opsx-archive once its implementation is finished and accepted.

Notice what remains the developer's responsibility: choosing the behavior, assessing trade-offs, checking evidence, and deciding when the change is ready. The workspace helps the agent work with better context and leaves a clearer trail for a human reviewer. It does not turn a generated patch into a trustworthy one by itself.

There is also no prize for using every component in every repository. Start with OpenCode and accurate project instructions. Add OpenSpec when the risk is implementing the wrong behavior; add a custom agent when a specialized perspective repeatedly helps; add a skill when a procedure deserves to be reused. That progression keeps the setup understandable as the project grows.