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

@lvy-jsd/dsh-tool-manager-panel

v0.1.0

Published

Web panel for dsh-tool-manager: browse the tool directory, see what each live session has loaded and what it costs, and load or unload from the UI.

Readme

@lvy-jsd/dsh-tool-manager-panel

Web panel for dsh-tool-manager: browse the tool directory, see what each live session has loaded and what it costs, and load or unload from the UI.

Optional — the core works without it. When the deployment has no web server (headless), the plugin mounts nothing and stays harmless.

What you get

| View | Shows | Actions | |---|---|---| | Directory | the same category → group → tool tree the model browses, with per-node tool counts and schema tokens, plus each tool's summary and high-risk mark | click to drill down; load on any node; search across the whole tree from the search box | | Sessions | every live agent (subagents marked with their parent), its loaded groups and tools, how many tools are visible (exempt for a route listed in exemptProviders, which is never narrowed), and the schema tokens actually sent for it | load / unload per agent | | Configuration | the effective always-on list, config additions, and the high-risk list, plus every registered extension point (classifiers with priorities, visibility filters, risk gates, state providers, categories) | read-only in v1 |

Loading from the panel goes through the same path as tools_load, so tool-catalog/before-load hooks and vetoes apply. The risk gate's approval prompt does not: it guards the model's tools_load call, and a click in the panel is itself the user's consent. Without any risk gate installed, high-risk loads are still refused.

Install

dsh plugin --profile web add @lvy-jsd/dsh-tool-manager @lvy-jsd/dsh-tool-manager-classifier-rules @lvy-jsd/dsh-tool-manager-panel

Then restart DSH (or let live reload pick it up). Open Settings: a Tool manager section (工具管理 in Chinese) appears in the settings sidebar.

The panel follows the DSH interface language (English and Chinese, English by default; category names and descriptions are translated) and the active theme, light or dark, because it is styled only with the host's --dsw-alias-* theme variables.

- id: tool-manager-panel
  name: '@lvy-jsd/dsh-tool-manager-panel'
  config:
    enabled: true   # false disables the routes (the settings section then reports the service offline)

How it is put together

Two halves:

  • Server half (src/index.ts) mounts two same-origin routes under a loopback + same-origin trust fence (the same shape dsh-mcp-connector uses):

    | Route | Purpose | |---|---| | POST /tool-manager/api | JSON-RPC with a method whitelist (tree, sessions, load, unload, config, extensions, search) | | GET /tool-manager/events | SSE: catalog rebuilt, per-session state changed |

  • Browser half (src/client.ts) is a small window.__ModuleLoader__.load({...}) registration, compiled by tsc into a classic script (lib/client.js) — no bundler. It registers one settings.section slot and renders the panel natively with React (no iframe). Copy lives in two dictionaries registered with the host locale service; styles use only --dsw-alias-* variables, so any DSH theme applies.

To add a language, add a dictionary next to en and zh in src/client.ts and register it under the same namespace (tool-manager.panel).

Writing your own panel

Every method reads from the toolCatalog service, so a different UI needs no core changes:

ctx.inject(['toolCatalog'], (c) => {
  const tree = c.toolCatalog.get()               // catalog for an agent (or the union)
  const rows = c.toolCatalog.agents()            // live agents with parents
  const state = c.toolCatalog.stateOf(agent)     // { loaded, groups, … } (Sets)
  const tokens = c.toolCatalog.wireTokens(agent) // schema tokens really sent
  const hits = c.toolCatalog.find('adb')         // structured cross-tree search
  await c.toolCatalog.load(agent, ['/device/adb'])   // same path as tools_load
})

License

MIT — see LICENSE.