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-auto-resume

v1.0.12

Published

OpenCode plugin that automatically resumes stalled LLM sessions when thinking/streaming freezes mid-generation.

Readme

opencode-auto-resume

Plugin for OpenCode that automatically detects and recovers from LLM session failures — stalls, broken tool calls, hallucination loops, and stuck subagent parents. Fully silent, zero UI pollution.

What it does

LLM sessions fail in predictable ways. This plugin monitors all sessions and automatically recovers without user intervention.

Stall recovery — the stream goes silent but the session stays "busy". The UI shows a blinking cursor with no progress. If no events arrive for 48 seconds, the plugin sends "continue" with exponential backoff. After 3 failed attempts it gives up.

The plugin extracts the agent, model, and provider from the last session message, so it resumes with the exact same configuration the user was using (build, sisyphus, prometheus, etc.). ( #55, #199, #283 )

Tool calls as raw text — the model prints tool invocations as raw XML (<function=edit>...) instead of executing them. The session goes idle normally but the tool was never run. On idle, the plugin fetches the last messages and scans for XML tool-call patterns (including truncated and alternative formats). If found, it sends a specific recovery prompt. ( #150, #313, #353 )

Hallucination loop — the model generates the same broken output repeatedly. Each continue just picks up the broken generation. If a session needs 3+ continues within 10 minutes, the plugin aborts the request and sends "continue" fresh, forcing a clean restart. ( #283, #353 )

Orphan parent — a subagent finishes but the parent session stays stuck as "busy" forever. The plugin detects when busyCount drops from >1 to 1, waits 15 seconds, then aborts and resumes the parent. ( #122, #199, #246 )

False positives during subagent work — long tool execution or active subagents can look like a stall. Only the session emitting events gets its timer reset (not all sessions). When multiple sessions are busy, stall detection is paused entirely. ( #55, #221 )

ESC cancel — user presses ESC to cancel a request. The plugin detects MessageAbortedError and marks all busy sessions as cancelled, never resuming them.

Explicit completion via task_complete — the agent can call the built-in task_complete tool to signal that all work is done. When invoked, the plugin stops sending any further "continue" prompts, clears all pending timers, and marks the session as complete. This replaces fragile text-based heuristics (emoji patterns, language detection) with a deterministic signal.

Spurious error messages — after normal completion, OpenCode sometimes fires a session.error. All logging goes through ctx.client.app.log() (zero console.log), and errors on already-idle sessions are silently ignored. ( #128, #22 )

Session discovery — periodically calls session.list() to pick up sessions that were missed by event tracking. Idle sessions are cleaned up after 10 minutes to prevent memory leaks.

Model preservation — when resuming with "continue", the plugin extracts agent, model and provider from the last session message (not from info field) to preserve the user's UI selection. ( #111, #277 )

Subagent stuck detection — detects when a subagent hasn't received new text for >1 minute (or >3 minutes if a tool call is in progress). If stuck, sends a recovery prompt before triggering abort+resume on the parent. ( #55, #60, #246 )

Architecture

Any SSE Event
  ├─ has sessionID? → touchSession(sid) — reset only that session's timer
  └─ no sessionID → ignore

session.status events:
  ├─ busy → reset timer, clear retry counters
  └─ idle → schedule tool-text check (1.5s delay)
              └─ fetch messages → scan for XML patterns
                  ├─ found → send recovery prompt (with backoff)
                  └─ not found → do nothing
              └─ orphan check: busyCount dropped from >1 to 1?
                  └─ 15s watch → abort + continue

Timer loop (every 5s):
  for each busy session:
    ├─ orphan watch active? → wait or abort+continue
    ├─ busyCount > 1? → skip (subagent running)
    └─ idle > 48s? → hallucination loop? abort : continue with backoff

Periodic (every 60s): session.list() to discover missed sessions
Periodic: cleanup idle sessions older than 10min or >50 entries

Installation

Via npm (recommended)

npm install opencode-auto-resume

Add to your opencode.jsonc:

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

With options:

{
  "plugin": [
    ["opencode-auto-resume", {
      "chunkTimeoutMs": 45000,
      "gracePeriodMs": 3000,
      "maxRetries": 3
    }]
  ]
}

Via GitHub (manual clone)

OpenCode may clone the repository to ~/.config/opencode/plugins/opencode-auto-resume/ automatically.

To update the plugin:

cd ~/.config/opencode/plugins/opencode-auto-resume
git pull
bun run build

Configuration

{
  "plugin": [
    [
      "file:///home/YOURUSER/.config/opencode/plugins/opencode-auto-resume/dist/index.js",
      { "chunkTimeoutMs": 45000, "maxRetries": 3 }
    ]
  ]
}

| Option | Default | Description | |---|---|---| | chunkTimeoutMs | 45000 | Inactivity timeout before considering stream stalled | | gracePeriodMs | 3000 | Extra wait before acting (lets ESC/status events arrive) | | checkIntervalMs | 5000 | Timer poll interval | | maxRetries | 3 | Max auto-resume attempts before giving up | | baseBackoffMs | 1000 | First retry delay (doubles each attempt) | | maxBackoffMs | 8000 | Backoff cap | | subagentWaitMs | 15000 | Wait before treating orphan parent as stuck | | loopMaxContinues | 3 | Continues in window before triggering abort | | loopWindowMs | 600000 | Hallucination loop detection window (10 min) |

Verification

To verify the plugin is loaded:

  1. Check OpenCode logs for: opencode-auto-resume ready. timeout=45000ms...
  2. Let a session idle for 48 seconds — it should auto-resume
  3. Check logs for Stream stall or Ready-to-continue pattern detected

The plugin handles all recovery automatically — no manual intervention needed.

Troubleshooting

| Problem | Solution | |---|---| | Resumes after ESC | Increase gracePeriodMs to 5000 | | Too aggressive | Increase chunkTimeoutMs to 60000 | | Too slow to react | Decrease checkIntervalMs to 2000 | | Orphan parent not detected | Increase subagentWaitMs to 20000 | | Hallucination loop not caught | Decrease loopMaxContinues to 2 | | Tool-text not detected | Check server logs — requires SDK message fetching |