Skip to content

Commit 2705e19

Browse files
committed
feat: support PLAN_VISUAL override for plan review
1 parent f37ffa4 commit 2705e19

3 files changed

Lines changed: 38 additions & 5 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,11 @@ Example:
8686
If submit_plan is unavailable, call edit_plan so I can review the plan in my editor.
8787
```
8888

89-
`edit_plan` uses `VISUAL` first, then `EDITOR`. The command must launch a separate process and block until editing is complete.
89+
`edit_plan` uses `PLAN_VISUAL` first, then `VISUAL`, then `EDITOR`. `PLAN_VISUAL` is useful when you want planner review to use a different editor from the rest of your shell tools. The command must launch a separate process and block until editing is complete.
9090

9191
Compatible examples:
9292

93+
- `PLAN_VISUAL="gvim -f"`
9394
- `VISUAL="gvim -f"`
9495
- `EDITOR="gedit --wait"`
9596
- `EDITOR="kate --block"`

index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,14 +133,14 @@ function restrictPlannerSubagent(input = {}) {
133133
}
134134

135135
function editorCommand() {
136-
return process.env.VISUAL?.trim() || process.env.EDITOR?.trim() || ""
136+
return process.env.PLAN_VISUAL?.trim() || process.env.VISUAL?.trim() || process.env.EDITOR?.trim() || ""
137137
}
138138

139139
function runEditor(target) {
140140
const editor = editorCommand()
141141
if (!editor) {
142142
throw new Error(
143-
"Neither `VISUAL` nor `EDITOR` is set, so edit_plan cannot open the plan. Configure a blocking editor command such as `code --wait`, or a terminal launcher that opens your editor in a separate window and waits.",
143+
"None of `PLAN_VISUAL`, `VISUAL`, or `EDITOR` is set, so edit_plan cannot open the plan. Configure a blocking editor command such as `code --wait`, or a terminal launcher that opens your editor in a separate window and waits.",
144144
)
145145
}
146146

@@ -168,7 +168,7 @@ function runEditor(target) {
168168
const suffix = detail ? `: ${detail}` : ""
169169
reject(
170170
new Error(
171-
`The external editor command exited with status ${code}${suffix}. Configure VISUAL or EDITOR to launch a separate process that waits until editing is complete.`,
171+
`The external editor command exited with status ${code}${suffix}. Configure PLAN_VISUAL, VISUAL, or EDITOR to launch a separate process that waits until editing is complete.`,
172172
),
173173
)
174174
})

test/plugin.test.js

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ import plannerPlugin from "../index.js"
66

77
async function withEnv(env, fn) {
88
const previous = {
9+
PLAN_VISUAL: process.env.PLAN_VISUAL,
10+
VISUAL: process.env.VISUAL,
11+
EDITOR: process.env.EDITOR,
912
OPENCODE_EXPERIMENTAL: process.env.OPENCODE_EXPERIMENTAL,
1013
OPENCODE_EXPERIMENTAL_PLAN_MODE: process.env.OPENCODE_EXPERIMENTAL_PLAN_MODE,
1114
OPENCODE_CLIENT: process.env.OPENCODE_CLIENT,
@@ -159,6 +162,7 @@ test("config hook denies review handoff tools for planner subagents", async () =
159162
test("edit_plan opens the current session plan in the configured editor", async () => {
160163
await withEnv(
161164
{
165+
PLAN_VISUAL: undefined,
162166
VISUAL: "true",
163167
EDITOR: "false",
164168
},
@@ -183,9 +187,37 @@ test("edit_plan opens the current session plan in the configured editor", async
183187
)
184188
})
185189

190+
test("edit_plan prefers PLAN_VISUAL over VISUAL and EDITOR", async () => {
191+
await withEnv(
192+
{
193+
PLAN_VISUAL: "true",
194+
VISUAL: "false",
195+
EDITOR: "false",
196+
},
197+
async () => {
198+
await withPlanFile(
199+
".opencode/plans/ses_edit_override.md",
200+
"# Edited with PLAN_VISUAL\n",
201+
async () => {
202+
const plugin = await plannerPlugin()
203+
const output = await plugin.tool.edit_plan.execute(
204+
{},
205+
{
206+
sessionID: "ses_edit_override",
207+
},
208+
)
209+
210+
assert.match(output, /# Edited with PLAN_VISUAL/)
211+
},
212+
)
213+
},
214+
)
215+
})
216+
186217
test("edit_plan reports when no blocking editor command is configured", async () => {
187218
await withEnv(
188219
{
220+
PLAN_VISUAL: undefined,
189221
VISUAL: undefined,
190222
EDITOR: undefined,
191223
},
@@ -198,7 +230,7 @@ test("edit_plan reports when no blocking editor command is configured", async ()
198230
sessionID: "ses_edit",
199231
},
200232
),
201-
/Neither `VISUAL` nor `EDITOR` is set/i,
233+
/None of `PLAN_VISUAL`, `VISUAL`, or `EDITOR` is set/i,
202234
)
203235
},
204236
)

0 commit comments

Comments
 (0)