summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGal Schlezinger <[email protected]>2025-07-08 23:29:07 +0300
committerGitHub <[email protected]>2025-07-08 15:29:07 -0500
commit14d81e574b4c4f308c477feca695337447e8cac1 (patch)
treec0c2a0c6fb4055b12b45b27d2a008701c3296c91
parent6efe8cc8dfa1ca0bfee0f18bc491fb8029709c3b (diff)
downloadopencode-14d81e574b4c4f308c477feca695337447e8cac1.tar.gz
opencode-14d81e574b4c4f308c477feca695337447e8cac1.zip
[config json schema] declare default values and examples for in-ide documentation (#754)
-rw-r--r--packages/opencode/config.schema.json267
-rwxr-xr-xpackages/opencode/script/schema.ts27
-rw-r--r--packages/opencode/src/config/config.ts70
3 files changed, 285 insertions, 79 deletions
diff --git a/packages/opencode/config.schema.json b/packages/opencode/config.schema.json
index 35dfd6f1e..b9d4a5ac9 100644
--- a/packages/opencode/config.schema.json
+++ b/packages/opencode/config.schema.json
@@ -14,111 +14,267 @@
"properties": {
"leader": {
"type": "string",
- "description": "Leader key for keybind combinations"
+ "default": "ctrl+x",
+ "description": "Leader key for keybind combinations\n\ndefault: `ctrl+x`",
+ "examples": [
+ "ctrl+x"
+ ]
},
- "help": {
+ "app_help": {
"type": "string",
- "description": "Show help dialog"
+ "default": "<leader>h",
+ "description": "Show help dialog\n\ndefault: `<leader>h`",
+ "examples": [
+ "<leader>h"
+ ]
},
"editor_open": {
"type": "string",
- "description": "Open external editor"
+ "default": "<leader>e",
+ "description": "Open external editor\n\ndefault: `<leader>e`",
+ "examples": [
+ "<leader>e"
+ ]
},
"session_new": {
"type": "string",
- "description": "Create a new session"
+ "default": "<leader>n",
+ "description": "Create a new session\n\ndefault: `<leader>n`",
+ "examples": [
+ "<leader>n"
+ ]
},
"session_list": {
"type": "string",
- "description": "List all sessions"
+ "default": "<leader>l",
+ "description": "List all sessions\n\ndefault: `<leader>l`",
+ "examples": [
+ "<leader>l"
+ ]
},
"session_share": {
"type": "string",
- "description": "Share current session"
+ "default": "<leader>s",
+ "description": "Share current session\n\ndefault: `<leader>s`",
+ "examples": [
+ "<leader>s"
+ ]
+ },
+ "session_unshare": {
+ "type": "string",
+ "default": "<leader>u",
+ "description": "Unshare current session\n\ndefault: `<leader>u`",
+ "examples": [
+ "<leader>u"
+ ]
},
"session_interrupt": {
"type": "string",
- "description": "Interrupt current session"
+ "default": "esc",
+ "description": "Interrupt current session\n\ndefault: `esc`",
+ "examples": [
+ "esc"
+ ]
},
"session_compact": {
"type": "string",
- "description": "Toggle compact mode for session"
+ "default": "<leader>c",
+ "description": "Compact the session\n\ndefault: `<leader>c`",
+ "examples": [
+ "<leader>c"
+ ]
},
"tool_details": {
"type": "string",
- "description": "Show tool details"
+ "default": "<leader>d",
+ "description": "Toggle tool details\n\ndefault: `<leader>d`",
+ "examples": [
+ "<leader>d"
+ ]
},
"model_list": {
"type": "string",
- "description": "List available models"
+ "default": "<leader>m",
+ "description": "List available models\n\ndefault: `<leader>m`",
+ "examples": [
+ "<leader>m"
+ ]
},
"theme_list": {
"type": "string",
- "description": "List available themes"
+ "default": "<leader>t",
+ "description": "List available themes\n\ndefault: `<leader>t`",
+ "examples": [
+ "<leader>t"
+ ]
+ },
+ "file_list": {
+ "type": "string",
+ "default": "<leader>f",
+ "description": "List files\n\ndefault: `<leader>f`",
+ "examples": [
+ "<leader>f"
+ ]
+ },
+ "file_close": {
+ "type": "string",
+ "default": "esc",
+ "description": "Close file\n\ndefault: `esc`",
+ "examples": [
+ "esc"
+ ]
+ },
+ "file_search": {
+ "type": "string",
+ "default": "<leader>/",
+ "description": "Search file\n\ndefault: `<leader>/`",
+ "examples": [
+ "<leader>/"
+ ]
+ },
+ "file_diff_toggle": {
+ "type": "string",
+ "default": "<leader>v",
+ "description": "Split/unified diff\n\ndefault: `<leader>v`",
+ "examples": [
+ "<leader>v"
+ ]
},
"project_init": {
"type": "string",
- "description": "Initialize project configuration"
+ "default": "<leader>i",
+ "description": "Create/update AGENTS.md\n\ndefault: `<leader>i`",
+ "examples": [
+ "<leader>i"
+ ]
},
"input_clear": {
"type": "string",
- "description": "Clear input field"
+ "default": "ctrl+c",
+ "description": "Clear input field\n\ndefault: `ctrl+c`",
+ "examples": [
+ "ctrl+c"
+ ]
},
"input_paste": {
"type": "string",
- "description": "Paste from clipboard"
+ "default": "ctrl+v",
+ "description": "Paste from clipboard\n\ndefault: `ctrl+v`",
+ "examples": [
+ "ctrl+v"
+ ]
},
"input_submit": {
"type": "string",
- "description": "Submit input"
+ "default": "enter",
+ "description": "Submit input\n\ndefault: `enter`",
+ "examples": [
+ "enter"
+ ]
},
"input_newline": {
"type": "string",
- "description": "Insert newline in input"
- },
- "history_previous": {
- "type": "string",
- "description": "Navigate to previous history item"
- },
- "history_next": {
- "type": "string",
- "description": "Navigate to next history item"
+ "default": "shift+enter,ctrl+j",
+ "description": "Insert newline in input\n\ndefault: `shift+enter,ctrl+j`",
+ "examples": [
+ "shift+enter,ctrl+j"
+ ]
},
"messages_page_up": {
"type": "string",
- "description": "Scroll messages up by one page"
+ "default": "pgup",
+ "description": "Scroll messages up by one page\n\ndefault: `pgup`",
+ "examples": [
+ "pgup"
+ ]
},
"messages_page_down": {
"type": "string",
- "description": "Scroll messages down by one page"
+ "default": "pgdown",
+ "description": "Scroll messages down by one page\n\ndefault: `pgdown`",
+ "examples": [
+ "pgdown"
+ ]
},
"messages_half_page_up": {
"type": "string",
- "description": "Scroll messages up by half page"
+ "default": "ctrl+alt+u",
+ "description": "Scroll messages up by half page\n\ndefault: `ctrl+alt+u`",
+ "examples": [
+ "ctrl+alt+u"
+ ]
},
"messages_half_page_down": {
"type": "string",
- "description": "Scroll messages down by half page"
+ "default": "ctrl+alt+d",
+ "description": "Scroll messages down by half page\n\ndefault: `ctrl+alt+d`",
+ "examples": [
+ "ctrl+alt+d"
+ ]
},
"messages_previous": {
"type": "string",
- "description": "Navigate to previous message"
+ "default": "ctrl+up",
+ "description": "Navigate to previous message\n\ndefault: `ctrl+up`",
+ "examples": [
+ "ctrl+up"
+ ]
},
"messages_next": {
"type": "string",
- "description": "Navigate to next message"
+ "default": "ctrl+down",
+ "description": "Navigate to next message\n\ndefault: `ctrl+down`",
+ "examples": [
+ "ctrl+down"
+ ]
},
"messages_first": {
"type": "string",
- "description": "Navigate to first message"
+ "default": "ctrl+g",
+ "description": "Navigate to first message\n\ndefault: `ctrl+g`",
+ "examples": [
+ "ctrl+g"
+ ]
},
"messages_last": {
"type": "string",
- "description": "Navigate to last message"
+ "default": "ctrl+alt+g",
+ "description": "Navigate to last message\n\ndefault: `ctrl+alt+g`",
+ "examples": [
+ "ctrl+alt+g"
+ ]
+ },
+ "messages_layout_toggle": {
+ "type": "string",
+ "default": "<leader>p",
+ "description": "Toggle layout\n\ndefault: `<leader>p`",
+ "examples": [
+ "<leader>p"
+ ]
+ },
+ "messages_copy": {
+ "type": "string",
+ "default": "<leader>y",
+ "description": "Copy message\n\ndefault: `<leader>y`",
+ "examples": [
+ "<leader>y"
+ ]
+ },
+ "messages_revert": {
+ "type": "string",
+ "default": "<leader>r",
+ "description": "Revert message\n\ndefault: `<leader>r`",
+ "examples": [
+ "<leader>r"
+ ]
},
"app_exit": {
"type": "string",
- "description": "Exit the application"
+ "default": "ctrl+c,<leader>q",
+ "description": "Exit the application\n\ndefault: `ctrl+c,<leader>q`",
+ "examples": [
+ "ctrl+c,<leader>q"
+ ]
}
},
"additionalProperties": false,
@@ -171,9 +327,15 @@
"additionalProperties": {
"type": "object",
"properties": {
+ "id": {
+ "type": "string"
+ },
"name": {
"type": "string"
},
+ "release_date": {
+ "type": "string"
+ },
"attachment": {
"type": "boolean"
},
@@ -202,7 +364,10 @@
"type": "number"
}
},
- "required": ["input", "output"],
+ "required": [
+ "input",
+ "output"
+ ],
"additionalProperties": false
},
"limit": {
@@ -215,12 +380,12 @@
"type": "number"
}
},
- "required": ["context", "output"],
+ "required": [
+ "context",
+ "output"
+ ],
"additionalProperties": false
},
- "id": {
- "type": "string"
- },
"options": {
"type": "object",
"additionalProperties": {}
@@ -234,7 +399,9 @@
"additionalProperties": {}
}
},
- "required": ["models"],
+ "required": [
+ "models"
+ ],
"additionalProperties": false
},
"description": "Custom provider configurations and model overrides"
@@ -270,7 +437,10 @@
"description": "Enable or disable the MCP server on startup"
}
},
- "required": ["type", "command"],
+ "required": [
+ "type",
+ "command"
+ ],
"additionalProperties": false
},
{
@@ -290,7 +460,10 @@
"description": "Enable or disable the MCP server on startup"
}
},
- "required": ["type", "url"],
+ "required": [
+ "type",
+ "url"
+ ],
"additionalProperties": false
}
]
@@ -330,7 +503,9 @@
}
}
},
- "required": ["command"],
+ "required": [
+ "command"
+ ],
"additionalProperties": false
}
}
@@ -353,7 +528,9 @@
}
}
},
- "required": ["command"],
+ "required": [
+ "command"
+ ],
"additionalProperties": false
}
}
@@ -366,4 +543,4 @@
},
"additionalProperties": false,
"$schema": "http://json-schema.org/draft-07/schema#"
-}
+} \ No newline at end of file
diff --git a/packages/opencode/script/schema.ts b/packages/opencode/script/schema.ts
index 1c0067c71..4aa1d9823 100755
--- a/packages/opencode/script/schema.ts
+++ b/packages/opencode/script/schema.ts
@@ -4,5 +4,30 @@ import "zod-openapi/extend"
import { Config } from "../src/config/config"
import { zodToJsonSchema } from "zod-to-json-schema"
-const result = zodToJsonSchema(Config.Info)
+const result = zodToJsonSchema(Config.Info, {
+ /**
+ * We'll use the `default` values of the field as the only value in `examples`.
+ * This will ensure no docs are needed to be read, as the configuration is
+ * self-documenting.
+ *
+ * See https://json-schema.org/draft/2020-12/draft-bhutton-json-schema-validation-00#rfc.section.9.5
+ */
+ postProcess(jsonSchema) {
+ const schema = jsonSchema as typeof jsonSchema & {
+ examples?: unknown[]
+ }
+ if (schema && typeof schema === "object" && "type" in schema && schema.type === "string" && schema?.default) {
+ if (!schema.examples) {
+ schema.examples = [schema.default]
+ }
+
+ schema.description = [schema.description || "", `default: \`${schema.default}\``]
+ .filter(Boolean)
+ .join("\n\n")
+ .trim()
+ }
+
+ return jsonSchema
+ },
+})
await Bun.write("config.schema.json", JSON.stringify(result, null, 2))
diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts
index c43a382a3..712ca3ff0 100644
--- a/packages/opencode/src/config/config.ts
+++ b/packages/opencode/src/config/config.ts
@@ -57,39 +57,43 @@ export namespace Config {
export const Keybinds = z
.object({
- leader: z.string().optional().describe("Leader key for keybind combinations"),
- app_help: z.string().optional().describe("Show help dialog"),
- editor_open: z.string().optional().describe("Open external editor"),
- session_new: z.string().optional().describe("Create a new session"),
- session_list: z.string().optional().describe("List all sessions"),
- session_share: z.string().optional().describe("Share current session"),
- session_unshare: z.string().optional().describe("Unshare current session"),
- session_interrupt: z.string().optional().describe("Interrupt current session"),
- session_compact: z.string().optional().describe("Toggle compact mode for session"),
- tool_details: z.string().optional().describe("Show tool details"),
- model_list: z.string().optional().describe("List available models"),
- theme_list: z.string().optional().describe("List available themes"),
- file_list: z.string().optional().describe("List files"),
- file_close: z.string().optional().describe("Close file"),
- file_search: z.string().optional().describe("Search file"),
- file_diff_toggle: z.string().optional().describe("Toggle split/unified diff"),
- project_init: z.string().optional().describe("Initialize project configuration"),
- input_clear: z.string().optional().describe("Clear input field"),
- input_paste: z.string().optional().describe("Paste from clipboard"),
- input_submit: z.string().optional().describe("Submit input"),
- input_newline: z.string().optional().describe("Insert newline in input"),
- messages_page_up: z.string().optional().describe("Scroll messages up by one page"),
- messages_page_down: z.string().optional().describe("Scroll messages down by one page"),
- messages_half_page_up: z.string().optional().describe("Scroll messages up by half page"),
- messages_half_page_down: z.string().optional().describe("Scroll messages down by half page"),
- messages_previous: z.string().optional().describe("Navigate to previous message"),
- messages_next: z.string().optional().describe("Navigate to next message"),
- messages_first: z.string().optional().describe("Navigate to first message"),
- messages_last: z.string().optional().describe("Navigate to last message"),
- messages_layout_toggle: z.string().optional().describe("Toggle layout"),
- messages_copy: z.string().optional().describe("Copy message"),
- messages_revert: z.string().optional().describe("Revert message"),
- app_exit: z.string().optional().describe("Exit the application"),
+ leader: z.string().optional().default("ctrl+x").describe("Leader key for keybind combinations"),
+ app_help: z.string().optional().default("<leader>h").describe("Show help dialog"),
+ editor_open: z.string().optional().default("<leader>e").describe("Open external editor"),
+ session_new: z.string().optional().default("<leader>n").describe("Create a new session"),
+ session_list: z.string().optional().default("<leader>l").describe("List all sessions"),
+ session_share: z.string().optional().default("<leader>s").describe("Share current session"),
+ session_unshare: z.string().optional().default("<leader>u").describe("Unshare current session"),
+ session_interrupt: z.string().optional().default("esc").describe("Interrupt current session"),
+ session_compact: z.string().optional().default("<leader>c").describe("Compact the session"),
+ tool_details: z.string().optional().default("<leader>d").describe("Toggle tool details"),
+ model_list: z.string().optional().default("<leader>m").describe("List available models"),
+ theme_list: z.string().optional().default("<leader>t").describe("List available themes"),
+ file_list: z.string().optional().default("<leader>f").describe("List files"),
+ file_close: z.string().optional().default("esc").describe("Close file"),
+ file_search: z.string().optional().default("<leader>/").describe("Search file"),
+ file_diff_toggle: z.string().optional().default("<leader>v").describe("Split/unified diff"),
+ project_init: z.string().optional().default("<leader>i").describe("Create/update AGENTS.md"),
+ input_clear: z.string().optional().default("ctrl+c").describe("Clear input field"),
+ input_paste: z.string().optional().default("ctrl+v").describe("Paste from clipboard"),
+ input_submit: z.string().optional().default("enter").describe("Submit input"),
+ input_newline: z.string().optional().default("shift+enter,ctrl+j").describe("Insert newline in input"),
+ messages_page_up: z.string().optional().default("pgup").describe("Scroll messages up by one page"),
+ messages_page_down: z.string().optional().default("pgdown").describe("Scroll messages down by one page"),
+ messages_half_page_up: z.string().optional().default("ctrl+alt+u").describe("Scroll messages up by half page"),
+ messages_half_page_down: z
+ .string()
+ .optional()
+ .default("ctrl+alt+d")
+ .describe("Scroll messages down by half page"),
+ messages_previous: z.string().optional().default("ctrl+up").describe("Navigate to previous message"),
+ messages_next: z.string().optional().default("ctrl+down").describe("Navigate to next message"),
+ messages_first: z.string().optional().default("ctrl+g").describe("Navigate to first message"),
+ messages_last: z.string().optional().default("ctrl+alt+g").describe("Navigate to last message"),
+ messages_layout_toggle: z.string().optional().default("<leader>p").describe("Toggle layout"),
+ messages_copy: z.string().optional().default("<leader>y").describe("Copy message"),
+ messages_revert: z.string().optional().default("<leader>r").describe("Revert message"),
+ app_exit: z.string().optional().default("ctrl+c,<leader>q").describe("Exit the application"),
})
.strict()
.openapi({