Skip to content

Commit 8d28936

Browse files
committed
chore(release): publish 0.3.1
1 parent 8df9586 commit 8d28936

7 files changed

Lines changed: 236 additions & 9 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Changelog
22

3+
## 0.3.1
4+
5+
- add a `planner_config` diagnostic tool and `/planner-config` command for inspecting planner runtime and editor configuration
6+
37
## 0.3.0
48

59
- add an `/edit-plan` command that routes to the `plan` agent and reuses the existing `edit_plan` tool flow

README.md

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ If you want reproducible installs instead of automatic plugin refreshes, pin an
3737

3838
```json
3939
{
40-
"plugin": ["opencode-planner@0.3.0"]
40+
"plugin": ["opencode-planner@0.3.1"]
4141
}
4242
```
4343

@@ -49,9 +49,11 @@ If you want reproducible installs instead of automatic plugin refreshes, pin an
4949
- lets users replace the plugin's base `plan` prompt with their own `agent.plan.prompt`
5050
- lets users override agent settings such as `agent.plan.model` and provider-specific options like `agent.plan.reasoningEffort`
5151
- denies `submit_plan`, `edit_plan`, and `plan_exit` to the built-in `general` and `explore` subagents so review and implementation handoff stay on the primary `plan` agent
52+
- exposes a `planner_config` tool so the `plan` agent can inspect planner-specific runtime and editor configuration
5253
- exposes a `plan_prompt` tool so the `plan` agent can reveal the plugin's prompt basis for customization
5354
- exposes an `edit_plan` tool so the `plan` agent can open the current plan in the configured external editor
5455
- registers an `/edit-plan` command that routes to the `plan` agent and asks it to call `edit_plan`
56+
- registers a `/planner-config` command that routes to the `plan` agent and asks it to call `planner_config`
5557
- uses `submit_plan` for review when available, otherwise falls back to external-editor review
5658
- keeps the agent in planner mode if the plan file changed after `submit_plan`; the revised plan must be resubmitted before `plan_exit`
5759
- can leave planner mode with `plan_exit` after approval when experimental plan mode is enabled in the CLI runtime (because the plan_exit tool is only available with `EXPERIMENTAL_PLAN_MODE` enabled; se OpenCode docs for Experiments)
@@ -90,6 +92,30 @@ The tool returns:
9092
- the injected planner reminder, which is plugin-controlled runtime guidance and is not customized via `agent.plan.prompt`
9193
- a short note explaining that the final runtime prompt can still differ because of user config, other plugins, or runtime tool availability like `plan_exit`
9294

95+
## Diagnose planner configuration
96+
97+
The plugin also adds a read-only `planner_config` tool. Use it when you want to inspect planner-specific configuration, especially editor selection precedence across `PLAN_VISUAL`, `VISUAL`, and `EDITOR`.
98+
99+
In the TUI, `/planner-config` is the shortcut for this diagnostic flow.
100+
101+
Example:
102+
103+
```text
104+
/planner-config
105+
```
106+
107+
The output includes:
108+
109+
- the current session plan path
110+
- planner tool availability from the plugin's perspective
111+
- whether `submit_plan` is available for Plannotator review and `edit_plan` is available as the local-editor fallback
112+
- editor precedence: `PLAN_VISUAL` -> `VISUAL` -> `EDITOR`
113+
- which editor variable won
114+
- the resolved editor command
115+
- relevant runtime flags that affect planner behavior, such as `OPENCODE_EXPERIMENTAL_PLAN_MODE` and `OPENCODE_CLIENT`
116+
117+
This is the quickest way to understand why `edit_plan` is using a specific editor command before you try `/edit-plan`.
118+
93119
## Review Without Plannotator
94120

