Skip to content

feat(opencode): monitor delivery via opencode-sentinel plugin (re-land of #547) - #570

Merged
fujibee merged 5 commits into
mainfrom
feat/opencode-sentinel-monitor
Jul 31, 2026
Merged

feat(opencode): monitor delivery via opencode-sentinel plugin (re-land of #547)#570
fujibee merged 5 commits into
mainfrom
feat/opencode-sentinel-monitor

Conversation

@fujibee

@fujibee fujibee commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Re-lands @tsukimiya's #547 from a branch in this repository, stacked on #569 the same way the originals were stacked. The three feature commits are cherry-picked with -x and keep their original authorship; one further commit is ours and is described below.

Base is #569, so this PR shows only the monitor work. Same mechanical reason as there: the original's checks predate the shard split, so the required context can never report on that head.

What it does

Gives opencode a real-time delivery mode. monitor=yes and delivery_modes=monitor turn off in the manifest let delivery.sh set monitor opencode through the central gate, and the opencode delivery plug writes a rule telling the agent to launch watch.sh under the opencode-sentinel plugin's sentinel_monitor tool — the same shape as Claude Code's Monitor. The rule also carries a turn-mode fallback for when that tool is absent.

No new manifest keys: delivery_modes already exists and is already enforced. What changes is the set of modes opencode declares, so this is a capability the type gains rather than a new interface.

both stays unsupported, and that is enforced rather than documented — the central gate in delivery.sh rejects any mode absent from delivery_modes before apply_settings runs, so the plug's both branch is unreachable. Verified against main rather than taken from the comment.

The one commit that is ours

docs(opencode): describe the monitor fallback as instructed, not enforced adjusts wording, not behaviour.

The page said monitor "never silently drops messages". agmsg writes the rule; it does not detect whether sentinel_monitor exists, so the fallback is an instruction the agent follows rather than a code path agmsg enforces. An agent that ignores it delivers nothing, and nothing reports that. The text now says monitor degrades to turn, spells out what is and is not guaranteed, and names turn as the mode to choose when delivery must not depend on an agent honouring a rule.

The implementation is untouched — the fallback is a good design for the constraint it works under. Only the promise now matches what the code can keep.

Tests

bats tests/test_delivery.bats tests/test_spawn.bats — 233/233, exit 0, against current main.

Closes #547 once this lands.

Known, tracked separately

The monitor rule interpolates the project path into command text as '$project', which is the shell-quoting gap tracked as the first item of #550. This adds two more occurrences of an existing pattern rather than a new class of problem; #550 is being updated to name the opencode rule among its affected files.

tsukimiya and others added 5 commits July 30, 2026 17:27
Route opencode's real-time delivery through the sentinel_monitor tool
(same shape as Claude Code's Monitor), with a turn-mode fallback when
the tool is unavailable.

(cherry picked from commit 0f4b8e6)
Companion to the monitor-delivery implementation: updates README.md,
README.ja.md, and docs/opencode.md so the delivery-modes table and the
OpenCode section list monitor as supported (via the external
opencode-sentinel plugin), describe the turn fallback when the plugin
is absent, and drop the stale 'no Monitor tool' / 'not supported'
claims about monitor and spawn.

(cherry picked from commit 4fc39bc)
- watch.sh command now passes "${SENTINEL_SESSION_ID:--}" (4 sites:
  _delivery.sh + template.md x3) instead of "$SENTINEL_SESSION_ID", so
  launcher shells that drop a quoted-but-empty first arg don't shift
  later watch.sh parameters. watch.sh documents this hazard for
  GROK_SESSION_ID and recommends the same "${VAR:--}" shape.
- template.md actas/drop steps in monitor mode now explicitly say to
  skip the sentinel_* tool calls when the plugin is unavailable, instead
  of assuming the tools exist whenever mode=monitor.
- README.md / README.ja.md delivery-modes table: monitor row notes
  OpenCode requires the plugin; turn row scopes OpenCode to the
  plugin-not-installed case (the template picker now defaults to
  monitor when the plugin is present).

Copilot review feedback on #547.

(cherry picked from commit e03fe89)
…rced

The page said monitor never silently drops messages. agmsg writes the rule
and does not detect whether the sentinel tool exists, so the fallback is an
instruction the agent follows, not a path agmsg enforces — an agent that
ignores it delivers nothing and nothing reports that.

Reworded to degrades-to-turn, with what is and is not guaranteed spelled
out and turn named as the mode to pick when delivery must not depend on the
agent honouring a rule. The implementation is unchanged; only the promise
now matches it.
…ands

The rule wrapped the path in literal single quotes, which holds only while
the path contains none. delivery.sh accepts an apostrophe because it is a
legal POSIX path character, so such a path ended the quoted argument early
in both generated commands — the sentinel_monitor watcher and the fallback
check-inbox — and anything after it became live shell syntax.

Quote once with %q and use that in both. $type stays as it was: it comes
from the type registry, not the caller.

The regression runs the generated command lines through bash -n rather than
matching text, so it fails on a broken quote instead of on a wording change.
Verified against the unquoted form, where it reports the watch.sh line as
unparseable.

Also carries the fallback wording the rest of this branch already fixed into
README.md, README.ja.md, and the opencode doc summary, which still described
the fallback as unconditional. Found in review; the earlier sweep looked for
the "never silently drops" phrasing and missed these.
@fujibee
fujibee force-pushed the feat/opencode-sentinel-monitor branch from acf8dc1 to 48fabca Compare July 31, 2026 00:32
@fujibee
fujibee changed the base branch from feat/opencode-spawn-prompt to main July 31, 2026 00:32
@fujibee fujibee closed this Jul 31, 2026
@fujibee fujibee reopened this Jul 31, 2026
@fujibee
fujibee merged commit 8101d6d into main Jul 31, 2026
14 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.

2 participants