Skip to content
Merged
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
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@ include the full version, for example `## 0.7.0-beta.1`.

### Fixed

- Restore compatibility with OpenCode 2.0.6: update the pinned SDKs, discover
services through `/api/info`, refresh owner activity with `session.update`,
and interrupt sessions with `resume: false`. Replace the removed headless
activation command with location-scoped `plugin.list` and document validation.

- Honor formal approvals for the exact verified PR commit even when publication
or description recovery finishes later. Retain review revocation, authorization,
and merge-readiness checks; keep timestamp gating for unbound merge comments.
Expand Down
12 changes: 9 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ titles, and can merge after an authorized approval. The TUI is optional.

## Requirements

- OpenCode **2** with a working model; tested with `0.0.0-beta-19398`.
- OpenCode **2.0.6** with a working model; client/plugin SDK pinned to `2.0.6`.
- Node.js 22+, npm, and Git on macOS/Linux.
- GitHub authentication (`gh auth login` and `gh auth setup-git`, or a token in
the service environment) and permission to comment, push, and create PRs.
Expand Down Expand Up @@ -113,13 +113,19 @@ Only the authenticated GitHub user is allowed by default; add colleagues to
Run once for **each configured primary checkout**, with its absolute path:

```bash
opencode2 api v2.plugin.awaitActivation --param 'location[directory]=/absolute/path/to/your-project'
opencode2 api plugin.list --param 'location[directory]=/absolute/path/to/your-project'
```

This starts the shared service if needed and loads the project's plugins. The
command exits; the bot keeps running without a TUI or extra monitoring process.
response lists the loaded plugins; confirm `automation` has `state.status` equal
to `active`. The command exits; the bot keeps running without a TUI or extra monitoring process.
**Repeat it after every service restart.**

