Monitor
OpenCode background, monitor, loop, and schedule job plugin with TUI status indicator. Requires och (custom opencode build with MCP/TUI integrations).
1
260
11 in 7 days
36.3
Multi-signal model
25 days ago
2026-09-10
Install and configure
opencode.jsonWrites to this project's opencode.json — applies to this repository only.
opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-monitor-plugin@1.2.3"]
}Writes to ~/.config/opencode/opencode.json — applies to every project.
~/.config/opencode/opencode.json
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["opencode-monitor-plugin@1.2.3"]
}If you want to modify the plugin locally, install it into the project and reference the local path.
shell
pnpm add -D opencode-monitor-pluginOpenCode loads npm dependencies through its embedded runtime on startup and caches them locally — no manual global install needed.
OpenCode plugin for background automation jobs. It provides slash commands, AI-callable tools, idle-aware result delivery, and a TUI status indicator.
Prerequisites
This plugin requires och (OpenCode >= 1.17.11-RC1) with the OpenTUI 0.4.x plugin runtime. OpenTUI 0.4+ no longer Solid-transforms .tsx files under node_modules, so this package ships a precompiled dist/tui.js as the public TUI entry.
Install och (Linux x64):
curl -fsSL https://s3.casonatto.dev/shared/opencode-custom/install.sh | sh
Full documentation: https://s3.casonatto.dev/shared/opencode-custom/opencode-custom-hindsight-install.md
Capabilities
- Run long shell commands without blocking the current assistant turn.
- Watch long-running command output for regex matches and deliver matched windows.
- Schedule one-shot prompts for later.
- Run repeated prompt loops; missed ticks while the target session is busy coalesce into one delivery.
- Queue all automatic deliveries until the target OpenCode session is idle.
- Show active jobs in the OpenCode TUI sidebar/title/footer and prompt-side chip.
- Cancel active jobs by job ID.
- Keep v1 state in-memory only; no daemon or persistent job database.
- Sanitize delivered output: nonce framing, ANSI/control stripping, and best-effort secret redaction.
Commands
/background <command>: run/bin/sh -c <command>and deliver the final capped tail output after exit./monitor --regex <pattern> [--before N] [--after N] [--debounce S] -- <command>: run a command and deliver matching output windows./loop <interval> <prompt>: repeatedly submit a prompt. Busy-session ticks coalesce into one delivery./schedule in <duration> <prompt>or/schedule at <iso-date> <prompt>: submit once at a future time./jobs: list jobs for the current session only./cancel <jobID>: cancel a job owned by the current session.
Slash commands are prompt templates that instruct the model to call the matching tool. The AI-callable tool names are:
opencode_monitor_backgroundopencode_monitor_monitoropencode_monitor_loopopencode_monitor_scheduleopencode_monitor_jobsopencode_monitor_cancel
OpenCode harness installation
Use this section when adding the plugin to an OpenCode harness/config repository. Run npm install from the same directory that owns the opencode.json and tui.json files, because the config examples below use relative ./node_modules/... paths. For the default global OpenCode config, that directory is ~/.config/opencode.
1. Install the pinned package
cd ~/.config/opencode
npm install opencode-monitor-plugin@1.2.3
The package is published to npm. Shared harnesses should pin an exact release.
Pin a branch, tag, or commit in shared harnesses when reproducibility matters:
cd ~/.config/opencode
npm install github:Shodocan/opencode-monitor-plugin#<tag-or-commit>
GitHub source installs run npm run prepare, which builds dist/; npm releases include the compiled entries.
Use direct installed file paths in OpenCode config. Bare package subpaths like opencode-monitor-plugin/tui can be treated by OpenCode as packages to install, so GitHub-installed packages should be referenced through ./node_modules/... from the config directory.
Installed entrypoints:
./node_modules/opencode-monitor-plugin/dist/server.js-> server plugin../node_modules/opencode-monitor-plugin/dist/tui.js-> TUI plugin (precompiled Solid universal ESM).
Why dist/tui.js instead of src/tui.tsx: OpenTUI 0.4+ does not Solid-transform package sources under node_modules; this package ships a precompiled Solid universal ESM entry at dist/tui.js.
2. Register server plugin in opencode.json
Add the server entrypoint to the normal OpenCode config:
{
"$schema": "https://opencode.ai/config.json",
"plugin": [
"./node_modules/opencode-monitor-plugin/dist/server.js"
]
}
The server entry exports one runtime factory. Keep programmatic helper imports at
opencode-monitor-plugin (dist/index.js); that helper module is not the runtime
configuration entry. When upgrading from 1.2.2, change an existing configured
dist/index.js path to dist/server.js as well as updating the package pin.
3. Register TUI plugin in tui.json
Add the TUI entrypoint to the OpenCode TUI config:
{
"$schema": "https://opencode.ai/tui.json",
"plugin": [
"./node_modules/opencode-monitor-plugin/dist/tui.js"
],
"plugin_enabled": {
"opencode-monitor-indicator": true
}
}
4. Restart OpenCode
Restart OpenCode after changing opencode.json, tui.json, or the installed package. Plugin config is loaded at startup.
5. Smoke test
Start a short monitor from an assistant turn:
Use opencode_monitor_monitor with raw args:
--regex OPENCODE_MONITOR_SMOKE --before 0 --after 0 --debounce 1 -- sh -c "sleep 2; printf 'OPENCODE_MONITOR_SMOKE ok\n'"
Expected:
- Tool returns
started mon_Nimmediately. - TUI shows an active monitor job while the command is running.
- After the match, OpenCode receives a visible synthetic prompt with the matched output.
Idle/busy delivery model
The plugin sends delivery requests to a local bridge. The bridge tracks opencode session status notifications:
idle: queued deliveries for that session may flush.busy,retry, or unknown: deliveries stay queued.
The bridge delivers through hidden-transport visible synthetic prompts with { text, sessionID, visible: true }. Visible synthetic prompts render with the opencode-injected header ◇ MCP · <server-name>; clients do not provide the caller name. It rechecks session status before each queued delivery. /loop uses latest-only coalescing and adds coalesced tick metadata; /background, /monitor, and /schedule retain full payloads subject to caps. The plugin must not use visible prompt append for queued output, because append mutates the user's prompt input.
Instance disposal
Native instance disposal stops admission immediately and cancels only that instance's
background jobs, monitors, schedules and loops. It waits for process closure, already
started deliveries and status/tail writes before returning. Jobs are in memory and
do not survive disposal. The final status marks the bridge down; other instances
remain operational. Programmatic callers can await plugin.dispose(); server hooks
provide dispose() and the compatible __stop() alias. Cleanup failures reject the
disposal promise.
Bridge config
BridgeServer writes a bearer-token config file to:
OPENCODE_MONITOR_BRIDGE_CONFIG, if set.${XDG_RUNTIME_DIR:-<os-temp>}/opencode-monitor/bridge.json.
Security constraints:
- parent directory mode:
0700 - config file mode:
0600 - owner must match the current uid when available
- symlinks are rejected
- HTTP listener is loopback-only
- bearer tokens are 32 random bytes encoded as base64url
Local development installation
Build the package and register the server plugin entry from dist/server.js in opencode config:
npm install
npm run build
Example opencode config fragment:
{
"$schema": "https://opencode.ai/config.json",
"plugin": ["./dist/server.js"]
}
Restart opencode after changing plugin/config files; config is loaded at startup.
Register the TUI plugin entry in tui.json. Prefer the precompiled entry after build:
{
"plugin": ["./dist/tui.js"]
}
For package-based installs under ~/.config/opencode, use
./node_modules/opencode-monitor-plugin/dist/tui.js. Pointing at src/tui.tsx
only works when that path is outside node_modules (OpenTUI 0.4+ skips
Solid transforms under node_modules).
The TUI plugin adds a visual running-job indicator in the prompt area plus a collapsible sidebar detail view.
Pre-release checklist
Before pushing, tagging, or publishing, run:
npm run typecheck
npm test
npm pack --dry-run
Then inspect the pack list and run a secret scan over tracked and package files to ensure no sensitive data is included.
Limits and safety notes
- Jobs are in-memory only; no daemon persistence in v1.
- Commands run through POSIX
/bin/sh -c. - Active jobs cap: 20.
- Completed retention: 50.
- Output tail cap: 200 lines / 32 KiB per stream.
- Monitor debounce: 1–60 seconds; default 5 seconds.
- Loop interval minimum: 10 seconds.
- Schedule horizon maximum: 30 days.
- ReDoS checks run in worker threads with bounded concurrency and timeout.
- Delivery text is nonce-framed, ANSI/control sanitized, and secret-redacted best-effort.
Validation
npm test
npm run typecheck
npm run build
Current suite covers parsers, registry, runner/ReDoS, monitor engine, bridge queues/server, notifier, plugin handlers, TUI build output, and integration behavior.
Support
For issues, questions, or support: wdcasonatto@gmail.com
Similar plugins
Navigator
opencode-navigator
Search, navigate, and manage OpenCode sessions from the TUI
Skills Tui
opencode-skills-tui
OpenCode TUI plugin that shows skills and loaded state in the sidebar
Cache Hit
opencode-cache-hit
OpenCode TUI sidebar: prompt cache hit rate, tokens & cost with sub-agent rollup. Works with opencode-visual-cache; optional per-call JSONL timeline.