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-subagent-permissions

v0.3.3

Published

OpenCode plugin: persistent, sanitized subagent permission context overlay for the primary TUI session view

Downloads

1,020

Readme

opencode-subagent-permissions

Persistent, sanitized subagent permission context for the OpenCode TUI.

When a subagent (or a nested descendant) raises a permission request, the native OpenCode prompt may show little context: with concurrent subagents the requester can be unclear, and tool arguments are not always visible. This plugin renders a compact widget in the right sidebar (first widget, above other sidebar plugins) that shows, for every pending request visible from your root session:

Permission requests (2)

1  @explore · bash
   rg "permission.ask" packages/opencode

2  @librarian · context7.query-docs
   /anomalyco/opencode

Rows show the requester, the tool, and the request essence in plain form (command text, skill name, matched pattern) — not JSON. The full sanitized payload and the matched patterns are available in the details dialog (Subagent permission requests: details in the command palette).

A second palette command, Subagent permission requests: manage, lists every pending request in the viewed session tree (all types, including ones the widget does not duplicate) and rejects the selected one. This is the cleanup surface for orphaned requests — pending requests whose run is gone and whose native dialog will never appear (for example, subagents spawned into other worktrees and later aborted). Rejecting removes the request from the core.

The widget lists only requests the native dialog renders without their essence (the generic "Call tool X" fallback: skills, MCP tools, custom permission types). Types the native dialog already renders fully — bash commands, file edits, task spawns, web fetches — are not duplicated in the widget.

Stale rows are cleaned up without polling: when a run ends without replying (abort, interrupt), the core removes its pending requests silently, so the widget refetches on the session's idle status transition; requests from deleted sessions are filtered out even if the core still lists them.

The panel is informational only. The native OpenCode permission dialog remains the only decision surface; the plugin never approves, denies, or rewrites any permission decision and never injects anything into the session.

Related upstream reports: #15332 (permission context), #13715 (nested-subagent routing).

Requirements

  • OpenCode 1.18.25 or newer with the typed TUI slot API.
  • No extra runtime installs: the plugin resolves solid-js / @opentui/* inside the OpenCode runtime.

Installation

OpenCode must be fully restarted after installing or changing plugin files or configuration — configuration and plugin files load at startup.

Local file install (this repository)

<project>/.opencode/tui.json (or ~/.config/opencode/tui.json for global):

{
  "$schema": "https://opencode.ai/tui.json",
  "plugin": ["/absolute/path/to/opencode-subagent-permissions/src/tui.tsx"]
}

Relative paths are resolved against the config file that declares them; use absolute paths to share one checkout across projects.

npm install (when published)

opencode plugin add opencode-subagent-permissions

and add the package name to tui.json (plugin) if your OpenCode version does not patch the config for you.

UI behavior

  • The panel appears in the root/primary session view while at least one pending request targets that session tree, and disappears when the last request resolves.
  • Requests are ordered oldest-first; a newly arriving request never replaces an existing one; resolving one request removes only that request.
  • Invocation context is resolved in priority order:
    1. the session tool part for the request's (messageID, callID) — the same source the native permission prompt uses,
    2. sanitized permission.metadata,
    3. an explicit Arguments unavailable from OpenCode marker (never invented context).
  • The origin row shows the requesting session's agent (@explore), falling back to the session title, falling back to Unknown subagent.
  • A command palette entry (Subagent permission requests: details) opens a scrollable dialog with the full sanitized payload for every pending request.

Security and redaction

Permission arguments can contain credentials. Everything shown in the panel and the details dialog passes through the sanitizer first:

  • object keys containing (case-insensitive) authorization, cookie, password, passwd, secret, token, api_key, apikey, private_key, client_secret are replaced with [REDACTED];
  • bearer-token and private-key patterns inside strings are redacted;
  • limits: max depth 6, 50 entries per level, 2,000 chars per string, 16 KiB per payload, 240 chars per compact summary;
  • nothing is written to disk by default; files are never read to build previews.

Integration scenario (manual, requires a live model)

The repository ships a fixture project for the full loop (test/fixtures/project/):

  1. cd test/fixtures/project
  2. Start the TUI: opencode (config already registers the TUI plugin and an integration-subagent agent whose Bash permission is ask).
  3. Prompt the primary session to spawn the integration-subagent subagent with the task "run your integration command".
  4. Before approving, verify the TUI shows the panel with the subagent's name, bash, and the printf SUBAGENT_PERMISSION_INTEGRATION_TEST command.
  5. Verify the native permission prompt is still the only decision surface. Approve once — only that panel entry disappears. Repeat with rejection.
  6. Run two requests concurrently (two subagents) and resolve them in reverse order; each row must disappear independently.
  7. Repeat with an MCP server configured via mcp config that exposes a tool with nested arguments and a fake secret value; verify the arguments are shown and the secret is redacted.

If OpenCode fails to deliver a nested-subagent request to the TUI at all, that is the known upstream core limitation (#13715); the plugin cannot display a request it never sees.

Development

npm install          # local devDependencies only (cache it wherever you like)
npm run typecheck    # tsc --noEmit, includes the TSX against real @opentui types
npm test             # vitest: unit + UI-logic + integration smoke

The integration smoke test spawns a real opencode serve and asserts the /permission data surface the panel depends on. The full TUI scenario needs a live model and is documented above.

Known limitations

  • OpenCode versions without the typed TUI slot API cannot render the panel.
  • Nested descendants may not deliver permission events in some affected OpenCode versions; the plugin shows what OpenCode actually delivers and labels anything missing.
  • The plugin starts with empty in-memory state after reload; the panel rebuilds from the authoritative pending-permissions query on the next render, so stale requests are never shown as live.