You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+7Lines changed: 7 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -41,6 +41,7 @@ If you want reproducible installs instead of automatic plugin refreshes, pin an
41
41
- exposes a `plan_prompt` tool so the `plan` agent can reveal the plugin's prompt basis for customization
42
42
- exposes an `edit_plan` tool so the `plan` agent can open the current plan in the configured external editor
43
43
- uses `submit_plan` for review when available, otherwise falls back to external-editor review
44
+
- keeps the agent in planner mode if the plan file changed after `submit_plan`; the revised plan must be resubmitted before `plan_exit`
44
45
- can leave planner mode with `plan_exit` after approval when experimental plan mode is enabled in the CLI runtime
45
46
46
47
## Customize the plan agent
@@ -87,6 +88,10 @@ Example:
87
88
If submit_plan is unavailable, call edit_plan so I can review the plan in my editor.
88
89
```
89
90
91
+
If you want to reopen the same plan after an initial review pass, prompt the `plan` agent with something like `edit the plan again externally`. That will cause it to call `edit_plan` again and reopen the current plan in the configured editor.
92
+
93
+
When the editor closes, `edit_plan` compares the plan before and after editing. If nothing changed, it reports that no changes were made. If the user edited the plan, the tool returns the previous and updated plan content so the `plan` agent can treat that as review feedback, summarize the edits, and continue planning from the revised plan.
94
+
90
95
`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.
91
96
92
97
Compatible examples:
@@ -109,6 +114,8 @@ Examples:
109
114
110
115
If `edit_plan` fails, the `plan` agent should fall back to telling you the plan file path and asking for review in chat.
111
116
117
+
If you edit the plan after calling `submit_plan`, the plugin treats that as a new draft. In that case the agent should stay in planner mode and call `submit_plan` again before `plan_exit`.
118
+
112
119
## Auto-updates
113
120
114
121
OpenCode installs and updates npm plugins automatically. During the beta phase of this plugin, `opencode-planner@beta` gives the smoothest update path for most users.
Copy file name to clipboardExpand all lines: index.js
+104-4Lines changed: 104 additions & 4 deletions
Original file line number
Diff line number
Diff line change
@@ -1,3 +1,4 @@
1
+
import{createHash}from"node:crypto"
1
2
import{spawn}from"node:child_process"
2
3
import{readFile}from"node:fs/promises"
3
4
importpathfrom"path"
@@ -26,6 +27,7 @@ function reviewInstruction(target) {
26
27
return[
27
28
`When the plan is complete, if the submit_plan tool is available, use it to submit the plan for review.`,
28
29
`Otherwise, call edit_plan to open the markdown plan in the configured external editor for review. If edit_plan fails, tell the user the plan is ready at ${target} and ask for review in chat.`,
30
+
`If edit_plan reports that the user changed the plan externally, treat that as review feedback on the plan, summarize the changes, and continue planning from the revised plan.`,
29
31
].join(" ")
30
32
}
31
33
@@ -41,6 +43,7 @@ function agentPrompt(target = defaultPlanTarget) {
41
43
...(planExit
42
44
? [
43
45
"After approval, if the user or Plannotator says something like 'Proceed with implementation', call plan_exit to hand off back to implementation mode.",
46
+
"If the plan changes after submit_plan, stay in planner mode, update the plan as needed, and call submit_plan again before plan_exit.",
44
47
]
45
48
: []),
46
49
].join("\n\n")
@@ -89,6 +92,7 @@ function note(id) {
89
92
out.length-1,
90
93
0,
91
94
"If the user or Plannotator then says something like 'Proceed with implementation', call the plan_exit tool to leave planner mode.",
95
+
"If the plan changed after submit_plan, do not call plan_exit yet. Revise as needed and call submit_plan again first.",
thrownewError(`The plan file \`${target}\` does not exist yet. Finish writing the plan first.`)
@@ -191,8 +257,25 @@ async function editPlan(sessionID) {
191
257
throwerror
192
258
}
193
259
194
-
constrendered=content.trim() ? content : `The plan file \`${target}\` is empty.`
195
-
return[`The plan was edited in your external editor.`,`File: ${target}`,"",rendered].join("\n")
260
+
if(before===after){
261
+
return[
262
+
"The plan was reopened in your external editor. No changes were made.",
263
+
`File: ${target}`,
264
+
"",
265
+
formatPlanBlock("## Current plan",after,`The plan file \`${target}\` is empty.`),
266
+
].join("\n")
267
+
}
268
+
269
+
return[
270
+
"The user edited the plan externally.",
271
+
`File: ${target}`,
272
+
"",
273
+
"Treat these external edits as review feedback on the plan. Summarize what changed, continue planning from the updated plan, and if this plan was already reviewed with submit_plan, submit the revised plan again before plan_exit.",
274
+
"",
275
+
formatPlanBlock("## Previous plan",before,"_(The plan file did not exist before editing.)_"),
276
+
"",
277
+
formatPlanBlock("## Updated plan",after,`The plan file \`${target}\` is empty.`),
278
+
].join("\n")
196
279
}
197
280
198
281
functionmode(input={}){
@@ -249,6 +332,7 @@ function mode(input = {}) {
249
332
250
333
exportdefaultasyncfunctionplannerPlugin(){
251
334
constseen=newSet()
335
+
constsubmittedPlans=newMap()
252
336
253
337
return{
254
338
tool: {
@@ -289,6 +373,22 @@ export default async function plannerPlugin() {
"The plan has changed since the last submit_plan review. Stay in planner mode, update the plan as needed, and call submit_plan again before plan_exit.",
0 commit comments