Compare commits

...
Author SHA1 Message Date
neriousy d08c92dbbb feat(schema): publish V2 config schema and accept V1 and V2 at /config.json
Generate the strict V2 opencode.json schema from Config.Info and serve it at /v2/config.json. Regenerate the root /config.json from the V2 schema merged with a frozen snapshot of the last V1 schema, so V1, V2, and mixed configs validate. A CI staleness check keeps it in sync.
2026-10-12 14:56:08 +00:00
30 changed files with 3776 additions and 648 deletions

No files matched your search

File diff suppressed because it is too large. Load diff
+13 -10
View File
@@ -22,11 +22,12 @@ legacy OpenCode, or migrating from V1.
Use only <https://opencode.ai/v2/docs/> documentation as the source of truth for V2.
Do not use <https://opencode.ai/docs/>, which documents V1, and do not use
general web search to resolve a V2 documentation question when the V2 docs or
linked pages cover it. The schema served from
<https://opencode.ai/config.json> may describe V1 even though V2 configuration
files include that URL for editor integration. Never use it to infer V2 field
names or shapes. If V2 documentation is missing or contradictory, state the
uncertainty or ask for clarification instead of falling back to V1.
linked pages cover it. The native V2 schema is
<https://opencode.ai/v2/config.json>. The schema at
<https://opencode.ai/config.json> also accepts V1 fields for compatibility, so
do not use it to infer V2 field names or shapes. If V2 documentation is missing
or contradictory, state the uncertainty or ask for clarification instead of
falling back to V1.
V1 documentation and syntax may be consulted only when the user explicitly
asks about V1 or when needed as migration input. Outputs and recommendations
@@ -74,7 +75,7 @@ autocomplete:
```jsonc
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
}
```
@@ -101,8 +102,9 @@ preferences, especially themes and keybindings.
Do not guess field names or shapes. Fetch the V2 configuration guide and its
linked topic guide as the source of truth, and preserve unrelated settings when
editing an existing file. Keep the published `$schema` URL in configuration
examples, but do not fetch it to determine the V2 configuration shape.
editing an existing file. Use the V2 `$schema` URL for native V2 examples;
leave `https://opencode.ai/config.json` in existing files that still use V1
syntax.
See the [full configuration guide](https://opencode.ai/v2/docs/config) for
every field, examples, config locations, and links to dedicated feature guides.
@@ -145,8 +147,9 @@ V1 config files and `.opencode/` definitions are intended to remain compatible.
The only intentional breaking changes are the server API and plugin API. Native
V2 config uses more ergonomic shapes, but conversion is optional. When the user
requests conversion, inspect the complete configuration, preserve behavior and
unrelated settings, and apply only the relevant migrations from the guide. For
plugin migrations, fetch and follow both the migration guide and the full
unrelated settings, and apply only the relevant migrations from the guide. Update
`$schema` to `https://opencode.ai/v2/config.json` when a file is fully converted.
For plugin migrations, fetch and follow both the migration guide and the full
[plugins guide](https://opencode.ai/v2/docs/build/plugins). If non-API V1
functionality fails in V2, use the `report` skill to file it as a compatibility
bug.
+139
View File
@@ -0,0 +1,139 @@
import { isDeepStrictEqual, parseArgs } from "node:util"
import { Schema } from "effect"
import { Config } from "../src/config.js"
// Generates the JSON schemas for `opencode.json`:
// - `--v2`: the strict schema generated from `Config.Info`, served at https://opencode.ai/v2/config.json.
// - `--compat`: the schema served at https://opencode.ai/config.json. Core still loads V1 configs and configs that
// mix V1 and V2 keys, so this schema accepts both. V1 keys come from `config-v1.json`, a frozen snapshot of the
// last V1 schema, and keys only V1 accepts are marked deprecated.
const args = parseArgs({
options: { v2: { type: "string" }, compat: { type: "string" }, check: { type: "boolean" } },
}).values
if (!args.v2 && !args.compat) throw new Error("Pass --v2 and/or --compat output paths")
type Json = { [key: string]: unknown }
interface ObjectSchema {
description?: string
properties?: Record<string, Json>
required?: string[]
additionalProperties?: boolean | Json
}
// Core merges V1 and V2 members inside these objects; every other value must be entirely V1 or entirely V2.
// See `packages/core/src/config/normalize.ts` and the "Migrate from V1" guide.
const mixedObjects = new Set(["mcp", "compaction", "experimental"])
const generated = Schema.toJsonSchemaDocument(Config.Info, { onExcessProperty: "error" })
const v1: { $defs: Record<string, Json> } = await Bun.file(new URL("./config-v1.json", import.meta.url)).json()
const v2 = {
$schema: "https://json-schema.org/draft/2020-12/schema",
$id: "https://opencode.ai/v2/config.json",
...generated.schema,
$defs: generated.definitions,
allowComments: true,
allowTrailingCommas: true,
}
const compat = {
$schema: "https://json-schema.org/draft/2020-12/schema",
$id: "https://opencode.ai/config.json",
...mergeObjects(
generated.definitions[definitionName(String(generated.schema.$ref))] as ObjectSchema,
prefixV1Refs(v1.$defs.Config) as ObjectSchema,
(key) => mixedObjects.has(key),
),
$defs: {
...generated.definitions,
...Object.fromEntries(
Object.entries(v1.$defs)
.filter(([name]) => name !== "Config")
.map(([name, schema]) => [v1Definition(name), prefixV1Refs(schema)]),
),
},
allowComments: true,
allowTrailingCommas: true,
}
const outputs = [
...(args.v2 ? [{ path: args.v2, document: v2 }] : []),
...(args.compat ? [{ path: args.compat, document: compat }] : []),
].map((output) => ({ path: output.path, content: `${JSON.stringify(output.document, null, 2)}\n` }))
if (args.check) {
const stale = await Promise.all(
outputs.map(async (output) => (await Bun.file(output.path).text()) !== output.content),
)
if (stale.some(Boolean)) {
console.error("Generated config schemas are stale. Run `bun run generate` from services/www.")
process.exit(1)
}
process.exit(0)
}
await Promise.all(outputs.map((output) => Bun.write(output.path, output.content)))
// Merges a V2 object schema with its V1 counterpart. A member declared by only one version is checked against the
// other version's `additionalProperties` schema as well, so V1 records such as `mcp` still accept their entries.
// Members only V1 accepts are marked deprecated; members whose shapes differ accept either shape.
function mergeObjects(current: ObjectSchema, legacy: ObjectSchema, mixed: (key: string) => boolean): ObjectSchema {
const currentExtra = extraProperties(current)
const legacyExtra = extraProperties(legacy)
const keys = new Set([...Object.keys(current.properties ?? {}), ...Object.keys(legacy.properties ?? {})])
const required = (current.required ?? []).filter((key) => legacy.required?.includes(key))
return {
...(legacy.description ? { description: legacy.description } : {}),
type: "object",
properties: Object.fromEntries(
[...keys].map((key) => {
const next = current.properties?.[key] ?? currentExtra
const prev = legacy.properties?.[key] ?? legacyExtra
if (!next) return [key, { ...prev, deprecated: true }]
if (!prev) return [key, next]
// Prefer the V1 copy of an identical shape because it carries descriptions.
if (isDeepStrictEqual(withoutDescriptions(prev), withoutDescriptions(next))) return [key, prev]
if (mixed(key)) return [key, mergeObjects(next, prev, () => false)]
return [key, { anyOf: [next, prev] }]
}),
),
...(required.length ? { required } : {}),
additionalProperties:
currentExtra && legacyExtra ? { anyOf: [currentExtra, legacyExtra] } : (currentExtra ?? legacyExtra ?? false),
} as ObjectSchema
}
function extraProperties(schema: ObjectSchema) {
return typeof schema.additionalProperties === "object" ? schema.additionalProperties : undefined
}
function definitionName(ref: string) {
return ref.slice("#/$defs/".length)
}
// V1 definitions are namespaced so they cannot collide with V2 definitions.
function v1Definition(name: string) {
return `V1.${name}`
}
function prefixV1Refs(value: unknown): unknown {
if (Array.isArray(value)) return value.map(prefixV1Refs)
if (!value || typeof value !== "object") return value
return Object.fromEntries(
Object.entries(value).map(([key, item]) =>
key === "$ref" && typeof item === "string" && item.startsWith("#/$defs/")
? [key, `#/$defs/${v1Definition(definitionName(item))}`]
: [key, prefixV1Refs(item)],
),
)
}
function withoutDescriptions(value: unknown): unknown {
if (Array.isArray(value)) return value.map(withoutDescriptions)
if (!value || typeof value !== "object") return value
return Object.fromEntries(
Object.entries(value)
.filter(([key]) => key !== "description")
.map(([key, item]) => [key, withoutDescriptions(item)]),
)
}
File diff suppressed because it is too large. Load diff
+1
View File
@@ -3,3 +3,4 @@
dist/
node_modules/
public/cli.json
public/config.json
+1
View File
@@ -6,6 +6,7 @@ The standard Astro website for OpenCode. The only deployment-specific path is th
- `src/docs/` is the self-contained documentation feature rendered under `/docs`.
- `/install` proxies the current installer.
- `/openapi.json` serves the generated OpenAPI specification.
- `/config.json` serves the strict V2 `opencode.json` schema. `bun run generate` also regenerates the V1-compatible schema that the console app serves at the root `https://opencode.ai/config.json`.
The deployment currently sets `base: "/v2"`. The `v2.opencode.ai` alias is handled by a Cloudflare Redirect Rule outside this project.
+2 -2
View File
@@ -7,8 +7,8 @@
"dev": "bun run generate && astro dev --host --port 3000",
"build": "bun run generate && astro build && bun script/pagefind.ts && bun run validate && bun script/prepare-cloudflare.ts",
"deploy": "wrangler deploy --config dist/server/wrangler.json",
"generate": "bun script/generate-openapi.ts && bun --cwd ../../packages/cli script/schema.ts ../../services/www/public/cli.json",
"check:generated": "bun script/generate-openapi.ts --check",
"generate": "bun script/generate-openapi.ts && bun --cwd ../../packages/cli script/schema.ts ../../services/www/public/cli.json && bun --cwd ../../packages/schema script/config-schema.ts --v2 ../../services/www/public/config.json --compat ../../packages/console/app/public/config.json",
"check:generated": "bun script/generate-openapi.ts --check && bun --cwd ../../packages/schema script/config-schema.ts --compat ../../packages/console/app/public/config.json --check",
"validate": "bun script/validate-links.ts",
"typecheck": "astro check"
},
+2 -2
View File
@@ -65,7 +65,7 @@ Define agents under `agents` in any [OpenCode configuration file](/config):
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"agents": {
"reviewer": {
"description": "Reviews current changes",
@@ -85,7 +85,7 @@ Set the primary agent used when a session has not selected one:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"default_agent": "writer",
"agents": {
"writer": { "mode": "primary" },
@@ -79,7 +79,7 @@ Configure image normalization in `opencode.json` or `opencode.jsonc`:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"media": {
"image": {
"auto_resize": true,
@@ -34,7 +34,7 @@ plugins.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"plugins": [
"opencode-acme-effect-plugin",
"opencode-acme-effect-plugin@1.2.0",
@@ -23,7 +23,7 @@ or plugin directories from other locations, add them to `plugins` in `opencode.j
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"plugins": [
"opencode-acme-plugin",
"opencode-acme-plugin@1.2.0",
+1 -1
View File
@@ -53,7 +53,7 @@ Define commands under `commands` in any OpenCode JSON or JSONC [configuration fi
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"commands": {
"review": {
"description": "Review code for correctness",
+3 -3
View File
@@ -26,7 +26,7 @@ Automatic compaction is on by default:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"compaction": {
"auto": true,
"keep": { "tokens": 15000 },
@@ -69,7 +69,7 @@ Add `compaction` to any [OpenCode configuration file](/config):
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"compaction": {
"auto": false,
"keep": { "tokens": 24000 },
@@ -94,7 +94,7 @@ provider or model with `settings.compaction`:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"openai": {
"settings": { "compaction": { "type": "native" } },
+8 -4
View File
@@ -6,7 +6,7 @@ Create `opencode.jsonc` in your project to configure OpenCode. Add the schema fo
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"model": "anthropic/claude-sonnet-4-5",
}
```
@@ -19,7 +19,7 @@ OpenCode supports JSON and JSONC. Use JSONC when you want comments or trailing c
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
// Use this model by default.
"model": "anthropic/claude-sonnet-4-5",
}
@@ -71,20 +71,24 @@ which overrides the global config. Settings that do not conflict are preserved.
## Schema
The complete OpenCode configuration schema is available at
[opencode.ai/config.json](https://opencode.ai/config.json).
[opencode.ai/v2/config.json](https://opencode.ai/v2/config.json).
Add the `$schema` field to your configuration file to enable validation and
autocomplete in editors that support JSON Schema:
```json title="opencode.json"
{
"$schema": "https://opencode.ai/config.json"
"$schema": "https://opencode.ai/v2/config.json"
}
```
Use the schema as the source of truth for available fields, accepted values,
and nested configuration shapes.
Files that still use V1 syntax can keep `https://opencode.ai/config.json`. That
schema accepts V1, native V2, and mixed configuration files, and marks V1-only
fields as deprecated.
### Shell
Set the shell used by the terminal and shell tools.
+1 -1
View File
@@ -418,7 +418,7 @@ the [model](/models) using the format `opencode-go/<model-id>`:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"model": "opencode-go/kimi-k3",
}
```
@@ -130,7 +130,7 @@ use the format `opencode/<model-id>`:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"model": "opencode/gpt-5.5",
}
```
+5 -5
View File
@@ -7,7 +7,7 @@ them. Formatters are disabled by default, so enable them in your configuration:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"formatter": true,
}
```
@@ -20,7 +20,7 @@ available.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"formatter": true,
}
```
@@ -31,7 +31,7 @@ resets them to the built-ins.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"formatter": {},
}
```
@@ -86,7 +86,7 @@ formatter needs both `command` and `extensions` to run.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"formatter": {
"prettier": {
"environment": {
@@ -183,7 +183,7 @@ formatting that a lower-priority file enabled, set it to `false`.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"formatter": false,
}
```
@@ -104,7 +104,7 @@ The V2 config schema accepts an `instructions` array, but V2 does not currently
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"instructions": ["CONTRIBUTING.md", "docs/guidelines/*.md", "https://example.com/instructions.md"],
}
```
@@ -31,7 +31,7 @@ To configure a server by hand, give it a unique name under `mcp.servers`. V2 doe
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"mcp": {
"servers": {
"my-server": {
@@ -86,7 +86,7 @@ Use configuration for process options such as a working directory or environment
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"mcp": {
"servers": {
"everything": {
@@ -136,7 +136,7 @@ Use configuration when the server needs headers or other options. Store secrets
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"mcp": {
"servers": {
"context7": {
@@ -182,7 +182,7 @@ For dynamic registration, configure only the server URL:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"mcp": {
"servers": {
"sentry": {
@@ -204,7 +204,7 @@ When a provider gives you client credentials, use V2's snake_case OAuth fields:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"mcp": {
"servers": {
"company-tools": {
@@ -244,7 +244,7 @@ Timeouts are positive integer milliseconds. Set defaults under `mcp.timeout`; a
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"mcp": {
"timeout": {
"startup": 45000,
@@ -276,7 +276,7 @@ OpenCode opens every server with the classic MCP `initialize` handshake by defau
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"mcp": {
"servers": {
"modern": {
+12 -1
View File
@@ -69,13 +69,24 @@ The recommended migration path is to ask OpenCode to update the configuration fo
```text
Migrate my OpenCode configuration, including file-based definitions, from the V1 format to the native V2 format.
Preserve its behavior and all unrelated settings.
Preserve its behavior and all unrelated settings. When a config file is fully converted, update its $schema to
https://opencode.ai/v2/config.json.
```
OpenCode can inspect the complete file, apply the relevant changes below, and avoid rewriting settings that do not need to
change. Conversion does not need to happen all at once: supported V1 and native V2 fields may coexist at the top level.
When both forms set the same canonical value, a valid native V2 value takes precedence regardless of JSON key order.
The schema at `https://opencode.ai/config.json` accepts V1, native V2, and mixed files, and marks V1-only fields as
deprecated. Once a file is fully converted, switch to the strict native V2 schema:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/v2/config.json",
"permissions": [{ "action": "shell", "resource": "git push *", "effect": "ask" }],
}
```
Nested mixing is intentionally bounded. OpenCode recognizes mixed V1 and V2 members within `mcp`, `compaction`, and
`experimental`, but it does not recursively infer formats inside individual agents, providers, commands, or models. Keep
each of those nested entries entirely in one format. Supported V1 syntax remains quiet by itself; malformed values,
+7 -7
View File
@@ -43,7 +43,7 @@ Set `model` in `opencode.json` or `opencode.jsonc` to choose the default for new
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"model": "anthropic/claude-sonnet-4-5",
}
```
@@ -73,7 +73,7 @@ Define new variants, or replace catalog variants with the same ID, in the model'
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"openai": {
"models": {
@@ -153,7 +153,7 @@ Use `modelID` to give an API model a friendlier catalog ID:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"model": "openai/coding-default",
"providers": {
"openai": {
@@ -243,7 +243,7 @@ With Ollama listening at `http://127.0.0.1:11434`, select a discovered model wit
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"model": "ollama/gemma3:4b",
}
```
@@ -277,7 +277,7 @@ provider ID:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"model": "lmstudio/google/gemma-4-26b-a4b",
}
```
@@ -309,7 +309,7 @@ With vLLM listening at `http://127.0.0.1:8000`, select a discovered model with t
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"model": "vllm/Qwen/Qwen3-Coder-30B-A3B-Instruct",
}
```
@@ -346,7 +346,7 @@ For another OpenAI-compatible server, define its provider package, endpoint, and
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"model": "local/coder",
"providers": {
"local": {
@@ -11,7 +11,7 @@ inspection, and always block pushes. Add these ordered rules to `opencode.jsonc`
```jsonc
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"permissions": [
{ "action": "shell", "resource": "*", "effect": "ask" },
{ "action": "shell", "resource": "git status *", "effect": "allow" },
@@ -142,7 +142,7 @@ A path outside both the active Location and its non-root project worktree needs
```jsonc
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"permissions": [
{ "action": "external_directory", "resource": "~/projects/reference/*", "effect": "allow" },
{ "action": "read", "resource": "~/projects/reference/*", "effect": "allow" },
@@ -179,7 +179,7 @@ Enable the experimental portable shell scanner with:
```jsonc
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"experimental": {
"portable_shell_scanner": true,
},
@@ -232,7 +232,7 @@ Put shared rules at the top level and narrower rules under
```jsonc
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"permissions": [
{ "action": "shell", "resource": "*", "effect": "ask" },
{ "action": "shell", "resource": "git status *", "effect": "allow" },
+1 -1
View File
@@ -8,7 +8,7 @@ Add published packages, versioned packages, scoped packages, or local plugin dir
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"plugins": [
"opencode-acme-plugin",
"opencode-acme-plugin@1.2.0",
+1 -1
View File
@@ -17,7 +17,7 @@ Deny one provider everywhere by adding a statement to `opencode.jsonc`:
```jsonc
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"experimental": {
"policies": [{ "action": "provider.use", "resource": "openai", "effect": "deny" }],
},
+19 -19
View File
@@ -34,7 +34,7 @@ runtime package, endpoint, and first model together.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"acme": {
"name": "Acme",
@@ -73,7 +73,7 @@ models, and connection still apply.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"anthropic": {
"settings": {
@@ -92,7 +92,7 @@ Use `headers` for additional HTTP headers and `body` for JSON fields that should
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"openai": {
"headers": {
@@ -112,7 +112,7 @@ Both fields can also be set on a model or variant when only part of a provider's
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"openai": {
"models": {
@@ -141,7 +141,7 @@ WebSocket transport, `chunkTimeout` bounds the gap between frames instead and de
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"anthropic": {
"settings": {
@@ -163,7 +163,7 @@ implement the OpenAI request format.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"acme": {
"package": "@opencode/ai/providers/openai-compatible",
@@ -207,7 +207,7 @@ You can also use an npm package such as `@acme/opencode-provider` or an absolute
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"acme": {
"package": "@acme/opencode-provider",
@@ -224,7 +224,7 @@ ID sent to the provider.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"model": "openai/coding",
"providers": {
"openai": {
@@ -265,7 +265,7 @@ once, then connect an API key or use the Microsoft Entra ID session from the Azu
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"azure": {
"settings": {
@@ -336,7 +336,7 @@ kept.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"azure": {
"models": {
@@ -375,7 +375,7 @@ identity token file, or container credential URI activates the provider; a regio
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"amazon-bedrock": {
"settings": {
@@ -392,7 +392,7 @@ VPC endpoint, set `baseURL` while keeping the same profile and region.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"amazon-bedrock": {
"settings": {
@@ -419,7 +419,7 @@ gcloud auth application-default login
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"google-vertex": {
"settings": {
@@ -489,7 +489,7 @@ model requests.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"ollama": {
"settings": {
@@ -511,7 +511,7 @@ LM Studio and vLLM also have built-in local discovery. Their default endpoints a
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"lmstudio": {
"settings": { "baseURL": "http://gpu-host:1234/v1" },
@@ -534,7 +534,7 @@ OpenRouter account, then refer to models with the full OpenRouter model ID after
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"model": "openrouter/anthropic/claude-sonnet-4",
}
```
@@ -544,7 +544,7 @@ This preserves OpenRouter request and reasoning behavior.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"openrouter": {
"settings": {
@@ -563,7 +563,7 @@ The configuration key becomes the provider prefix and each `models` key becomes
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"model": "company/coder",
"providers": {
"company": {
@@ -607,7 +607,7 @@ sessions.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"providers": {
"openai": {
"settings": { "transport": "http" },
+1 -1
View File
@@ -8,7 +8,7 @@ your client when you need it.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"references": {
"docs": {
"path": "../product-docs",
+1 -1
View File
@@ -67,7 +67,7 @@ Add more local directories or HTTP catalogs with the `skills` array in any `open
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"skills": [
"./team-skills",
"~/shared/opencode-skills",
+1 -1
View File
@@ -103,7 +103,7 @@ filesystem capture.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"snapshots": false,
}
```
+2 -2
View File
@@ -10,7 +10,7 @@ Enable warming in any [OpenCode configuration file](/config):
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"warming": true,
}
```
@@ -26,7 +26,7 @@ window:
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"warming": {
"prompt": "Do not perform any work. Reply with exactly: OK",
"interval": "5 minutes",
+4 -4
View File
@@ -34,7 +34,7 @@ Set a provider in `opencode.jsonc` to skip the selection prompt.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"websearch": {
"provider": "tavily",
},
@@ -45,7 +45,7 @@ Use `"random"` to choose an available provider automatically. Each session keeps
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"websearch": {
"provider": "random",
},
@@ -70,7 +70,7 @@ Web searches use the `websearch` permission action and the search query as the r
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"permissions": [
{
"action": "websearch",
@@ -89,7 +89,7 @@ Set `websearch` to `false` to remove the web search tool from model requests.
```jsonc title="opencode.jsonc"
{
"$schema": "https://opencode.ai/config.json",
"$schema": "https://opencode.ai/v2/config.json",
"websearch": false,
}
```