Skip to content

fix: single submit_plan with text/path auto-detect for OpenCode#333

Merged
backnotprop merged 4 commits into
mainfrom
fix/opencode-regressions
Mar 18, 2026
Merged

fix: single submit_plan with text/path auto-detect for OpenCode#333
backnotprop merged 4 commits into
mainfrom
fix/opencode-regressions

Conversation

@backnotprop
Copy link
Copy Markdown
Owner

@backnotprop backnotprop commented Mar 18, 2026

Summary

Collapses the two-tool approach (submit_plan + submit_plan_file) back into a single submit_plan(plan) that auto-detects whether the argument is markdown text or a file path, based on rcdailey's feedback that one tool is sufficient.

Provenance

Version State User sentiment
v0.8–v0.12 submit_plan(plan: string) — text-based, uniform across agents Happy: rcdailey contributed 3 PRs, sfpmld wanted more access, users filed enhancements not bugs
v0.13.0 (PR #318) submit_plan(path: string) — file-only, 80+ line prompt, TodoWrite warfare Broke: linxi-1214 blocked, ilmpc confirmed upstream OpenCode prompt change, rcdailey reported leaked file paths
v0.14.0 (PR #329) Emergency patches — permission overrides, more prompt stripping Partial fix: permission errors resolved, but agent still writes to repo root, TodoWrite replacements fragile
This PR submit_plan(plan) — text or path, one tool, ~25 line prompt Restores happy-state contract + adds file-based revision workflow

How it works

  1. First submission: Agent passes plan as markdown text → submit_plan(plan: "# My Plan\n..."). Simple, works from any agent.

  2. On deny: Response includes the history path where the plan was saved:

    YOUR PLAN WAS NOT APPROVED.
    Your plan is saved at: ~/.plannotator/history/myproject/auth-2026-03-18/001.md
    You can edit this file to make targeted changes, then pass its path to submit_plan.
    
  3. On revision: Agent edits the file with Edit tool (targeted changes, not full rewrite), then calls submit_plan(plan: "/path/to/plan.md"). Auto-detected as file path.

Auto-detection logic

function isFilePath(value: string): boolean {
  return path.isAbsolute(value) && value.endsWith(".md") && existsSync(value);
}

Plan markdown virtually never satisfies all three conditions (absolute path + .md extension + exists on disk).

What changed

  • apps/opencode-plugin/index.ts: Single tool, auto-detect, unified ~25 line prompt for all primary agents, removed TodoWrite warfare
  • packages/server/index.ts: Surface historyPath through waitForDecision() (the server already saved plans to history via saveToHistory() — just never returned the path)
  • packages/shared/feedback-templates.ts: Deny response includes file path hint when historyPath is provided
  • packages/shared/feedback-templates.test.ts: Updated test for new wording, added history path test

What's preserved

  • stripConflictingPlanModeRules() — still strips "STRICTLY FORBIDDEN" from system prompt
  • experimental.chat.messages.transform — still filters "STRICTLY FORBIDDEN" from user messages
  • plan_exit suppression via tool.definition hook
  • Per-agent .md permission override for plan agent
  • Agent switching on approval

Test plan

  • bun test apps/opencode-plugin/plan-mode.test.ts — 10 pass
  • bun test packages/shared/feedback-templates.test.ts — 6 pass
  • Manual: plan agent submits text → review UI → deny → response includes history path → agent edits file → resubmits path
  • Manual: Build agent can use submit_plan (uniform access)
  • Manual: first submission with text, revision with path, both work

Fixes #328

🤖 Generated with Claude Code

PR #318 replaced the original text-based submit_plan with a file-path-only
version and split prompt injection between plan/non-plan agents. This caused
regressions: the agent couldn't figure out file paths from non-plan agents,
and the 80+ line prompt with TodoWrite replacements was fragile against
OpenCode upstream changes.

This restores the original submit_plan(plan) that accepts markdown text
directly — the contract that worked uniformly across all agents — and keeps
the file-based workflow as submit_plan_file(path) for users who want
persistent plan files.

Key changes:
- Two tools: submit_plan (text) + submit_plan_file (path)
- Unified prompt for all primary agents (not just plan mode)
- Removed aggressive TodoWrite string replacements and system-reminder
- Kept adversarial stripping of OpenCode's STRICTLY FORBIDDEN rules
- Extracted shared server helpers to reduce duplication

Addresses #328

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Collapses submit_plan + submit_plan_file back into one tool that
auto-detects whether the argument is plan text or a file path.

First submission: agent passes markdown text (simple, works from any agent).
On deny: response includes the history path where the plan was saved, so the
agent can Edit the file for targeted revisions and resubmit with the path.

Key changes:
- One tool: submit_plan(plan) accepts text or absolute .md file path
- Server surfaces historyPath through waitForDecision (already saved by
  saveToHistory, just not returned before)
- Deny response includes file path hint for Edit-based revision workflow
- Unified prompt for all primary agents (~25 lines, no TodoWrite warfare)
- Still strips OpenCode's STRICTLY FORBIDDEN rules and suppresses plan_exit

Addresses #328 and rcdailey's feedback on PR #333

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@backnotprop backnotprop changed the title fix: restore uniform submit_plan + add submit_plan_file for OpenCode fix: single submit_plan with text/path auto-detect for OpenCode Mar 18, 2026
backnotprop and others added 2 commits March 18, 2026 14:32
…o-tier prompt

- Remove historyPath from deny flow — internal history directory should not
  be exposed to agents. Text submissions get text feedback; file submissions
  get file feedback. No crossover.
- Error when agent passes an absolute .md path that doesn't exist instead of
  silently treating it as plan text.
- Restore two-tier prompt: plan agent gets full planning instructions, other
  primary agents get a minimal reminder (matching pre-v0.13.0 behavior).
- Clean up stale prompt copy referencing historyPath-based revision flow.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…oisy logs

- Override todowrite description to defer to submit_plan during active planning
- Tool description now instructs agent to explore and ask questions before submitting
- Sequenced planning prompt: explore, ask, then write
- Remove success logs from integration saves (stderr was bleeding through)
- Append resubmit reminder to OpenCode deny feedback

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@backnotprop backnotprop merged commit d5b6bc7 into main Mar 18, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

submit_plan not appear after plan is finished

1 participant