From dae84b50652fc57831c3fee50334b8396b12fa43 Mon Sep 17 00:00:00 2001 From: Ariane Emory Date: Sat, 31 Jan 2026 00:31:26 -0500 Subject: [PATCH] feat: add experimental.plan_mode config option Allow enabling experimental plan mode via config file using experimental.plan_mode property, equivalent to setting OPENCODE_EXPERIMENTAL_PLAN_MODE environment variable. The environment variable takes precedence if both are set. --- packages/opencode/src/config/config.ts | 8 ++++++++ packages/opencode/src/session/prompt.ts | 3 ++- packages/opencode/src/tool/registry.ts | 2 +- 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/packages/opencode/src/config/config.ts b/packages/opencode/src/config/config.ts index 7969e307957..8f3104ee807 100644 --- a/packages/opencode/src/config/config.ts +++ b/packages/opencode/src/config/config.ts @@ -1095,6 +1095,7 @@ export namespace Config { .positive() .optional() .describe("Timeout in milliseconds for model context protocol (MCP) requests"), + plan_mode: z.boolean().optional().describe("Enable experimental plan mode"), }) .optional(), }) @@ -1268,6 +1269,13 @@ export namespace Config { return state().then((x) => x.config) } + export async function experimentalPlanMode() { + // Environment variable takes precedence + if (Flag.OPENCODE_EXPERIMENTAL_PLAN_MODE) return true + const config = await get() + return config.experimental?.plan_mode === true + } + export async function getGlobal() { return global() } diff --git a/packages/opencode/src/session/prompt.ts b/packages/opencode/src/session/prompt.ts index 94eabdef7f4..290de1b481d 100644 --- a/packages/opencode/src/session/prompt.ts +++ b/packages/opencode/src/session/prompt.ts @@ -34,6 +34,7 @@ import { spawn } from "child_process" import { Command } from "../command" import { $, fileURLToPath } from "bun" import { ConfigMarkdown } from "../config/markdown" +import { Config } from "../config/config" import { SessionSummary } from "./summary" import { NamedError } from "@opencode-ai/util/error" import { fn } from "@/util/fn" @@ -1202,7 +1203,7 @@ export namespace SessionPrompt { if (!userMessage) return input.messages // Original logic when experimental plan mode is disabled - if (!Flag.OPENCODE_EXPERIMENTAL_PLAN_MODE) { + if (!(await Config.experimentalPlanMode())) { if (input.agent.name === "plan") { userMessage.parts.push({ id: Identifier.ascending("part"), diff --git a/packages/opencode/src/tool/registry.ts b/packages/opencode/src/tool/registry.ts index 7b3a4588972..acb2ec02804 100644 --- a/packages/opencode/src/tool/registry.ts +++ b/packages/opencode/src/tool/registry.ts @@ -117,7 +117,7 @@ export namespace ToolRegistry { ApplyPatchTool, ...(Flag.OPENCODE_EXPERIMENTAL_LSP_TOOL ? [LspTool] : []), ...(config.experimental?.batch_tool === true ? [BatchTool] : []), - ...(Flag.OPENCODE_EXPERIMENTAL_PLAN_MODE && Flag.OPENCODE_CLIENT === "cli" ? [PlanExitTool, PlanEnterTool] : []), + ...((await Config.experimentalPlanMode()) && Flag.OPENCODE_CLIENT === "cli" ? [PlanExitTool, PlanEnterTool] : []), ...custom, ] }