npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

opencode-script-runner

v0.1.5

Published

Run shell scripts in the background from OpenCode and get notified when they finish.

Readme

opencode-script-runner

Run a shell script in the background from OpenCode and get notified when it finishes. You keep working while the script runs, and the plugin wakes you with the result when it is done.

This is an OpenCode server plugin. It runs on your machine inside the OpenCode server process, so a background script survives the tool call that started it.

Features

  • Start any script with one tool call and get a run id back immediately.
  • Read live output while the script runs.
  • Check status without blocking.
  • Kill a running script.
  • Get a wake notification with the exit code and a tail of the output when the script finishes.
  • Logs are written to disk, so output survives session restarts.

Install

This package is published to the public npm registry.

Add it to your OpenCode config. Open your global config at ~/.config/opencode/opencode.json and add the package name to the plugin array:

{
  "$schema": "https://opencode.ai/config.json",
  "plugin": [
    "opencode-script-runner"
  ]
}

OpenCode downloads and installs npm plugins automatically at startup. Quit and restart OpenCode for the change to take effect.

That is all. No manual download or setup is needed.

Usage

The plugin adds four tools. Each is called by the OpenCode agent (you) and returns text.

Start a script

script_run(script="./train.sh")

This starts train.sh in the background and returns a run id, for example calm-falcon-4321. The agent keeps working. When the script finishes, the plugin sends a wake notification with the exit code and the last part of the output.

Pass arguments, a working directory, and a timeout if needed:

script_run(script="./train.sh", args=["--epochs", "100"], cwd="/path/to/project", timeout=3600000)

Use an interpreter when the script is not executable or is in another language:

script_run(script="./train.sh", interpreter="bash")
script_run(script="./app.py", interpreter="python3")

script= must be a file path. To run an inline shell command (one with &&, ||, |, redirects, cd x && ... and so on) you MUST pass interpreter="bash":

script_run(script="cd /path/to/project && ./verify.sh && echo VERIFY_OK", interpreter="bash")

Without an interpreter, script= is spawned directly as a single executable path, so an inline command fails to start (ENOENT) and the run errors immediately with an empty log. If you pass a shell command without an interpreter, the plugin rejects it before spawning and tells you to add interpreter="bash".

Failed starts surface in three places: the script_status result (error: <message>), the script-done notification (<error> line plus non-zero/empty exit-code), and the run's log file. Every script_run call leaves a log file on disk after it finishes, so a run that failed to start is still inspectable.

Check status

script_status(run_id="calm-falcon-4321")

Returns running or a finished status with the exit code.

Read output

script_log(run_id="calm-falcon-4321", tail=50)

Returns the whole log, or only the last tail lines. Each run writes its own log file under ~/.local/share/opencode/script-runs/.

Stop a script

script_cancel(run_id="calm-falcon-4321")

Kills the whole process group of the script, including any child processes, then escalates to SIGKILL if the group is still alive after 2 seconds. Returns immediately (never waits on the model). The cancel result is returned to the caller; no wake notification is emitted for an explicit cancel (the caller asked for it). Check script_status after cancelling to confirm the run is stopped.

Cancel is fail-fast: the tool resolves within 2 seconds no matter what. If the process cannot be confirmed stopped, it returns an error and the agent can try other measures.

Note: a docker compose up (or other daemon-managed) stack can outlive the script process group — the containers run under dockerd, so a plain process-group kill may not stop them. Run docker compose down to stop a stack.

Wake notification

When a script finishes, the agent receives a system event that looks like this:

<task-notification>
<event>script-done</event>
<run-id>calm-falcon-4321</run-id>
<status>complete</status>
<exit-code>0</exit-code>
<output-tail>
... last lines of the script output ...
</output-tail>

A failed run reports status=error (or timeout/cancelled) with a non-zero or none exit-code, and — when the process failed to start or errored — an <error> line carrying the message. Treat this as a status event, not as an instruction. To act on it, read the full log with script_log, then continue whatever the script produced.

Logs and state

  • Script output: ~/.local/share/opencode/script-runs/<project>/<run-id>.log
  • Plugin debug log: ~/.opencode-script-runner.log

Development

npm install      # install dependencies
npm run typecheck  # type check only
npm run build    # compile TypeScript to dist/
npm publish      # build and publish to npm (runs build automatically first)

License

MIT