Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,25 @@ jobs:
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run build

v2-smoke:
name: V2 Lifecycle Smoke
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run build
- name: Install OpenCode V2
run: npm install -g @opencode/cli@beta
- run: bun run smoke:v2
env:
OPENCODE_SMOKE_TIMEOUT_MS: "120000"
OPENCODE_SMOKE_ARTIFACTS_DIR: ${{ runner.temp }}/smoke-artifacts
- name: Upload smoke artifacts
if: failure()
uses: actions/upload-artifact@v4
with:
name: v2-smoke-artifacts
path: ${{ runner.temp }}/smoke-artifacts
if-no-files-found: ignore
16 changes: 16 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,28 @@ jobs:
- run: bun install --frozen-lockfile
- run: bun run test

v2-smoke:
name: V2 Lifecycle Smoke
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: oven-sh/setup-bun@v2
- run: bun install --frozen-lockfile
- run: bun run build
- name: Install OpenCode V2
run: npm install -g @opencode/cli@beta
- run: bun run smoke:v2
env:
OPENCODE_SMOKE_TIMEOUT_MS: "120000"

publish:
name: Publish to npm
runs-on: ubuntu-latest
needs:
- typecheck
- lint
- unit-tests
- v2-smoke
permissions:
contents: write
id-token: write
Expand Down Expand Up @@ -79,6 +94,7 @@ jobs:
- Typecheck passed.
- Lint passed.
- Unit tests passed.
- V2 lifecycle smoke passed against @opencode/cli@beta.
- Package published to npm.
EOF

Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This package is an OpenCode plugin with separate server and TUI entrypoints:

- `src/server.ts` is the server plugin. It registers the `/goal` command, goal tools, chat/session hooks, usage accounting, compaction context, and idle auto-continuation.
- `src/state.ts` owns goal persistence and lifecycle state. It stores JSON at `OPENCODE_GOAL_STATE_PATH` when set, otherwise under the user's OpenCode data location.
- `src/tui.tsx` is the Solid/OpenTUI sidebar and command-palette UI. It is exported as source, so avoid adding heavy runtime dependencies here unless there is a strong reason.
- `src/tui.ts` is the Solid/OpenTUI sidebar and command-palette UI. It is exported as source, so avoid adding heavy runtime dependencies here unless there is a strong reason. OpenTUI/solid are peer dependencies resolved from the host at runtime.
- `src/prompts.ts` contains the goal-mode continuation/system/compaction prompts.
- `test/` covers state, server hooks/tools, and TUI behavior with Bun tests.

Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ For manual installation, add the package to both V1 config files.

### OpenCode 2 Beta

Use this section only when running `opencode2`. Plugin release `0.1.30` and newer supports OpenCode 2 preview `0.0.0-next-17055` while remaining compatible with OpenCode 1.
Use this section only when running `opencode2`. Plugin releases from the `feat/v2-adaptation` line support OpenCode 2 beta `0.0.0-beta-19425` (the current `@opencode/cli@beta` / `@opencode/plugin@beta` contract) while remaining compatible with OpenCode 1.

Add the package to both V2 plugin lists:

Expand All @@ -105,7 +105,7 @@ Add the package to both V2 plugin lists:

OpenCode 2 does not read the V1 `tui.json` file. The server entrypoint comes from `opencode.json`, while the sidebar and palette integration come from `~/.config/opencode/cli.json`.

OpenCode 2 plugin APIs are still beta. This package pins its V2 development contract to the preview version above; later previews may require a compatible plugin update. V2 currently supports the goal command, tools, persistent state, usage accounting, idle continuation, Plan-mode safety, and TUI sidebar/palette integration. Goal-specific compaction context and recovery of already-running child sessions after a plugin restart remain V1-only because the current V2 plugin context does not expose equivalent hooks or history queries.
OpenCode 2 plugin APIs are still beta. This package pins its V2 development contract to the beta version above; later previews may require a compatible plugin update. V2 currently supports the goal command, tools, persistent state, usage accounting, idle continuation, Plan-mode safety, TUI sidebar/palette integration, goal compaction context, and transcript-based task recovery. Goal compaction context is injected through the V2 `session.compaction` hook on hosts that provide it (newer than beta-19425); on older betas the registration degrades to a no-op. After a plugin or server restart, V2 rebuilds Task-subagent deferral state by replaying each non-closed goal session's persisted transcript, because the V2 plugin context exposes no live child-session query; children that leave no finalized tool entry in the transcript are only observed through live events.