OpenCode 2.0.6 uses operation names without the `v2.` prefix and no longer exposes
`plugin.awaitActivation`. Upgrade the automation package together with OpenCode;
older beta SDKs cannot discover its service correctly. See
[upgrade compatibility](docs/installation.md#opencode-206-compatibility).

For automatic startup after a machine reboot, put one invocation per project in
your operating system's startup mechanism, under the same user, after networking
is available. Use absolute executable/repository paths (`command -v opencode2`
Expand Down
2 changes: 1 addition & 1 deletion docs/advanced.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ The [README](../README.md) covers the combined package and setup wizard. Use
`examples/advanced.opencode.jsonc` for custom schedules, multiple repositories,
or separately loaded scheduler and dispatcher components.

Both components use only the OpenCode **2** SDK, pinned to `0.0.0-beta-19398`:
Both components use only the OpenCode **2** SDK, pinned to `2.0.6`:

- `automation.scheduler`: invokes configured RPC methods on an interval.
- `automation.github`: owns issue discovery, comments, isolated work, verification,
Expand Down
5 changes: 3 additions & 2 deletions docs/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,9 @@ In the shared background service, each scheduler/dispatcher component renews one
empty maintenance session in the owner location at startup and every ten minutes.
OpenCode counts durable session events as activity; polling plugin APIs alone
does not prevent its hourly inactivity eviction. No model is prompted by keepalive.
The service PID must match the plugin process before any maintenance session is
created. Shutdown releases local SDK waits independently of adapter cancellation,
The service is discovered through `/api/info`; `server.info` must report the plugin
process PID before any maintenance session is created. `session.update` refreshes
its title without prompting a model. Shutdown releases local SDK waits independently of adapter cancellation,
settles state writes, bounds RPC disposal, and releases locks. A healthy worktree
session continues and the replacement owner reconciles its saved identity.

Expand Down
22 changes: 13 additions & 9 deletions docs/bot-workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ happen inside `running`; they are not additional persisted phases.

```mermaid
flowchart TD
Load[Load combined automation plugin] --> Owner{Primary Git checkout root?}
Activate[Open TUI or call plugin.list for the owner location] --> Load[Load combined automation plugin]
Load --> Owner{Primary Git checkout root?}
Owner -->|No or outside Git| Inactive[Plugin stays inactive]
Owner -->|Yes| Config[Use nonempty plugin options or read .opencode/automation.json]
Config -->|No project config| Inactive
Expand Down Expand Up @@ -49,8 +50,9 @@ flowchart TD
Merge --> Worker
RPC -.-> Keepalive[Each component touches the same empty owner session every ten minutes]
State -.-> Keepalive
Keepalive --> PID{Registered service PID matches this process?}
PID -->|Yes| Touch[Create or reuse maintenance session, then emit rename event]
Keepalive --> Discover[Discover service through /api/info]
Discover --> PID{server.info PID matches this process?}
PID -->|Yes| Touch[Create or reuse maintenance session, then session.update its title]
PID -->|No| Skip[Skip keepalive]
Stop[Owner reload or shutdown] --> Cleanup[Stop timers, save stopped inventory snapshots, settle writes, dispose RPC, release locks]
Cleanup --> Preserve[Preserve durable queue and healthy worktree execution]
Expand Down Expand Up @@ -90,7 +92,9 @@ flowchart TD
- Each component renews one empty owner maintenance session at startup and every
ten minutes. Durable session events refresh OpenCode's inactivity timer; listing
plugins does not. No model is prompted. A PID check prevents touching a different
service. Requests do not overlap and have a 15-second deadline. Pausing issue
service, using `server.info` after discovery through `/api/info` in SDK 2.0.6.
The title update uses `session.update`. Requests do not overlap and have a
15-second deadline. Pausing issue
scans does not pause keepalive. Standalone servers without a matching registered
service skip it.
- State is schema-validated and saved through a temporary file, file sync, and
Expand Down Expand Up @@ -309,13 +313,13 @@ sequenceDiagram
alt Operator closes task
U->>D: Confirm Stop and close task in bot menu
D->>D: Persist closing and reject new checkpoints and prompts
D->>S: Interrupt known task sessions and wait for idleness
D->>S: Interrupt known task sessions with resume false and wait for idleness
D->>D: Drain in-flight worker and persist closed
Note over D,G: Preserve work and history, no GitHub closure request
else Operator cancels the round
U->>D: Confirm Cancel current round
D->>D: Persist cancelling and reject new execution checkpoints
D->>S: Interrupt saved sessions and wait for idleness
D->>S: Interrupt saved sessions with resume false and wait for idleness
D->>D: Drain worker and question posts, archive round, enter watching
Note over D,G: Keep PR tracking and future feedback, preserve cancelled worktree
else Owner is disposed
Expand Down Expand Up @@ -408,7 +412,7 @@ flowchart TD
ID --> Session[Get saved helper or create only on explicit not-found]
Session --> Prompt[Send deterministic attachment prompt, hooks disable all tools]
Prompt --> Wait[Wait with session deadline]
Wait -->|Timeout| Interrupt[Attempt helper interruption and return error]
Wait -->|Timeout| Interrupt[Interrupt helper with resume false and return error]
Wait -->|Other failure| Error
Wait -->|Completed| Result{Succeeded outcome and non-error final assistant with finish stop?}
Result -->|No| Error
Expand Down Expand Up @@ -724,7 +728,7 @@ flowchart TD
Close[bot menu: Stop and close task] --> Flight{Publication or merge already in flight?}
Flight -->|Yes| RejectClose[Reject closure, wait and try again]
Flight -->|No| SaveClose[Persist closing before interruption]
SaveClose --> Interrupt[Interrupt known sessions, missing sessions count as stopped]
SaveClose --> Interrupt[Interrupt with resume false, missing sessions count as stopped]
Interrupt --> Drain[Wait for current worker and pending question posts]
Drain --> Again[Interrupt again to cover in-flight session creation]
Again --> Closed[Persist closed, preserve history and all local work]
Expand All @@ -735,7 +739,7 @@ flowchart TD
CancelRound[Cancel current round] --> Publish{Publication or merge in flight?}
Publish -->|Yes| RejectClose
Publish -->|No| SaveCancel[Persist cancelling, block prompts, hooks and checkpoints]
SaveCancel --> DrainCancel[Interrupt sessions, drain worker and questions, interrupt again]
SaveCancel --> DrainCancel[Interrupt with resume false, drain worker and questions, interrupt again]
DrainCancel -->|Success| Watch[Archive round, clear live errors, enter watching]
DrainCancel -->|Failure| RetryCancel[Keep cancelling and error, retry after 30 seconds or owner restart]
RetryCancel --> DrainCancel
Expand Down
25 changes: 24 additions & 1 deletion docs/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ hook; remove the OpenCode loaders first as described in the README.

## Prerequisites

- OpenCode **2**, with a working model. Tested SDK version: `0.0.0-beta-19398`.
- OpenCode **2.0.6**, with a working model. Client/plugin SDK version: `2.0.6`.
- Node.js 22+, npm, Git, and Bash on macOS/Linux.
- GitHub authentication and permission to comment, push, create PRs, and merge.
- A target repository with issues enabled and at least one pushed commit.
Expand Down Expand Up @@ -113,6 +113,29 @@ entrypoints in an isolated Node installation without initializing a renderer.

## Testing and migration

### OpenCode 2.0.6 compatibility

This branch pins `@opencode/client`, `@opencode/plugin`, and the development theme
package to `2.0.6`. Update the automation package when upgrading OpenCode from the
older beta build. An old package can still appear active and scan GitHub while
its management CLI and owner keepalive fail to discover the newer service.

Service discovery now probes `/api/info`. Owner keepalive verifies the service
PID with `client.server.info()` and updates the same empty maintenance session
through `session.update`. Session interruption uses `resume: false` to stop work
without automatically resuming it. The package does not claim compatibility
with the earlier beta API.

For headless startup, use `opencode2 api plugin.list --param
'location[directory]=/absolute/path/to/project'` on one line. Confirm that
`automation` is `active` in the response and repeat for each owner after a
service restart. The old `v2.plugin.awaitActivation` operation is unavailable.
`opencode2 api session.active` lists active execution before a planned restart.
After upgrading, verify `opencode2-automation status` inside each owner checkout,
fresh dispatcher/scheduler timestamps, and `/bot` in a reopened TUI.

### State preservation

Use a separate test repository when testing on another machine. Independent
machines do not share queue ownership and can duplicate work on the same issues.
This installation procedure does not migrate sessions, queues, or worktrees.
Expand Down
Loading