diff options
| author | Dax <[email protected]> | 2026-01-08 17:32:21 -0500 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-01-08 17:32:21 -0500 |
| commit | 22dd70b75bdb662a8cd78a67772bf54d7fc570f1 (patch) | |
| tree | abff1af7d24d882aca11c1c1f9b3d438c2cbda7c | |
| parent | b4f8de0c0adb714e64aa9b2babea91afa5d04758 (diff) | |
| download | opencode-22dd70b75bdb662a8cd78a67772bf54d7fc570f1.tar.gz opencode-22dd70b75bdb662a8cd78a67772bf54d7fc570f1.zip | |
feat(question): support multi-select questions (#7386)
| -rw-r--r-- | packages/opencode/src/cli/cmd/tui/routes/session/index.tsx | 8 | ||||
| -rw-r--r-- | packages/opencode/src/cli/cmd/tui/routes/session/question.tsx | 125 | ||||
| -rw-r--r-- | packages/opencode/src/question/index.ts | 20 | ||||
| -rw-r--r-- | packages/opencode/src/server/question.ts | 2 | ||||
| -rw-r--r-- | packages/opencode/src/tool/question.ts | 7 | ||||
| -rw-r--r-- | packages/opencode/src/tool/question.txt | 1 | ||||
| -rw-r--r-- | packages/opencode/test/question/question.test.ts | 12 | ||||
| -rw-r--r-- | packages/sdk/js/src/v2/gen/sdk.gen.ts | 3 | ||||
| -rw-r--r-- | packages/sdk/js/src/v2/gen/types.gen.ts | 13 | ||||
| -rw-r--r-- | packages/sdk/openapi.json | 1545 |
10 files changed, 1411 insertions, 325 deletions
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx index 5c34fd4ad..10e340d7f 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx @@ -1840,6 +1840,12 @@ function TodoWrite(props: ToolProps<typeof TodoWriteTool>) { function Question(props: ToolProps<typeof QuestionTool>) { const { theme } = useTheme() const count = createMemo(() => props.input.questions?.length ?? 0) + + function format(answer?: string[]) { + if (!answer?.length) return "(no answer)" + return answer.join(", ") + } + return ( <Switch> <Match when={props.metadata.answers}> @@ -1849,7 +1855,7 @@ function Question(props: ToolProps<typeof QuestionTool>) { {(q, i) => ( <box flexDirection="row" gap={1}> <text fg={theme.textMuted}>{q.question}</text> - <text fg={theme.text}>{props.metadata.answers?.[i()] || "(no answer)"}</text> + <text fg={theme.text}>{format(props.metadata.answers?.[i()])}</text> </box> )} </For> diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx index 82a6a021c..e43f4219b 100644 --- a/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx +++ b/packages/opencode/src/cli/cmd/tui/routes/session/question.tsx @@ -4,7 +4,7 @@ import { useKeyboard } from "@opentui/solid" import type { TextareaRenderable } from "@opentui/core" import { useKeybind } from "../../context/keybind" import { useTheme } from "../../context/theme" -import type { QuestionRequest } from "@opencode-ai/sdk/v2" +import type { QuestionAnswer, QuestionRequest } from "@opencode-ai/sdk/v2" import { useSDK } from "../../context/sdk" import { SplitBorder } from "../../component/border" import { useTextareaKeybindings } from "../../component/textarea-keybindings" @@ -17,11 +17,11 @@ export function QuestionPrompt(props: { request: QuestionRequest }) { const bindings = useTextareaKeybindings() const questions = createMemo(() => props.request.questions) - const single = createMemo(() => questions().length === 1) - const tabs = createMemo(() => (single() ? 1 : questions().length + 1)) // questions + confirm tab (no confirm for single) + const single = createMemo(() => questions().length === 1 && questions()[0]?.multiple !== true) + const tabs = createMemo(() => (single() ? 1 : questions().length + 1)) // questions + confirm tab (no confirm for single select) const [store, setStore] = createStore({ tab: 0, - answers: [] as string[], + answers: [] as QuestionAnswer[], custom: [] as string[], selected: 0, editing: false, @@ -34,10 +34,15 @@ export function QuestionPrompt(props: { request: QuestionRequest }) { const options = createMemo(() => question()?.options ?? []) const other = createMemo(() => store.selected === options().length) const input = createMemo(() => store.custom[store.tab] ?? "") + const multi = createMemo(() => question()?.multiple === true) + const customPicked = createMemo(() => { + const value = input() + if (!value) return false + return store.answers[store.tab]?.includes(value) ?? false + }) function submit() { - // Fill in empty answers with empty strings - const answers = questions().map((_, i) => store.answers[i] ?? "") + const answers = questions().map((_, i) => store.answers[i] ?? []) sdk.client.question.reply({ requestID: props.request.id, answers, @@ -52,7 +57,7 @@ export function QuestionPrompt(props: { request: QuestionRequest }) { function pick(answer: string, custom: boolean = false) { const answers = [...store.answers] - answers[store.tab] = answer + answers[store.tab] = [answer] setStore("answers", answers) if (custom) { const inputs = [...store.custom] @@ -62,7 +67,7 @@ export function QuestionPrompt(props: { request: QuestionRequest }) { if (single()) { sdk.client.question.reply({ requestID: props.request.id, - answers: [answer], + answers: [[answer]], }) return } @@ -70,6 +75,17 @@ export function QuestionPrompt(props: { request: QuestionRequest }) { setStore("selected", 0) } + function toggle(answer: string) { + const existing = store.answers[store.tab] ?? [] + const next = [...existing] + const index = next.indexOf(answer) + if (index === -1) next.push(answer) + if (index !== -1) next.splice(index, 1) + const answers = [...store.answers] + answers[store.tab] = next + setStore("answers", answers) + } + const dialog = useDialog() useKeyboard((evt) => { @@ -82,11 +98,49 @@ export function QuestionPrompt(props: { request: QuestionRequest }) { } if (evt.name === "return") { evt.preventDefault() - const text = textarea?.plainText?.trim() - if (text) { - pick(text, true) + const text = textarea?.plainText?.trim() ?? "" + const prev = store.custom[store.tab] + + if (!text) { + if (prev) { + const inputs = [...store.custom] + inputs[store.tab] = "" + setStore("custom", inputs) + } + + const answers = [...store.answers] + if (prev) { + answers[store.tab] = (answers[store.tab] ?? []).filter((x) => x !== prev) + } + if (!prev) { + answers[store.tab] = [] + } + setStore("answers", answers) + setStore("editing", false) + return + } + + if (multi()) { + const inputs = [...store.custom] + inputs[store.tab] = text + setStore("custom", inputs) + + const existing = store.answers[store.tab] ?? [] + const next = [...existing] + if (prev) { + const index = next.indexOf(prev) + if (index !== -1) next.splice(index, 1) + } + if (!next.includes(text)) next.push(text) + const answers = [...store.answers] + answers[store.tab] = next + setStore("answers", answers) setStore("editing", false) + return } + + pick(text, true) + setStore("editing", false) return } // Let textarea handle all other keys @@ -133,13 +187,25 @@ export function QuestionPrompt(props: { request: QuestionRequest }) { if (evt.name === "return") { evt.preventDefault() if (other()) { - setStore("editing", true) - } else { - const opt = opts[store.selected] - if (opt) { - pick(opt.label) + if (!multi()) { + setStore("editing", true) + return + } + const value = input() + if (value && customPicked()) { + toggle(value) + return } + setStore("editing", true) + return } + const opt = opts[store.selected] + if (!opt) return + if (multi()) { + toggle(opt.label) + return + } + pick(opt.label) } if (evt.name === "escape" || keybind.match("app_exit", evt)) { @@ -162,7 +228,9 @@ export function QuestionPrompt(props: { request: QuestionRequest }) { <For each={questions()}> {(q, index) => { const isActive = () => index() === store.tab - const isAnswered = () => store.answers[index()] !== undefined + const isAnswered = () => { + return (store.answers[index()]?.length ?? 0) > 0 + } return ( <box paddingLeft={1} @@ -185,13 +253,16 @@ export function QuestionPrompt(props: { request: QuestionRequest }) { <Show when={!confirm()}> <box paddingLeft={1} gap={1}> <box> - <text fg={theme.text}>{question()?.question}</text> + <text fg={theme.text}> + {question()?.question} + {multi() ? " (select all that apply)" : ""} + </text> </box> <box> <For each={options()}> {(opt, i) => { const active = () => i() === store.selected - const picked = () => store.answers[store.tab] === opt.label + const picked = () => store.answers[store.tab]?.includes(opt.label) ?? false return ( <box> <box flexDirection="row" gap={1}> @@ -212,17 +283,18 @@ export function QuestionPrompt(props: { request: QuestionRequest }) { <box> <box flexDirection="row" gap={1}> <box backgroundColor={other() ? theme.backgroundElement : undefined}> - <text fg={other() ? theme.secondary : input() ? theme.success : theme.text}> + <text fg={other() ? theme.secondary : customPicked() ? theme.success : theme.text}> {options().length + 1}. Type your own answer </text> </box> - <text fg={theme.success}>{input() ? "✓" : ""}</text> + <text fg={theme.success}>{customPicked() ? "✓" : ""}</text> </box> <Show when={store.editing}> <box paddingLeft={3}> <textarea ref={(val: TextareaRenderable) => (textarea = val)} focused + initialValue={input()} placeholder="Type your own answer" textColor={theme.text} focusedTextColor={theme.text} @@ -247,11 +319,12 @@ export function QuestionPrompt(props: { request: QuestionRequest }) { </box> <For each={questions()}> {(q, index) => { - const answer = () => store.answers[index()] + const value = () => store.answers[index()]?.join(", ") ?? "" + const answered = () => Boolean(value()) return ( <box flexDirection="row" gap={1} paddingLeft={1}> <text fg={theme.textMuted}>{q.header}:</text> - <text fg={answer() ? theme.text : theme.error}>{answer() ?? "(not answered)"}</text> + <text fg={answered() ? theme.text : theme.error}>{answered() ? value() : "(not answered)"}</text> </box> ) }} @@ -279,8 +352,12 @@ export function QuestionPrompt(props: { request: QuestionRequest }) { </text> </Show> <text fg={theme.text}> - enter <span style={{ fg: theme.textMuted }}>{confirm() ? "submit" : single() ? "submit" : "confirm"}</span> + enter{" "} + <span style={{ fg: theme.textMuted }}> + {confirm() ? "submit" : multi() ? "toggle" : single() ? "submit" : "confirm"} + </span> </text> + <text fg={theme.text}> esc <span style={{ fg: theme.textMuted }}>dismiss</span> </text> diff --git a/packages/opencode/src/question/index.ts b/packages/opencode/src/question/index.ts index 0fc90b40c..23656b53a 100644 --- a/packages/opencode/src/question/index.ts +++ b/packages/opencode/src/question/index.ts @@ -23,6 +23,7 @@ export namespace Question { question: z.string().describe("Complete question"), header: z.string().max(12).describe("Very short label (max 12 chars)"), options: z.array(Option).describe("Available choices"), + multiple: z.boolean().optional().describe("Allow selecting multiple choices"), }) .meta({ ref: "QuestionInfo", @@ -46,8 +47,15 @@ export namespace Question { }) export type Request = z.infer<typeof Request> + export const Answer = z.array(z.string()).meta({ + ref: "QuestionAnswer", + }) + export type Answer = z.infer<typeof Answer> + export const Reply = z.object({ - answers: z.array(z.string()).describe("User answers in order of questions"), + answers: z + .array(Answer) + .describe("User answers in order of questions (each answer is an array of selected labels)"), }) export type Reply = z.infer<typeof Reply> @@ -58,7 +66,7 @@ export namespace Question { z.object({ sessionID: z.string(), requestID: z.string(), - answers: z.array(z.string()), + answers: z.array(Answer), }), ), Rejected: BusEvent.define( @@ -75,7 +83,7 @@ export namespace Question { string, { info: Request - resolve: (answers: string[]) => void + resolve: (answers: Answer[]) => void reject: (e: any) => void } > = {} @@ -89,13 +97,13 @@ export namespace Question { sessionID: string questions: Info[] tool?: { messageID: string; callID: string } - }): Promise<string[]> { + }): Promise<Answer[]> { const s = await state() const id = Identifier.ascending("question") log.info("asking", { id, questions: input.questions.length }) - return new Promise<string[]>((resolve, reject) => { + return new Promise<Answer[]>((resolve, reject) => { const info: Request = { id, sessionID: input.sessionID, @@ -111,7 +119,7 @@ export namespace Question { }) } - export async function reply(input: { requestID: string; answers: string[] }): Promise<void> { + export async function reply(input: { requestID: string; answers: Answer[] }): Promise<void> { const s = await state() const existing = s.pending[input.requestID] if (!existing) { diff --git a/packages/opencode/src/server/question.ts b/packages/opencode/src/server/question.ts index e4f9e443a..c893862ca 100644 --- a/packages/opencode/src/server/question.ts +++ b/packages/opencode/src/server/question.ts @@ -52,7 +52,7 @@ export const QuestionRoute = new Hono() requestID: z.string(), }), ), - validator("json", z.object({ answers: z.array(z.string()) })), + validator("json", Question.Reply), async (c) => { const params = c.req.valid("param") const json = c.req.valid("json") diff --git a/packages/opencode/src/tool/question.ts b/packages/opencode/src/tool/question.ts index 5b34875c1..c6f0b9159 100644 --- a/packages/opencode/src/tool/question.ts +++ b/packages/opencode/src/tool/question.ts @@ -15,7 +15,12 @@ export const QuestionTool = Tool.define("question", { tool: ctx.callID ? { messageID: ctx.messageID, callID: ctx.callID } : undefined, }) - const formatted = params.questions.map((q, i) => `"${q.question}"="${answers[i] ?? "Unanswered"}"`).join(", ") + function format(answer: Question.Answer | undefined) { + if (!answer?.length) return "Unanswered" + return answer.join(", ") + } + + const formatted = params.questions.map((q, i) => `"${q.question}"="${format(answers[i])}"`).join(", ") return { title: `Asked ${params.questions.length} question${params.questions.length > 1 ? "s" : ""}`, diff --git a/packages/opencode/src/tool/question.txt b/packages/opencode/src/tool/question.txt index bb5af8275..a85a4110f 100644 --- a/packages/opencode/src/tool/question.txt +++ b/packages/opencode/src/tool/question.txt @@ -6,4 +6,5 @@ Use this tool when you need to ask the user questions during execution. This all Usage notes: - Users will always be able to select "Other" to provide custom text input +- Answers are returned as arrays of labels; set `multiple: true` to allow selecting more than one - If you recommend a specific option, make that the first option in the list and add "(Recommended)" at the end of the label diff --git a/packages/opencode/test/question/question.test.ts b/packages/opencode/test/question/question.test.ts index 2e4b2d7ab..cf24faa7d 100644 --- a/packages/opencode/test/question/question.test.ts +++ b/packages/opencode/test/question/question.test.ts @@ -82,11 +82,11 @@ test("reply - resolves the pending ask with answers", async () => { await Question.reply({ requestID, - answers: ["Option 1"], + answers: [["Option 1"]], }) const answers = await askPromise - expect(answers).toEqual(["Option 1"]) + expect(answers).toEqual([["Option 1"]]) }, }) }) @@ -115,7 +115,7 @@ test("reply - removes from pending list", async () => { await Question.reply({ requestID: pending[0].id, - answers: ["Option 1"], + answers: [["Option 1"]], }) const pendingAfter = await Question.list() @@ -131,7 +131,7 @@ test("reply - does nothing for unknown requestID", async () => { fn: async () => { await Question.reply({ requestID: "que_unknown", - answers: ["Option 1"], + answers: [["Option 1"]], }) // Should not throw }, @@ -244,11 +244,11 @@ test("ask - handles multiple questions", async () => { await Question.reply({ requestID: pending[0].id, - answers: ["Build", "Dev"], + answers: [["Build"], ["Dev"]], }) const answers = await askPromise - expect(answers).toEqual(["Build", "Dev"]) + expect(answers).toEqual([["Build"], ["Dev"]]) }, }) }) diff --git a/packages/sdk/js/src/v2/gen/sdk.gen.ts b/packages/sdk/js/src/v2/gen/sdk.gen.ts index dae865a7c..f83913ea5 100644 --- a/packages/sdk/js/src/v2/gen/sdk.gen.ts +++ b/packages/sdk/js/src/v2/gen/sdk.gen.ts @@ -84,6 +84,7 @@ import type { PtyRemoveResponses, PtyUpdateErrors, PtyUpdateResponses, + QuestionAnswer, QuestionListResponses, QuestionRejectErrors, QuestionRejectResponses, @@ -1815,7 +1816,7 @@ export class Question extends HeyApiClient { parameters: { requestID: string directory?: string - answers?: Array<string> + answers?: Array<QuestionAnswer> }, options?: Options<never, ThrowOnError>, ) { diff --git a/packages/sdk/js/src/v2/gen/types.gen.ts b/packages/sdk/js/src/v2/gen/types.gen.ts index ea86b022d..9cb7222aa 100644 --- a/packages/sdk/js/src/v2/gen/types.gen.ts +++ b/packages/sdk/js/src/v2/gen/types.gen.ts @@ -541,6 +541,10 @@ export type QuestionInfo = { * Available choices */ options: Array<QuestionOption> + /** + * Allow selecting multiple choices + */ + multiple?: boolean } export type QuestionRequest = { @@ -561,12 +565,14 @@ export type EventQuestionAsked = { properties: QuestionRequest } +export type QuestionAnswer = Array<string> + export type EventQuestionReplied = { type: "question.replied" properties: { sessionID: string requestID: string - answers: Array<string> + answers: Array<QuestionAnswer> } } @@ -3630,7 +3636,10 @@ export type QuestionListResponse = QuestionListResponses[keyof QuestionListRespo export type QuestionReplyData = { body?: { - answers: Array<string> + /** + * User answers in order of questions (each answer is an array of selected labels) + */ + answers: Array<QuestionAnswer> } path: { requestID: string diff --git a/packages/sdk/openapi.json b/packages/sdk/openapi.json index 13346a625..6357d2c07 100644 --- a/packages/sdk/openapi.json +++ b/packages/sdk/openapi.json @@ -27,7 +27,10 @@ "type": "string" } }, - "required": ["healthy", "version"] + "required": [ + "healthy", + "version" + ] } } } @@ -476,7 +479,10 @@ "type": "number" } }, - "required": ["rows", "cols"] + "required": [ + "rows", + "cols" + ] } } } @@ -1169,7 +1175,9 @@ ], "summary": "Get session", "description": "Retrieve detailed information about a specific OpenCode session.", - "tags": ["Session"], + "tags": [ + "Session" + ], "responses": { "200": { "description": "Get session", @@ -1375,7 +1383,9 @@ } ], "summary": "Get session children", - "tags": ["Session"], + "tags": [ + "Session" + ], "description": "Retrieve all child sessions that were forked from the specified parent session.", "responses": { "200": { @@ -1558,7 +1568,11 @@ "pattern": "^msg.*" } }, - "required": ["modelID", "providerID", "messageID"] + "required": [ + "modelID", + "providerID", + "messageID" + ] } } } @@ -1960,7 +1974,10 @@ "type": "boolean" } }, - "required": ["providerID", "modelID"] + "required": [ + "providerID", + "modelID" + ] } } } @@ -2023,7 +2040,10 @@ } } }, - "required": ["info", "parts"] + "required": [ + "info", + "parts" + ] } } } @@ -2097,7 +2117,10 @@ } } }, - "required": ["info", "parts"] + "required": [ + "info", + "parts" + ] } } } @@ -2143,7 +2166,10 @@ "type": "string" } }, - "required": ["providerID", "modelID"] + "required": [ + "providerID", + "modelID" + ] }, "agent": { "type": "string" @@ -2187,7 +2213,9 @@ } } }, - "required": ["parts"] + "required": [ + "parts" + ] } } } @@ -2250,7 +2278,10 @@ } } }, - "required": ["info", "parts"] + "required": [ + "info", + "parts" + ] } } } @@ -2519,7 +2550,10 @@ "type": "string" } }, - "required": ["providerID", "modelID"] + "required": [ + "providerID", + "modelID" + ] }, "agent": { "type": "string" @@ -2563,7 +2597,9 @@ } } }, - "required": ["parts"] + "required": [ + "parts" + ] } } } @@ -2617,7 +2653,10 @@ } } }, - "required": ["info", "parts"] + "required": [ + "info", + "parts" + ] } } } @@ -2695,13 +2734,20 @@ "$ref": "#/components/schemas/FilePartSource" } }, - "required": ["type", "mime", "url"] + "required": [ + "type", + "mime", + "url" + ] } ] } } }, - "required": ["arguments", "command"] + "required": [ + "arguments", + "command" + ] } } } @@ -2788,13 +2834,19 @@ "type": "string" } }, - "required": ["providerID", "modelID"] + "required": [ + "providerID", + "modelID" + ] }, "command": { "type": "string" } }, - "required": ["agent", "command"] + "required": [ + "agent", + "command" + ] } } } @@ -2876,7 +2928,9 @@ "pattern": "^prt.*" } }, - "required": ["messageID"] + "required": [ + "messageID" + ] } } } @@ -3022,10 +3076,16 @@ "properties": { "response": { "type": "string", - "enum": ["once", "always", "reject"] + "enum": [ + "once", + "always", + "reject" + ] } }, - "required": ["response"] + "required": [ + "response" + ] } } } @@ -3100,13 +3160,19 @@ "properties": { "reply": { "type": "string", - "enum": ["once", "always", "reject"] + "enum": [ + "once", + "always", + "reject" + ] }, "message": { "type": "string" } }, - "required": ["reply"] + "required": [ + "reply" + ] } } } @@ -3254,13 +3320,16 @@ "type": "object", "properties": { "answers": { + "description": "User answers in order of questions (each answer is an array of selected labels)", "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/QuestionAnswer" } } }, - "required": ["answers"] + "required": [ + "answers" + ] } } } @@ -3410,7 +3479,10 @@ } } }, - "required": ["providers", "default"] + "required": [ + "providers", + "default" + ] } } } @@ -3512,10 +3584,15 @@ "properties": { "field": { "type": "string", - "enum": ["reasoning_content", "reasoning_details"] + "enum": [ + "reasoning_content", + "reasoning_details" + ] } }, - "required": ["field"], + "required": [ + "field" + ], "additionalProperties": false } ] @@ -3551,10 +3628,16 @@ "type": "number" } }, - "required": ["input", "output"] + "required": [ + "input", + "output" + ] } }, - "required": ["input", "output"] + "required": [ + "input", + "output" + ] }, "limit": { "type": "object", @@ -3566,7 +3649,10 @@ "type": "number" } }, - "required": ["context", "output"] + "required": [ + "context", + "output" + ] }, "modalities": { "type": "object", @@ -3575,25 +3661,44 @@ "type": "array", "items": { "type": "string", - "enum": ["text", "audio", "image", "video", "pdf"] + "enum": [ + "text", + "audio", + "image", + "video", + "pdf" + ] } }, "output": { "type": "array", "items": { "type": "string", - "enum": ["text", "audio", "image", "video", "pdf"] + "enum": [ + "text", + "audio", + "image", + "video", + "pdf" + ] } } }, - "required": ["input", "output"] + "required": [ + "input", + "output" + ] }, "experimental": { "type": "boolean" }, "status": { "type": "string", - "enum": ["alpha", "beta", "deprecated"] + "enum": [ + "alpha", + "beta", + "deprecated" + ] }, "options": { "type": "object", @@ -3618,7 +3723,9 @@ "type": "string" } }, - "required": ["npm"] + "required": [ + "npm" + ] }, "variants": { "type": "object", @@ -3648,7 +3755,12 @@ } } }, - "required": ["name", "env", "id", "models"] + "required": [ + "name", + "env", + "id", + "models" + ] } }, "default": { @@ -3667,7 +3779,11 @@ } } }, - "required": ["all", "default", "connected"] + "required": [ + "all", + "default", + "connected" + ] } } } @@ -3780,7 +3896,9 @@ "type": "number" } }, - "required": ["method"] + "required": [ + "method" + ] } } } @@ -3853,7 +3971,9 @@ "type": "string" } }, - "required": ["method"] + "required": [ + "method" + ] } } } @@ -3905,7 +4025,9 @@ "type": "string" } }, - "required": ["text"] + "required": [ + "text" + ] }, "lines": { "type": "object", @@ -3914,7 +4036,9 @@ "type": "string" } }, - "required": ["text"] + "required": [ + "text" + ] }, "line_number": { "type": "number" @@ -3934,7 +4058,9 @@ "type": "string" } }, - "required": ["text"] + "required": [ + "text" + ] }, "start": { "type": "number" @@ -3943,11 +4069,21 @@ "type": "number" } }, - "required": ["match", "start", "end"] + "required": [ + "match", + "start", + "end" + ] } } }, - "required": ["path", "lines", "line_number", "absolute_offset", "submatches"] + "required": [ + "path", + "lines", + "line_number", + "absolute_offset", + "submatches" + ] } } } @@ -3986,7 +4122,10 @@ "name": "dirs", "schema": { "type": "string", - "enum": ["true", "false"] + "enum": [ + "true", + "false" + ] } }, { @@ -3994,7 +4133,10 @@ "name": "type", "schema": { "type": "string", - "enum": ["file", "directory"] + "enum": [ + "file", + "directory" + ] } }, { @@ -4250,7 +4392,12 @@ "level": { "description": "Log level", "type": "string", - "enum": ["debug", "info", "error", "warn"] + "enum": [ + "debug", + "info", + "error", + "warn" + ] }, "message": { "description": "Log message", @@ -4265,7 +4412,11 @@ "additionalProperties": {} } }, - "required": ["service", "level", "message"] + "required": [ + "service", + "level", + "message" + ] } } } @@ -4415,7 +4566,10 @@ ] } }, - "required": ["name", "config"] + "required": [ + "name", + "config" + ] } } } @@ -4463,7 +4617,9 @@ "type": "string" } }, - "required": ["authorizationUrl"] + "required": [ + "authorizationUrl" + ] } } } @@ -4530,7 +4686,9 @@ "const": true } }, - "required": ["success"] + "required": [ + "success" + ] } } } @@ -4619,7 +4777,9 @@ "type": "string" } }, - "required": ["code"] + "required": [ + "code" + ] } } } @@ -4936,7 +5096,9 @@ "type": "string" } }, - "required": ["text"] + "required": [ + "text" + ] } } } @@ -5199,7 +5361,9 @@ "type": "string" } }, - "required": ["command"] + "required": [ + "command" + ] } } } @@ -5252,7 +5416,12 @@ }, "variant": { "type": "string", - "enum": ["info", "success", "warning", "error"] + "enum": [ + "info", + "success", + "warning", + "error" + ] }, "duration": { "description": "Duration in milliseconds", @@ -5260,7 +5429,10 @@ "type": "number" } }, - "required": ["message", "variant"] + "required": [ + "message", + "variant" + ] } } } @@ -5397,7 +5569,9 @@ "pattern": "^ses" } }, - "required": ["sessionID"] + "required": [ + "sessionID" + ] } } } @@ -5437,7 +5611,10 @@ }, "body": {} }, - "required": ["path", "body"] + "required": [ + "path", + "body" + ] } } } @@ -5604,10 +5781,15 @@ "type": "string" } }, - "required": ["version"] + "required": [ + "version" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.installation.update-available": { "type": "object", @@ -5623,10 +5805,15 @@ "type": "string" } }, - "required": ["version"] + "required": [ + "version" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Project": { "type": "object", @@ -5668,7 +5855,10 @@ "type": "number" } }, - "required": ["created", "updated"] + "required": [ + "created", + "updated" + ] }, "sandboxes": { "type": "array", @@ -5677,7 +5867,12 @@ } } }, - "required": ["id", "worktree", "time", "sandboxes"] + "required": [ + "id", + "worktree", + "time", + "sandboxes" + ] }, "Event.project.updated": { "type": "object", @@ -5690,7 +5885,10 @@ "$ref": "#/components/schemas/Project" } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.server.instance.disposed": { "type": "object", @@ -5706,10 +5904,15 @@ "type": "string" } }, - "required": ["directory"] + "required": [ + "directory" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.lsp.client.diagnostics": { "type": "object", @@ -5728,10 +5931,16 @@ "type": "string" } }, - "required": ["serverID", "path"] + "required": [ + "serverID", + "path" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.lsp.updated": { "type": "object", @@ -5745,7 +5954,10 @@ "properties": {} } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "FileDiff": { "type": "object", @@ -5766,7 +5978,13 @@ "type": "number" } }, - "required": ["file", "before", "after", "additions", "deletions"] + "required": [ + "file", + "before", + "after", + "additions", + "deletions" + ] }, "UserMessage": { "type": "object", @@ -5788,7 +6006,9 @@ "type": "number" } }, - "required": ["created"] + "required": [ + "created" + ] }, "summary": { "type": "object", @@ -5806,7 +6026,9 @@ } } }, - "required": ["diffs"] + "required": [ + "diffs" + ] }, "agent": { "type": "string" @@ -5821,7 +6043,10 @@ "type": "string" } }, - "required": ["providerID", "modelID"] + "required": [ + "providerID", + "modelID" + ] }, "system": { "type": "string" @@ -5839,7 +6064,14 @@ "type": "string" } }, - "required": ["id", "sessionID", "role", "time", "agent", "model"] + "required": [ + "id", + "sessionID", + "role", + "time", + "agent", + "model" + ] }, "ProviderAuthError": { "type": "object", @@ -5858,10 +6090,16 @@ "type": "string" } }, - "required": ["providerID", "message"] + "required": [ + "providerID", + "message" + ] } }, - "required": ["name", "data"] + "required": [ + "name", + "data" + ] }, "UnknownError": { "type": "object", @@ -5877,10 +6115,15 @@ "type": "string" } }, - "required": ["message"] + "required": [ + "message" + ] } }, - "required": ["name", "data"] + "required": [ + "name", + "data" + ] }, "MessageOutputLengthError": { "type": "object", @@ -5894,7 +6137,10 @@ "properties": {} } }, - "required": ["name", "data"] + "required": [ + "name", + "data" + ] }, "MessageAbortedError": { "type": "object", @@ -5910,10 +6156,15 @@ "type": "string" } }, - "required": ["message"] + "required": [ + "message" + ] } }, - "required": ["name", "data"] + "required": [ + "name", + "data" + ] }, "APIError": { "type": "object", @@ -5956,10 +6207,16 @@ } } }, - "required": ["message", "isRetryable"] + "required": [ + "message", + "isRetryable" + ] } }, - "required": ["name", "data"] + "required": [ + "name", + "data" + ] }, "AssistantMessage": { "type": "object", @@ -5984,7 +6241,9 @@ "type": "number" } }, - "required": ["created"] + "required": [ + "created" + ] }, "error": { "anyOf": [ @@ -6030,7 +6289,10 @@ "type": "string" } }, - "required": ["cwd", "root"] + "required": [ + "cwd", + "root" + ] }, "summary": { "type": "boolean" @@ -6060,10 +6322,18 @@ "type": "number" } }, - "required": ["read", "write"] + "required": [ + "read", + "write" + ] } }, - "required": ["input", "output", "reasoning", "cache"] + "required": [ + "input", + "output", + "reasoning", + "cache" + ] }, "finish": { "type": "string" @@ -6108,10 +6378,15 @@ "$ref": "#/components/schemas/Message" } }, - "required": ["info"] + "required": [ + "info" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.message.removed": { "type": "object", @@ -6130,10 +6405,16 @@ "type": "string" } }, - "required": ["sessionID", "messageID"] + "required": [ + "sessionID", + "messageID" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "TextPart": { "type": "object", @@ -6170,7 +6451,9 @@ "type": "number" } }, - "required": ["start"] + "required": [ + "start" + ] }, "metadata": { "type": "object", @@ -6180,7 +6463,13 @@ "additionalProperties": {} } }, - "required": ["id", "sessionID", "messageID", "type", "text"] + "required": [ + "id", + "sessionID", + "messageID", + "type", + "text" + ] }, "ReasoningPart": { "type": "object", @@ -6218,10 +6507,19 @@ "type": "number" } }, - "required": ["start"] + "required": [ + "start" + ] } }, - "required": ["id", "sessionID", "messageID", "type", "text", "time"] + "required": [ + "id", + "sessionID", + "messageID", + "type", + "text", + "time" + ] }, "FilePartSourceText": { "type": "object", @@ -6240,7 +6538,11 @@ "maximum": 9007199254740991 } }, - "required": ["value", "start", "end"] + "required": [ + "value", + "start", + "end" + ] }, "FileSource": { "type": "object", @@ -6256,7 +6558,11 @@ "type": "string" } }, - "required": ["text", "type", "path"] + "required": [ + "text", + "type", + "path" + ] }, "Range": { "type": "object", @@ -6271,7 +6577,10 @@ "type": "number" } }, - "required": ["line", "character"] + "required": [ + "line", + "character" + ] }, "end": { "type": "object", @@ -6283,10 +6592,16 @@ "type": "number" } }, - "required": ["line", "character"] + "required": [ + "line", + "character" + ] } }, - "required": ["start", "end"] + "required": [ + "start", + "end" + ] }, "SymbolSource": { "type": "object", @@ -6313,7 +6628,14 @@ "maximum": 9007199254740991 } }, - "required": ["text", "type", "path", "range", "name", "kind"] + "required": [ + "text", + "type", + "path", + "range", + "name", + "kind" + ] }, "ResourceSource": { "type": "object", @@ -6332,7 +6654,12 @@ "type": "string" } }, - "required": ["text", "type", "clientName", "uri"] + "required": [ + "text", + "type", + "clientName", + "uri" + ] }, "FilePartSource": { "anyOf": [ @@ -6376,7 +6703,14 @@ "$ref": "#/components/schemas/FilePartSource" } }, - "required": ["id", "sessionID", "messageID", "type", "mime", "url"] + "required": [ + "id", + "sessionID", + "messageID", + "type", + "mime", + "url" + ] }, "ToolStatePending": { "type": "object", @@ -6396,7 +6730,11 @@ "type": "string" } }, - "required": ["status", "input", "raw"] + "required": [ + "status", + "input", + "raw" + ] }, "ToolStateRunning": { "type": "object", @@ -6429,10 +6767,16 @@ "type": "number" } }, - "required": ["start"] + "required": [ + "start" + ] } }, - "required": ["status", "input", "time"] + "required": [ + "status", + "input", + "time" + ] }, "ToolStateCompleted": { "type": "object", @@ -6474,7 +6818,10 @@ "type": "number" } }, - "required": ["start", "end"] + "required": [ + "start", + "end" + ] }, "attachments": { "type": "array", @@ -6483,7 +6830,14 @@ } } }, - "required": ["status", "input", "output", "title", "metadata", "time"] + "required": [ + "status", + "input", + "output", + "title", + "metadata", + "time" + ] }, "ToolStateError": { "type": "object", @@ -6519,10 +6873,18 @@ "type": "number" } }, - "required": ["start", "end"] + "required": [ + "start", + "end" + ] } }, - "required": ["status", "input", "error", "time"] + "required": [ + "status", + "input", + "error", + "time" + ] }, "ToolState": { "anyOf": [ @@ -6573,7 +6935,15 @@ "additionalProperties": {} } }, - "required": ["id", "sessionID", "messageID", "type", "callID", "tool", "state"] + "required": [ + "id", + "sessionID", + "messageID", + "type", + "callID", + "tool", + "state" + ] }, "StepStartPart": { "type": "object", @@ -6595,7 +6965,12 @@ "type": "string" } }, - "required": ["id", "sessionID", "messageID", "type"] + "required": [ + "id", + "sessionID", + "messageID", + "type" + ] }, "StepFinishPart": { "type": "object", @@ -6644,13 +7019,29 @@ "type": "number" } }, - "required": ["read", "write"] + "required": [ + "read", + "write" + ] } }, - "required": ["input", "output", "reasoning", "cache"] + "required": [ + "input", + "output", + "reasoning", + "cache" + ] } }, - "required": ["id", "sessionID", "messageID", "type", "reason", "cost", "tokens"] + "required": [ + "id", + "sessionID", + "messageID", + "type", + "reason", + "cost", + "tokens" + ] }, "SnapshotPart": { "type": "object", @@ -6672,7 +7063,13 @@ "type": "string" } }, - "required": ["id", "sessionID", "messageID", "type", "snapshot"] + "required": [ + "id", + "sessionID", + "messageID", + "type", + "snapshot" + ] }, "PatchPart": { "type": "object", @@ -6700,7 +7097,14 @@ } } }, - "required": ["id", "sessionID", "messageID", "type", "hash", "files"] + "required": [ + "id", + "sessionID", + "messageID", + "type", + "hash", + "files" + ] }, "AgentPart": { "type": "object", @@ -6738,10 +7142,20 @@ "maximum": 9007199254740991 } }, - "required": ["value", "start", "end"] + "required": [ + "value", + "start", + "end" + ] } }, - "required": ["id", "sessionID", "messageID", "type", "name"] + "required": [ + "id", + "sessionID", + "messageID", + "type", + "name" + ] }, "RetryPart": { "type": "object", @@ -6772,10 +7186,20 @@ "type": "number" } }, - "required": ["created"] + "required": [ + "created" + ] } }, - "required": ["id", "sessionID", "messageID", "type", "attempt", "error", "time"] + "required": [ + "id", + "sessionID", + "messageID", + "type", + "attempt", + "error", + "time" + ] }, "CompactionPart": { "type": "object", @@ -6797,7 +7221,13 @@ "type": "boolean" } }, - "required": ["id", "sessionID", "messageID", "type", "auto"] + "required": [ + "id", + "sessionID", + "messageID", + "type", + "auto" + ] }, "Part": { "anyOf": [ @@ -6833,7 +7263,15 @@ "type": "string" } }, - "required": ["id", "sessionID", "messageID", "type", "prompt", "description", "agent"] + "required": [ + "id", + "sessionID", + "messageID", + "type", + "prompt", + "description", + "agent" + ] }, { "$ref": "#/components/schemas/ReasoningPart" @@ -6884,10 +7322,15 @@ "type": "string" } }, - "required": ["part"] + "required": [ + "part" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.message.part.removed": { "type": "object", @@ -6909,10 +7352,17 @@ "type": "string" } }, - "required": ["sessionID", "messageID", "partID"] + "required": [ + "sessionID", + "messageID", + "partID" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "PermissionRequest": { "type": "object", @@ -6957,10 +7407,20 @@ "type": "string" } }, - "required": ["messageID", "callID"] + "required": [ + "messageID", + "callID" + ] } }, - "required": ["id", "sessionID", "permission", "patterns", "metadata", "always"] + "required": [ + "id", + "sessionID", + "permission", + "patterns", + "metadata", + "always" + ] }, "Event.permission.asked": { "type": "object", @@ -6973,7 +7433,10 @@ "$ref": "#/components/schemas/PermissionRequest" } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.permission.replied": { "type": "object", @@ -6993,13 +7456,24 @@ }, "reply": { "type": "string", - "enum": ["once", "always", "reject"] + "enum": [ + "once", + "always", + "reject" + ] } }, - "required": ["sessionID", "requestID", "reply"] + "required": [ + "sessionID", + "requestID", + "reply" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "SessionStatus": { "anyOf": [ @@ -7011,7 +7485,9 @@ "const": "idle" } }, - "required": ["type"] + "required": [ + "type" + ] }, { "type": "object", @@ -7030,7 +7506,12 @@ "type": "number" } }, - "required": ["type", "attempt", "message", "next"] + "required": [ + "type", + "attempt", + "message", + "next" + ] }, { "type": "object", @@ -7040,7 +7521,9 @@ "const": "busy" } }, - "required": ["type"] + "required": [ + "type" + ] } ] }, @@ -7061,10 +7544,16 @@ "$ref": "#/components/schemas/SessionStatus" } }, - "required": ["sessionID", "status"] + "required": [ + "sessionID", + "status" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.session.idle": { "type": "object", @@ -7080,10 +7569,15 @@ "type": "string" } }, - "required": ["sessionID"] + "required": [ + "sessionID" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "QuestionOption": { "type": "object", @@ -7097,7 +7591,10 @@ "type": "string" } }, - "required": ["label", "description"] + "required": [ + "label", + "description" + ] }, "QuestionInfo": { "type": "object", @@ -7117,9 +7614,17 @@ "items": { "$ref": "#/components/schemas/QuestionOption" } + }, + "multiple": { + "description": "Allow selecting multiple choices", + "type": "boolean" } }, - "required": ["question", "header", "options"] + "required": [ + "question", + "header", + "options" + ] }, "QuestionRequest": { "type": "object", @@ -7149,10 +7654,17 @@ "type": "string" } }, - "required": ["messageID", "callID"] + "required": [ + "messageID", + "callID" + ] } }, - "required": ["id", "sessionID", "questions"] + "required": [ + "id", + "sessionID", + "questions" + ] }, "Event.question.asked": { "type": "object", @@ -7165,7 +7677,16 @@ "$ref": "#/components/schemas/QuestionRequest" } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] + }, + "QuestionAnswer": { + "type": "array", + "items": { + "type": "string" + } }, "Event.question.replied": { "type": "object", @@ -7186,14 +7707,21 @@ "answers": { "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/QuestionAnswer" } } }, - "required": ["sessionID", "requestID", "answers"] + "required": [ + "sessionID", + "requestID", + "answers" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.question.rejected": { "type": "object", @@ -7212,10 +7740,16 @@ "type": "string" } }, - "required": ["sessionID", "requestID"] + "required": [ + "sessionID", + "requestID" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.session.compacted": { "type": "object", @@ -7231,10 +7765,15 @@ "type": "string" } }, - "required": ["sessionID"] + "required": [ + "sessionID" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.file.edited": { "type": "object", @@ -7250,10 +7789,15 @@ "type": "string" } }, - "required": ["file"] + "required": [ + "file" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Todo": { "type": "object", @@ -7275,7 +7819,12 @@ "type": "string" } }, - "required": ["content", "status", "priority", "id"] + "required": [ + "content", + "status", + "priority", + "id" + ] }, "Event.todo.updated": { "type": "object", @@ -7297,10 +7846,16 @@ } } }, - "required": ["sessionID", "todos"] + "required": [ + "sessionID", + "todos" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.tui.prompt.append": { "type": "object", @@ -7316,10 +7871,15 @@ "type": "string" } }, - "required": ["text"] + "required": [ + "text" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.tui.command.execute": { "type": "object", @@ -7358,10 +7918,15 @@ ] } }, - "required": ["command"] + "required": [ + "command" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.tui.toast.show": { "type": "object", @@ -7381,7 +7946,12 @@ }, "variant": { "type": "string", - "enum": ["info", "success", "warning", "error"] + "enum": [ + "info", + "success", + "warning", + "error" + ] }, "duration": { "description": "Duration in milliseconds", @@ -7389,10 +7959,16 @@ "type": "number" } }, - "required": ["message", "variant"] + "required": [ + "message", + "variant" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.tui.session.select": { "type": "object", @@ -7410,10 +7986,15 @@ "pattern": "^ses" } }, - "required": ["sessionID"] + "required": [ + "sessionID" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.mcp.tools.changed": { "type": "object", @@ -7429,10 +8010,15 @@ "type": "string" } }, - "required": ["server"] + "required": [ + "server" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.command.executed": { "type": "object", @@ -7459,14 +8045,26 @@ "pattern": "^msg.*" } }, - "required": ["name", "sessionID", "arguments", "messageID"] + "required": [ + "name", + "sessionID", + "arguments", + "messageID" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "PermissionAction": { "type": "string", - "enum": ["allow", "deny", "ask"] + "enum": [ + "allow", + "deny", + "ask" + ] }, "PermissionRule": { "type": "object", @@ -7481,7 +8079,11 @@ "$ref": "#/components/schemas/PermissionAction" } }, - "required": ["permission", "pattern", "action"] + "required": [ + "permission", + "pattern", + "action" + ] }, "PermissionRuleset": { "type": "array", @@ -7525,7 +8127,11 @@ } } }, - "required": ["additions", "deletions", "files"] + "required": [ + "additions", + "deletions", + "files" + ] }, "share": { "type": "object", @@ -7534,7 +8140,9 @@ "type": "string" } }, - "required": ["url"] + "required": [ + "url" + ] }, "title": { "type": "string" @@ -7558,7 +8166,10 @@ "type": "number" } }, - "required": ["created", "updated"] + "required": [ + "created", + "updated" + ] }, "permission": { "$ref": "#/components/schemas/PermissionRuleset" @@ -7579,10 +8190,19 @@ "type": "string" } }, - "required": ["messageID"] + "required": [ + "messageID" + ] } }, - "required": ["id", "projectID", "directory", "title", "version", "time"] + "required": [ + "id", + "projectID", + "directory", + "title", + "version", + "time" + ] }, "Event.session.created": { "type": "object", @@ -7598,10 +8218,15 @@ "$ref": "#/components/schemas/Session" } }, - "required": ["info"] + "required": [ + "info" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.session.updated": { "type": "object", @@ -7617,10 +8242,15 @@ "$ref": "#/components/schemas/Session" } }, - "required": ["info"] + "required": [ + "info" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.session.deleted": { "type": "object", @@ -7636,10 +8266,15 @@ "$ref": "#/components/schemas/Session" } }, - "required": ["info"] + "required": [ + "info" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.session.diff": { "type": "object", @@ -7661,10 +8296,16 @@ } } }, - "required": ["sessionID", "diff"] + "required": [ + "sessionID", + "diff" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.session.error": { "type": "object", @@ -7701,7 +8342,10 @@ } } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.file.watcher.updated": { "type": "object", @@ -7733,10 +8377,16 @@ ] } }, - "required": ["file", "event"] + "required": [ + "file", + "event" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.vcs.branch.updated": { "type": "object", @@ -7754,7 +8404,10 @@ } } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Pty": { "type": "object", @@ -7780,13 +8433,24 @@ }, "status": { "type": "string", - "enum": ["running", "exited"] + "enum": [ + "running", + "exited" + ] }, "pid": { "type": "number" } }, - "required": ["id", "title", "command", "args", "cwd", "status", "pid"] + "required": [ + "id", + "title", + "command", + "args", + "cwd", + "status", + "pid" + ] }, "Event.pty.created": { "type": "object", @@ -7802,10 +8466,15 @@ "$ref": "#/components/schemas/Pty" } }, - "required": ["info"] + "required": [ + "info" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.pty.updated": { "type": "object", @@ -7821,10 +8490,15 @@ "$ref": "#/components/schemas/Pty" } }, - "required": ["info"] + "required": [ + "info" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.pty.exited": { "type": "object", @@ -7844,10 +8518,16 @@ "type": "number" } }, - "required": ["id", "exitCode"] + "required": [ + "id", + "exitCode" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.pty.deleted": { "type": "object", @@ -7864,10 +8544,15 @@ "pattern": "^pty.*" } }, - "required": ["id"] + "required": [ + "id" + ] } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.server.connected": { "type": "object", @@ -7881,7 +8566,10 @@ "properties": {} } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event.global.disposed": { "type": "object", @@ -7895,7 +8583,10 @@ "properties": {} } }, - "required": ["type", "properties"] + "required": [ + "type", + "properties" + ] }, "Event": { "anyOf": [ @@ -8028,7 +8719,10 @@ "$ref": "#/components/schemas/Event" } }, - "required": ["directory", "payload"] + "required": [ + "directory", + "payload" + ] }, "BadRequestError": { "type": "object", @@ -8049,7 +8743,11 @@ "const": false } }, - "required": ["data", "errors", "success"] + "required": [ + "data", + "errors", + "success" + ] }, "NotFoundError": { "type": "object", @@ -8065,10 +8763,15 @@ "type": "string" } }, - "required": ["message"] + "required": [ + "message" + ] } }, - "required": ["name", "data"] + "required": [ + "name", + "data" + ] }, "KeybindsConfig": { "description": "Custom keybind configurations", @@ -8515,7 +9218,12 @@ "LogLevel": { "description": "Log level", "type": "string", - "enum": ["DEBUG", "INFO", "WARN", "ERROR"] + "enum": [ + "DEBUG", + "INFO", + "WARN", + "ERROR" + ] }, "ServerConfig": { "description": "Server configuration for opencode serve and web commands", @@ -8547,7 +9255,11 @@ }, "PermissionActionConfig": { "type": "string", - "enum": ["ask", "allow", "deny"] + "enum": [ + "ask", + "allow", + "deny" + ] }, "PermissionObjectConfig": { "type": "object", @@ -8671,7 +9383,11 @@ }, "mode": { "type": "string", - "enum": ["subagent", "primary", "all"] + "enum": [ + "subagent", + "primary", + "all" + ] }, "hidden": { "description": "Hide this subagent from the @ autocomplete menu (default: false, only applies to mode: subagent)", @@ -8771,10 +9487,15 @@ "properties": { "field": { "type": "string", - "enum": ["reasoning_content", "reasoning_details"] + "enum": [ + "reasoning_content", + "reasoning_details" + ] } }, - "required": ["field"], + "required": [ + "field" + ], "additionalProperties": false } ] @@ -8810,10 +9531,16 @@ "type": "number" } }, - "required": ["input", "output"] + "required": [ + "input", + "output" + ] } }, - "required": ["input", "output"] + "required": [ + "input", + "output" + ] }, "limit": { "type": "object", @@ -8825,7 +9552,10 @@ "type": "number" } }, - "required": ["context", "output"] + "required": [ + "context", + "output" + ] }, "modalities": { "type": "object", @@ -8834,25 +9564,44 @@ "type": "array", "items": { "type": "string", - "enum": ["text", "audio", "image", "video", "pdf"] + "enum": [ + "text", + "audio", + "image", + "video", + "pdf" + ] } }, "output": { "type": "array", "items": { "type": "string", - "enum": ["text", "audio", "image", "video", "pdf"] + "enum": [ + "text", + "audio", + "image", + "video", + "pdf" + ] } } }, - "required": ["input", "output"] + "required": [ + "input", + "output" + ] }, "experimental": { "type": "boolean" }, "status": { "type": "string", - "enum": ["alpha", "beta", "deprecated"] + "enum": [ + "alpha", + "beta", + "deprecated" + ] }, "options": { "type": "object", @@ -8877,7 +9626,9 @@ "type": "string" } }, - "required": ["npm"] + "required": [ + "npm" + ] }, "variants": { "description": "Variant-specific configuration", @@ -8986,7 +9737,10 @@ "maximum": 9007199254740991 } }, - "required": ["type", "command"], + "required": [ + "type", + "command" + ], "additionalProperties": false }, "McpOAuthConfig": { @@ -9052,13 +9806,19 @@ "maximum": 9007199254740991 } }, - "required": ["type", "url"], + "required": [ + "type", + "url" + ], "additionalProperties": false }, "LayoutConfig": { "description": "@deprecated Always uses stretch layout.", "type": "string", - "enum": ["auto", "stretch"] + "enum": [ + "auto", + "stretch" + ] }, "Config": { "type": "object", @@ -9095,12 +9855,17 @@ "type": "boolean" } }, - "required": ["enabled"] + "required": [ + "enabled" + ] }, "diff_style": { "description": "Control diff rendering style: 'auto' adapts to terminal width, 'stacked' always shows single column", "type": "string", - "enum": ["auto", "stacked"] + "enum": [ + "auto", + "stacked" + ] } } }, @@ -9132,7 +9897,9 @@ "type": "boolean" } }, - "required": ["template"] + "required": [ + "template" + ] } }, "watcher": { @@ -9158,7 +9925,11 @@ "share": { "description": "Control sharing behavior:'manual' allows manual sharing via commands, 'auto' enables automatic sharing, 'disabled' disables all sharing", "type": "string", - "enum": ["manual", "auto", "disabled"] + "enum": [ + "manual", + "auto", + "disabled" + ] }, "autoshare": { "description": "@deprecated Use 'share' field instead. Share newly created sessions automatically", @@ -9286,7 +10057,9 @@ "type": "boolean" } }, - "required": ["enabled"], + "required": [ + "enabled" + ], "additionalProperties": false } ] @@ -9356,7 +10129,9 @@ "const": true } }, - "required": ["disabled"] + "required": [ + "disabled" + ] }, { "type": "object", @@ -9393,7 +10168,9 @@ "additionalProperties": {} } }, - "required": ["command"] + "required": [ + "command" + ] } ] } @@ -9476,7 +10253,9 @@ } } }, - "required": ["command"] + "required": [ + "command" + ] } } }, @@ -9501,7 +10280,9 @@ } } }, - "required": ["command"] + "required": [ + "command" + ] } } } @@ -9560,7 +10341,11 @@ }, "parameters": {} }, - "required": ["id", "description", "parameters"] + "required": [ + "id", + "description", + "parameters" + ] }, "ToolList": { "type": "array", @@ -9587,7 +10372,13 @@ "type": "string" } }, - "required": ["home", "state", "config", "worktree", "directory"] + "required": [ + "home", + "state", + "config", + "worktree", + "directory" + ] }, "Worktree": { "type": "object", @@ -9602,7 +10393,11 @@ "type": "string" } }, - "required": ["name", "branch", "directory"] + "required": [ + "name", + "branch", + "directory" + ] }, "WorktreeCreateInput": { "type": "object", @@ -9622,7 +10417,9 @@ "type": "string" } }, - "required": ["branch"] + "required": [ + "branch" + ] }, "TextPartInput": { "type": "object", @@ -9653,7 +10450,9 @@ "type": "number" } }, - "required": ["start"] + "required": [ + "start" + ] }, "metadata": { "type": "object", @@ -9663,7 +10462,10 @@ "additionalProperties": {} } }, - "required": ["type", "text"] + "required": [ + "type", + "text" + ] }, "FilePartInput": { "type": "object", @@ -9688,7 +10490,11 @@ "$ref": "#/components/schemas/FilePartSource" } }, - "required": ["type", "mime", "url"] + "required": [ + "type", + "mime", + "url" + ] }, "AgentPartInput": { "type": "object", @@ -9720,10 +10526,17 @@ "maximum": 9007199254740991 } }, - "required": ["value", "start", "end"] + "required": [ + "value", + "start", + "end" + ] } }, - "required": ["type", "name"] + "required": [ + "type", + "name" + ] }, "SubtaskPartInput": { "type": "object", @@ -9748,7 +10561,12 @@ "type": "string" } }, - "required": ["type", "prompt", "description", "agent"] + "required": [ + "type", + "prompt", + "description", + "agent" + ] }, "Command": { "type": "object", @@ -9788,7 +10606,11 @@ } } }, - "required": ["name", "template", "hints"] + "required": [ + "name", + "template", + "hints" + ] }, "Model": { "type": "object", @@ -9812,7 +10634,11 @@ "type": "string" } }, - "required": ["id", "url", "npm"] + "required": [ + "id", + "url", + "npm" + ] }, "name": { "type": "string" @@ -9854,7 +10680,13 @@ "type": "boolean" } }, - "required": ["text", "audio", "image", "video", "pdf"] + "required": [ + "text", + "audio", + "image", + "video", + "pdf" + ] }, "output": { "type": "object", @@ -9875,7 +10707,13 @@ "type": "boolean" } }, - "required": ["text", "audio", "image", "video", "pdf"] + "required": [ + "text", + "audio", + "image", + "video", + "pdf" + ] }, "interleaved": { "anyOf": [ @@ -9887,15 +10725,28 @@ "properties": { "field": { "type": "string", - "enum": ["reasoning_content", "reasoning_details"] + "enum": [ + "reasoning_content", + "reasoning_details" + ] } }, - "required": ["field"] + "required": [ + "field" + ] } ] } }, - "required": ["temperature", "reasoning", "attachment", "toolcall", "input", "output", "interleaved"] + "required": [ + "temperature", + "reasoning", + "attachment", + "toolcall", + "input", + "output", + "interleaved" + ] }, "cost": { "type": "object", @@ -9916,7 +10767,10 @@ "type": "number" } }, - "required": ["read", "write"] + "required": [ + "read", + "write" + ] }, "experimentalOver200K": { "type": "object", @@ -9937,13 +10791,24 @@ "type": "number" } }, - "required": ["read", "write"] + "required": [ + "read", + "write" + ] } }, - "required": ["input", "output", "cache"] + "required": [ + "input", + "output", + "cache" + ] } }, - "required": ["input", "output", "cache"] + "required": [ + "input", + "output", + "cache" + ] }, "limit": { "type": "object", @@ -9955,11 +10820,19 @@ "type": "number" } }, - "required": ["context", "output"] + "required": [ + "context", + "output" + ] }, "status": { "type": "string", - "enum": ["alpha", "beta", "deprecated", "active"] + "enum": [ + "alpha", + "beta", + "deprecated", + "active" + ] }, "options": { "type": "object", @@ -10019,7 +10892,12 @@ }, "source": { "type": "string", - "enum": ["env", "config", "custom", "api"] + "enum": [ + "env", + "config", + "custom", + "api" + ] }, "env": { "type": "array", @@ -10047,7 +10925,14 @@ } } }, - "required": ["id", "name", "source", "env", "options", "models"] + "required": [ + "id", + "name", + "source", + "env", + "options", + "models" + ] }, "ProviderAuthMethod": { "type": "object", @@ -10068,7 +10953,10 @@ "type": "string" } }, - "required": ["type", "label"] + "required": [ + "type", + "label" + ] }, "ProviderAuthAuthorization": { "type": "object", @@ -10092,7 +10980,11 @@ "type": "string" } }, - "required": ["url", "method", "instructions"] + "required": [ + "url", + "method", + "instructions" + ] }, "Symbol": { "type": "object", @@ -10113,10 +11005,17 @@ "$ref": "#/components/schemas/Range" } }, - "required": ["uri", "range"] + "required": [ + "uri", + "range" + ] } }, - "required": ["name", "kind", "location"] + "required": [ + "name", + "kind", + "location" + ] }, "FileNode": { "type": "object", @@ -10132,13 +11031,22 @@ }, "type": { "type": "string", - "enum": ["file", "directory"] + "enum": [ + "file", + "directory" + ] }, "ignored": { "type": "boolean" } }, - "required": ["name", "path", "absolute", "type", "ignored"] + "required": [ + "name", + "path", + "absolute", + "type", + "ignored" + ] }, "FileContent": { "type": "object", @@ -10192,14 +11100,24 @@ } } }, - "required": ["oldStart", "oldLines", "newStart", "newLines", "lines"] + "required": [ + "oldStart", + "oldLines", + "newStart", + "newLines", + "lines" + ] } }, "index": { "type": "string" } }, - "required": ["oldFileName", "newFileName", "hunks"] + "required": [ + "oldFileName", + "newFileName", + "hunks" + ] }, "encoding": { "type": "string", @@ -10209,7 +11127,10 @@ "type": "string" } }, - "required": ["type", "content"] + "required": [ + "type", + "content" + ] }, "File": { "type": "object", @@ -10229,10 +11150,19 @@ }, "status": { "type": "string", - "enum": ["added", "deleted", "modified"] + "enum": [ + "added", + "deleted", + "modified" + ] } }, - "required": ["path", "added", "removed", "status"] + "required": [ + "path", + "added", + "removed", + "status" + ] }, "Agent": { "type": "object", @@ -10245,7 +11175,11 @@ }, "mode": { "type": "string", - "enum": ["subagent", "primary", "all"] + "enum": [ + "subagent", + "primary", + "all" + ] }, "native": { "type": "boolean" @@ -10275,7 +11209,10 @@ "type": "string" } }, - "required": ["modelID", "providerID"] + "required": [ + "modelID", + "providerID" + ] }, "prompt": { "type": "string" @@ -10293,7 +11230,12 @@ "maximum": 9007199254740991 } }, - "required": ["name", "mode", "permission", "options"] + "required": [ + "name", + "mode", + "permission", + "options" + ] }, "MCPStatusConnected": { "type": "object", @@ -10303,7 +11245,9 @@ "const": "connected" } }, - "required": ["status"] + "required": [ + "status" + ] }, "MCPStatusDisabled": { "type": "object", @@ -10313,7 +11257,9 @@ "const": "disabled" } }, - "required": ["status"] + "required": [ + "status" + ] }, "MCPStatusFailed": { "type": "object", @@ -10326,7 +11272,10 @@ "type": "string" } }, - "required": ["status", "error"] + "required": [ + "status", + "error" + ] }, "MCPStatusNeedsAuth": { "type": "object", @@ -10336,7 +11285,9 @@ "const": "needs_auth" } }, - "required": ["status"] + "required": [ + "status" + ] }, "MCPStatusNeedsClientRegistration": { "type": "object", @@ -10349,7 +11300,10 @@ "type": "string" } }, - "required": ["status", "error"] + "required": [ + "status", + "error" + ] }, "MCPStatus": { "anyOf": [ @@ -10389,7 +11343,11 @@ "type": "string" } }, - "required": ["name", "uri", "client"] + "required": [ + "name", + "uri", + "client" + ] }, "LSPStatus": { "type": "object", @@ -10416,7 +11374,12 @@ ] } }, - "required": ["id", "name", "root", "status"] + "required": [ + "id", + "name", + "root", + "status" + ] }, "FormatterStatus": { "type": "object", @@ -10434,7 +11397,11 @@ "type": "boolean" } }, - "required": ["name", "extensions", "enabled"] + "required": [ + "name", + "extensions", + "enabled" + ] }, "OAuth": { "type": "object", @@ -10456,7 +11423,12 @@ "type": "string" } }, - "required": ["type", "refresh", "access", "expires"] + "required": [ + "type", + "refresh", + "access", + "expires" + ] }, "ApiAuth": { "type": "object", @@ -10469,7 +11441,10 @@ "type": "string" } }, - "required": ["type", "key"] + "required": [ + "type", + "key" + ] }, "WellKnownAuth": { "type": "object", @@ -10485,7 +11460,11 @@ "type": "string" } }, - "required": ["type", "key", "token"] + "required": [ + "type", + "key", + "token" + ] }, "Auth": { "anyOf": [ @@ -10502,4 +11481,4 @@ } } } -} +}
\ No newline at end of file |
