Open-source project
prevalentWare/opencode-goal-plugin avatar
prevalentWare/opencode-goal-plugin

opencode-goal-plugin: persistent goal mode for OpenCode agents

OpenCode goal plugin for Codex-style goal mode, /goal slash commands, persistent objectives, and AI coding agent focus.

371 stars31 forksTypeScriptMIT

At a glance

What is it?
A TypeScript plugin that adds Codex-style /goal commands, per-session goal state and optional idle auto-continuation to OpenCode. The interesting part is not the slash command, it is the evidence rule that gates goal closure and the budget and no-progress safeguards around automatic turns.
Who is it for?
Adopt it if you already run OpenCode and keep losing the thread across long refactors, migrations or test-fixing sessions, and you want the goal to survive compaction and idle gaps rather than living in your scrollback. Skip it if you are on OpenCode 2 beta and depend on goal-specific compaction context or on recovery of already-running child sessions after a plugin restart, because the README states both are V1-only.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 1 day ago.
What is it written in?
Mainly TypeScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.

DEEP OPEN-SOURCE ANALYSIS

The problem: an OpenCode session forgets what it was doing

An OpenCode session is a conversation. The objective lives in the prompt history, which means it competes for attention with every later message, and it is the first thing lost when the session is summarized. The README frames the target workflow as making OpenCode behave "more like a goal-driven coding agent instead of a one-prompt assistant", and lists long refactors, migrations, reviews and test-fixing sessions as the cases it was built for. That is a fair description of the failure mode: the agent is not short of capability, it is short of a durable statement of what done means.

The plugin's answer is to promote the objective to a first-class object with its own lifecycle. A goal is created, persisted per session, displayed, and closed only through an explicit transition. The audience is narrow and identifiable: people already running OpenCode who want a single tracked objective rather than a queue of prompts. If you use a different coding agent, nothing here transfers, because the whole thing is an OpenCode plugin with OpenCode config keys.

What the plugin actually adds to a session

Three command surfaces: `/goal <objective>`, `/pause_goal` and `/resume_goal`. The README notes these are exposed through the server command catalog, which is why they appear in the TUI, the desktop app, the web surface and remote integrations rather than only in one client. Alongside the commands there is a sidebar indicator showing status, elapsed time and the objective text.

The agent-facing side is a set of tools: `get_goal`, `get_goal_history`, `list_all_goals`, `create_goal`, `set_goal`, `update_goal_objective`, `update_goal_status`, `update_goal` and `clear_goal`. That split matters. The human uses slash commands, the model uses tools, and both read and write the same per-session state. State is stored with history and checkpoints, and the README states the files are written with owner-only permissions. That last detail is a deliberate choice: goal objectives are free text you typed, and they can contain paths, ticket references or internal context you would not want world-readable on a shared machine.

The evidence rule is the real design decision

Most goal features in coding agents are a sticky note. This one puts a gate on the exit. According to the README, closing a goal as `complete` requires verified evidence, and closing it as `unmet` requires a concrete blocker. The model cannot simply declare victory; it has to supply something that supports the claim, or name what stopped it.

That is a stronger constraint than it first appears, because it changes what the agent does near the end of a task. Instead of summarizing progress and stopping, it has to produce a closing artifact. The cost is friction: a goal that is genuinely finished but whose evidence is awkward to express will sit open, and the agent may spend turns assembling proof rather than moving on. The benefit is that "done" stops being a matter of tone. Whether the evidence check is strict enough to be useful in practice is not something the README quantifies, and I have not run it, so treat the mechanism as documented rather than demonstrated.

Idle continuation and the safeguards wrapped around it

The plugin can send the next goal prompt automatically when the session goes idle, hooked on `session.idle` and `session.status`. Automatic turns are the part most likely to burn money, so the options list is mostly limits. `max_auto_turns` defaults to 25. `min_continue_interval_seconds` defaults to 3. `max_turn_time` defaults to 300 seconds. `default_token_budget` defaults to 200000 and `max_goal_duration_seconds` defaults to 1800, after which the plugin performs a budget wrap-up rather than continuing indefinitely.

There is also a no-progress detector: `no_progress_token_threshold` defaults to 50 and `max_no_progress_turns` defaults to 2, after which the goal pauses instead of looping. That combination is the honest part of the design. An agent that keeps producing tokens while making no progress is the classic failure of unattended loops, and the plugin treats it as a pause condition rather than something to push through.

Task deferral is the subtlest piece. With `defer_while_tasks_active` at its default of `true`, continuation waits for active OpenCode Task child sessions and their orchestrator reconciliation before sending the next goal prompt. The README is explicit that a deferral re-checks child sessions on a short timer, so a goal deferred by a task does not depend on a further idle event to resume. `max_task_block_seconds` defaults to 900 and caps how long one child session may hold things up, including the case where a child stays listed but never reports a terminal state. Set it to `0` to remove the ceiling. If your subagents routinely run longer than fifteen minutes, the default ceiling will cut them off as a deferral source, which is a configuration mismatch rather than a bug.

Plan mode is treated as a boundary, not a suggestion

Goals created from the `plan` agent stay paused, and the README states that auto-continue never escapes a Plan-mode session or switches agents on its own. Two options control this: `restricted_agents` defaults to `["plan"]`, and `allow_goal_execution_from_plan` defaults to `false`. Both defaults are the safe ones, and both are the ones to leave alone unless you have a specific reason.