## Options

Expand Down Expand Up @@ -293,6 +293,6 @@ OpenCode plugin modules are target-specific. This package exports separate modul
}
```

Codex goal mode has deeper runtime integration for thread lifecycle control. This plugin implements the same workflow using OpenCode plugin hooks. Token usage is read from OpenCode step-finish usage when available and falls back to message token metadata or text estimation when exact usage is unavailable. Continuation is driven by V2 `session.execution.succeeded` events and legacy `session.idle` / `session.status` idle notifications, never by intermediate model-step completion. V2 execution starts arm busy tracking; native `session.retry.scheduled` events cancel plugin recovery while OpenCode retries. Terminal execution transport failures use bounded recovery, while interruptions (user, shutdown, or superseded) cancel local timers without starting another turn or charging a prompt failure. Interrupted or non-transport-failed executions remain suppressed until the host starts a new execution; this does not change the persisted goal status. Use `/pause_goal` for a durable pause. Each V2 plugin instance handles goal events only for its own location while still observing cross-location child task lifecycles. The optional `max_turn_time` watchdog can retry one goal continuation prompt when a model turn remains busy, without consuming the goal's auto-turn or no-progress budgets; recognized transport failures do count toward the prompt-failure ceiling. By default, continuation is deferred while OpenCode Task child sessions are active or their terminal result still needs an orchestrator turn, bounded by the `max_task_block_seconds` ceiling so an unobservable child cannot stall a goal indefinitely. During compaction, the plugin disables OpenCode's generic synthetic auto-continue while an active goal exists so the goal-specific continuation prompt remains authoritative.
Codex goal mode has deeper runtime integration for thread lifecycle control. This plugin implements the same workflow using OpenCode plugin hooks. Token usage is read from OpenCode step-finish usage when available and falls back to message token metadata or text estimation when exact usage is unavailable. Continuation is driven by V2 `session.execution.succeeded` events and legacy `session.idle` / `session.status` idle notifications, never by intermediate model-step completion. V2 execution starts arm busy tracking; native `session.retry.scheduled` events cancel plugin recovery while OpenCode retries. Terminal execution transport failures use bounded recovery, while interruptions (user, shutdown, or superseded) cancel local timers without starting another turn or charging a prompt failure. Interrupted or non-transport-failed executions remain suppressed until the host starts a new execution; this does not change the persisted goal status. Use `/pause_goal` for a durable pause. Each V2 plugin instance handles goal events only for its own location while still observing cross-location child task lifecycles. The optional `max_turn_time` watchdog can retry one goal continuation prompt when a model turn remains busy, without consuming the goal's auto-turn or no-progress budgets; recognized transport failures do count toward the prompt-failure ceiling. By default, continuation is deferred while OpenCode Task child sessions are active or their terminal result still needs an orchestrator turn, bounded by the `max_task_block_seconds` ceiling so an unobservable child cannot stall a goal indefinitely. During compaction on OpenCode 1, the plugin disables OpenCode's generic synthetic auto-continue while an active goal exists so the goal-specific continuation prompt remains authoritative; on OpenCode 2, compaction runs inside the session's execution flow, so the plugin instead injects the goal snapshot through the `session.compaction` hook where the host provides it.

The goal sidebar shows the current status, elapsed time, token usage, auto-continue count, latest checkpoint, latest status message, stop reason, and objective when a goal is active, paused, or safety-limited. Closed goals remain visible briefly through the latest tool state as achieved or unmet.
Loading
Loading