95121
In the TUI, you can use `/edit-plan` as a shortcut to ask the `plan` agent to reopen the current plan in your configured external editor. This routes through the existing `edit_plan` tool behavior.
@@ -161,7 +187,7 @@ npm run debug:plan
161187
npm run opencode:no-plannotator -- debug config
162188
```
163189

164-
`npm run debug:plan` checks the active OpenCode runtime and reports whether the local repo plugin is loaded, whether `plan_prompt`, `edit_plan`, `submit_plan`, and `plan_exit` are allowed by the `plan` agent, and whether they are actually registered as runtime tools.
190+
`npm run debug:plan` checks the active OpenCode runtime and reports whether the local repo plugin is loaded, whether `planner_config`, `plan_prompt`, `edit_plan`, `submit_plan`, and `plan_exit` are allowed by the `plan` agent, and whether they are actually registered as runtime tools.
165191

166192
This is the fastest way to distinguish:
167193

@@ -181,7 +207,7 @@ It starts OpenCode with an isolated temporary home/config, keeps the local repo
181207
1. Update `CHANGELOG.md`.
182208
2. Bump the version in `package.json`.
183209
3. Commit the release.
184-
4. Create and push a git tag like `v0.3.0` for the release.
210+
4. Create and push a git tag like `v0.3.1` for the release.
185211
5. Let GitHub Actions publish to npm `latest`.
186212
6. Publish matching GitHub release notes.
187213

@@ -198,7 +224,7 @@ Configure npm Trusted Publishing for this package:
198224
- Repository: `opencode-planner`
199225
- Workflow filename: `release.yml`
200226

201-
The release workflow publishes stable tags like `v0.3.0` to npm `latest` and creates matching GitHub release notes automatically.
227+
The release workflow publishes stable tags like `v0.3.1` to npm `latest` and creates matching GitHub release notes automatically.
202228

203229
Trusted Publishing uses GitHub OIDC and does not require an `NPM_TOKEN` secret for publishing.
204230

index.js

Lines changed: 73 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ const editPlanCommand = {
1313
template:
1414
"Reopen the current markdown plan in the configured external editor by calling the edit_plan tool. If the tool reports that the user changed the plan externally, treat those edits as review feedback, summarize what changed, and continue planning from the updated plan.",
1515
}
16+
const plannerConfigCommand = {
17+
description: "Show planner configuration details",
18+
agent,
19+
template:
20+
"Call the planner_config tool for the current session and return its output so the user can inspect planner tool availability, editor resolution, and relevant runtime flags.",
21+
}
1622

1723
function truthy(key) {
1824
const value = process.env[key]?.toLowerCase()
@@ -136,14 +142,38 @@ function restrictPlannerSubagent(input = {}) {
136142
...input,
137143
permission: merge(input?.permission, {
138144
edit_plan: "deny",
145+
planner_config: "deny",
139146
plan_exit: "deny",
140147
submit_plan: "deny",
141148
}),
142149
}
143150
}
144151

152+
function editorConfig() {
153+
const variables = ["PLAN_VISUAL", "VISUAL", "EDITOR"].map((key) => {
154+
const value = process.env[key]?.trim() ?? ""
155+
return {
156+
key,
157+
value,
158+
set: Boolean(value),
159+
}
160+
})
161+
162+
const selected = variables.find((entry) => entry.set) ?? null
163+
164+
return {
165+
variables,
166+
selected,
167+
command: selected?.value ?? "",
168+
}
169+
}
170+
145171
function editorCommand() {
146-
return process.env.PLAN_VISUAL?.trim() || process.env.VISUAL?.trim() || process.env.EDITOR?.trim() || ""
172+
return editorConfig().command
173+
}
174+
175+
function formatSetting(value) {
176+
return value ? `\`${value}\`` : "<unset>"
147177
}
148178

149179
function hashPlan(content) {
@@ -284,6 +314,39 @@ async function editPlan(sessionID) {
284314
].join("\n")
285315
}
286316