The reason this deserves its own section is that it is the only place in the material where the plugin draws a hard line about what an autonomous loop may do. Everything else is a budget or a timer, which are soft limits that expire and let work continue. Plan mode is different: the goal is created and then deliberately not executed. If your workflow assumes that setting a goal from plan mode will start work, it will not, and the goal will sit paused until you resume it.

Installing it, and why the config format matters

The README splits installation by CLI, and warns against mixing the formats. OpenCode 1 uses `plugin` and `tui.json`; OpenCode 2 uses `plugins` and the global `cli.json`. Identify which you have by running `opencode --version` and checking whether it prints `1.x`, or by noting that you invoke `opencode2`.

For OpenCode 1, the one-liner is `opencode plugin @prevalentware/opencode-goal-plugin`, or `opencode plugin -g @prevalentware/opencode-goal-plugin` for a global install. The README states OpenCode detects both package entrypoints and writes the plugin into the server and TUI config targets. Manual installation means adding `"plugin": ["@prevalentware/opencode-goal-plugin"]` to both `opencode.json` and `tui.json`. Missing the second file is the obvious way to end up with a working command and no sidebar indicator.

For OpenCode 2 beta, add the package to `plugins` in `opencode.json` and to `plugins` in `~/.config/opencode/cli.json`. The README notes that OpenCode 2 does not read the V1 `tui.json`, and that the server entrypoint comes from `opencode.json` while sidebar and palette integration come from the global `cli.json`. Server options in V1 use the package-and-options tuple, an array of package name plus an options object; V2 uses the object form with `package` and `options` keys. Those two shapes are not interchangeable.

Where it stops working: OpenCode 2 beta and the V1-only features

The README is unusually direct about this. OpenCode 2 plugin APIs are still beta, and the package pins its V2 development contract to preview `0.0.0-next-17055`, with the warning that later previews may require a compatible plugin update. Plugin release `0.1.30` and newer supports that preview while remaining compatible with OpenCode 1.

The functional gap is more specific. V2 currently supports the goal command, tools, persistent state, usage accounting, idle continuation, Plan-mode safety and TUI sidebar and palette integration. Goal-specific compaction context and recovery of already-running child sessions after a plugin restart remain V1-only, because the README states the current V2 plugin context does not expose equivalent hooks or history queries. So the two features most tied to long unattended runs, surviving compaction and picking up child sessions after a restart, are exactly the ones missing on the beta line. If you are on `opencode2` and your goals outlive a session summary, this is the wrong tool for now. On OpenCode 1 the same caveat does not apply, and the plugin is the more complete version.

A second limitation is structural rather than versioned: this is a plugin, not a scheduler. It keeps one session pointed at one objective. It does not coordinate goals across sessions, and `list_all_goals` is described as a tool the agent can call, not a cross-session dashboard. `max_objective_chars` defaults to 100000, which is generous enough that the practical limit on objective size is your own patience for writing it.

How this differs from letting the agent plan its own steps

The nearest alternative is not another plugin, it is the built-in pattern: give the agent a task, let it write a todo list, and re-prompt it when it stops. OpenCode already supports that, and it costs nothing to set up. The difference is where the objective lives. A todo list is a plan the agent produced and can revise; a goal is a statement you set and the agent must close with evidence or a blocker. The first adapts to what the agent discovers, the second holds it to what you asked for.

That trade favors the plugin when the objective is fixed and the path is not, which is the shape of a migration or a test-fixing session. It favors the todo-list approach when the objective itself is expected to change as you learn, because a goal you keep rewriting with `update_goal_objective` is just a todo list with extra state files. There is no third option in the material: the plugin does not offer a lighter mode where goals are advisory rather than gated, so the evidence rule is not optional once you use it.

Maintenance, release cadence and the MIT licence

The release history shows v0.1.48 and v0.1.47 published within minutes of each other on 2026-09-07, with v0.1.46 two days earlier. A rapid patch cadence at a 0.1.x version number is worth reading as a signal about stability expectations: the API surface and the OpenCode 2 contract are still moving. Pinning a version and reading the release notes before upgrading is the practical response, particularly if you are on the V2 preview, where the README itself warns that a later preview may need a plugin update.

The package is MIT licensed, which permits commercial and private use, modification and redistribution with the licence and copyright notice retained. That is the whole of what the licence identifier tells you; it says nothing about whether the plugin is suitable for your workflow, and nothing here should be read as legal advice. The upgrade cost is mostly configuration drift: V1 and V2 use different file names and different option shapes, so moving between them is a rewrite of your plugin block rather than a version bump.

Editorial conclusion

Adopt it if you already run OpenCode and keep losing the thread across long refactors, migrations or test-fixing sessions, and you want the goal to survive compaction and idle gaps rather than living in your scrollback. Skip it if you are on OpenCode 2 beta and depend on goal-specific compaction context or on recovery of already-running child sessions after a plugin restart, because the README states both are V1-only. Before rolling it out, verify three things against your own setup: that `opencode --version` matches the config format you are about to edit, that `restricted_agents` still contains `plan` with `allow_goal_execution_from_plan` left at `false`, and that `max_auto_turns` and `default_token_budget` are set to numbers you would accept if the session kept going unattended.

Official sources

  1. License: MIT
  2. prevalentWare/opencode-goal-plugin on GitHub
  3. Project website
  4. README
  5. Releases
Community notes

Community notes