317+
function plannerConfig(sessionID) {
318+
const target = file(sessionID ?? "<session-id>")
319+
const permission = mode().permission
320+
const editor = editorConfig()
321+
const planExitEnabled = hasPlanExit()
322+
323+
return [
324+
"# opencode-planner configuration",
325+
"## Planner files",
326+
`- Current session plan path: \`${target}\``,
327+
`- Default plan path pattern: \`${defaultPlanTarget}\``,
328+
"",
329+
"## Planner tools",
330+
`- plan_prompt: ${permission.plan_prompt === "allow" ? "allowed by the `plan` agent" : "not allowed by the `plan` agent"}`,
331+
`- edit_plan: ${permission.edit_plan === "allow" ? "allowed by the `plan` agent as the fallback local-editor review tool" : "not allowed by the `plan` agent"}`,
332+
`- planner_config: ${permission.planner_config === "allow" ? "allowed by the `plan` agent" : "not allowed by the `plan` agent"}`,
333+
`- submit_plan: ${permission.submit_plan === "allow" ? "allowed by the `plan` agent and required for Plannotator review; availability still depends on the host runtime" : "not allowed by the `plan` agent"}`,
334+
`- plan_exit: ${planExitEnabled ? "enabled by the current runtime flags when the host runtime provides it" : "not enabled by the current runtime flags"}`,
335+
"",
336+
"## Editor resolution",
337+
"- Precedence: `PLAN_VISUAL` -> `VISUAL` -> `EDITOR`",
338+
...editor.variables.map((entry) => `- ${entry.key}: ${formatSetting(entry.value)}`),
339+
`- Selected source: ${editor.selected ? `\`${editor.selected.key}\`` : "none"}`,
340+
`- Selected command: ${formatSetting(editor.command)}`,
341+
"",
342+
"## Runtime flags",
343+
`- OPENCODE_EXPERIMENTAL: ${formatSetting(process.env.OPENCODE_EXPERIMENTAL?.trim() ?? "")}`,
344+
`- OPENCODE_EXPERIMENTAL_PLAN_MODE: ${formatSetting(process.env.OPENCODE_EXPERIMENTAL_PLAN_MODE?.trim() ?? "")}`,
345+
`- OPENCODE_CLIENT: ${formatSetting(process.env.OPENCODE_CLIENT?.trim() ?? "")}`,
346+
`- plan_exit expected: ${planExitEnabled ? "yes" : "no"}`,
347+
].join("\n")
348+
}
349+
287350
function mode(input = {}) {
288351
const base = {
289352
mode: "primary",
@@ -311,6 +374,7 @@ function mode(input = {}) {
311374
codesearch: "allow",
312375
batch: "allow",
313376
edit_plan: "allow",
377+
planner_config: "allow",
314378
plan_prompt: "allow",
315379
submit_plan: "allow",
316380
...(hasPlanExit() ? { plan_exit: "allow" } : {}),
@@ -356,10 +420,18 @@ export default async function plannerPlugin() {
356420
return editPlan(context.sessionID)
357421
},
358422
},
423+
planner_config: {
424+
description: "Show planner configuration details for the current session",
425+
args: {},
426+
async execute(_, context) {
427+
return plannerConfig(context.sessionID)
428+
},
429+
},
359430
},
360431
async config(cfg) {
361432
cfg.agent ??= {}
362433
cfg.command = {
434+
"planner-config": plannerConfigCommand,
363435
"edit-plan": editPlanCommand,
364436
...cfg.command,
365437
}

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "opencode-planner",
3-
"version": "0.3.0",
3+
"version": "0.3.1",
44
"description": "Experimental OpenCode plugin that adds a dedicated planning agent with read-only planning constraints.",
55
"type": "module",
66
"author": "Tim Richardson",

scripts/debug-plan-runtime.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,12 +42,15 @@ const tools = plan.tools ?? {}
4242
const prompt = plan.prompt ?? ""
4343

4444
const editPlanCommandConfigured = Boolean(commands["edit-plan"])
45+
const plannerConfigCommandConfigured = Boolean(commands["planner-config"])
4546
const planPromptAllowed = hasAllowedPermission("plan_prompt", permissions)
4647
const editPlanAllowed = hasAllowedPermission("edit_plan", permissions)
48+
const plannerConfigAllowed = hasAllowedPermission("planner_config", permissions)
4749
const planExitAllowed = hasAllowedPermission("plan_exit", permissions)
4850
const submitPlanAllowed = hasAllowedPermission("submit_plan", permissions)
4951
const planPromptTool = Boolean(tools.plan_prompt)
5052
const editPlanTool = Boolean(tools.edit_plan)
53+
const plannerConfigTool = Boolean(tools.planner_config)
5154
const planExitTool = Boolean(tools.plan_exit)
5255
const submitPlanTool = Boolean(tools.submit_plan)
5356
const usingLocalPlugin = plugins.includes(localPlugin)
@@ -57,10 +60,13 @@ console.log("OpenCode plan runtime check")
5760
console.log("")
5861
line("Repo plugin loaded", usingLocalPlugin ? "yes" : "no")
5962
line("/edit-plan command", editPlanCommandConfigured ? "yes" : "no")
63+
line("/planner-config command", plannerConfigCommandConfigured ? "yes" : "no")
6064
line("plan_prompt allowed", planPromptAllowed ? "yes" : "no")
6165
line("plan_prompt tool", planPromptTool ? "yes" : "no")
6266
line("edit_plan allowed", editPlanAllowed ? "yes" : "no")
6367
line("edit_plan tool", editPlanTool ? "yes" : "no")
68+
line("planner_config allowed", plannerConfigAllowed ? "yes" : "no")
69+
line("planner_config tool", plannerConfigTool ? "yes" : "no")
6470
line("submit_plan allowed", submitPlanAllowed ? "yes" : "no")
6571
line("plan_exit allowed", planExitAllowed ? "yes" : "no")
6672
line("submit_plan tool", submitPlanTool ? "yes" : "no")
@@ -84,12 +90,18 @@ if (!usingLocalPlugin) {
8490
if (!editPlanCommandConfigured) {
8591
console.log("- /edit-plan is not configured in the resolved command list.")
8692
}
93+
if (!plannerConfigCommandConfigured) {
94+
console.log("- /planner-config is not configured in the resolved command list.")
95+
}
8796
if (!planPromptTool) {
8897
console.log("- plan_prompt is not registered as a runtime tool.")
8998
}
9099
if (!editPlanTool) {
91100
console.log("- edit_plan is not registered as a runtime tool.")
92101
}
102+
if (!plannerConfigTool) {
103+
console.log("- planner_config is not registered as a runtime tool.")
104+
}
93105
if (!submitPlanTool) {
94106
console.log("- submit_plan is not registered as a runtime tool.")
95107
}

0 commit comments

Comments
 (0)