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

dsh-ssh-manager

v0.3.0

Published

Manage SSH identity keys and per-host ssh config from the web settings page, so git-over-ssh works in headless server mode.

Readme

dsh-ssh-manager

A DeepSeek Harness plugin for managing SSH identities from the web settings page, so an unattended agent can git clone git@host:user/repo in headless server mode.

It adds one card to Plugins → Plugin configuration → SSH and turns what you enter there into real ssh files under $DSH_HOME/.ssh (~/.dsh/.ssh when DSH_HOME is unset) — always separate from your own ~/.ssh.

Install

Requires Node ≥ 20 and pnpm (which dsh plugin forwards to).

dsh plugin --profile web add dsh-ssh-manager        # from npm
dsh plugin --profile web add /path/to/dsh-ssh-manager   # or a local checkout

That installs the package into the profile and appends it to dsh.profile.bundles; the plugin's own cordis.patch.yml inserts its loader row from there. Restart the harness and the card appears — no web-app rebuild, and nothing to build in this package (lib/ ships prebuilt and self-contained).

Don't also add a - insert: - id: dsh-ssh-manager row to the profile's user patch: two rows with the same id are a fatal duplicate-entry error.

ln -s /abs/path/to/dsh-ssh-manager "$DSH_HOME/profiles/<profile>/node_modules/dsh-ssh-manager"

then add the row to the profile's cordis.patch.yml:

- insert:
    - id: dsh-ssh-manager
      name: 'dsh-ssh-manager'

Profiles with patchReload: live pick the patch up without a restart; write it atomically (write tmp + rename) if so.

Using it

  1. Open Plugins → Plugin configuration → SSH.
  2. First time only: the card shows a warning and greys out Add SSH host until ~/.ssh/config imports the managed dir. Add the Include line appends that one line for you, preserving your existing config and its file mode.
  3. Add SSH host → fill in host, URL/HostName, user, paste the private key, add any extra ssh-config options → Save.
  4. git clone [email protected]:you/repo now works from the agent. The public key is derived to <host>.pub, ready to paste into GitHub/GitLab.

Fields. Host is the ssh Host alias, URL / HostName the machine to connect to, User the ssh user (git for GitHub/GitLab), Extra ssh-config options one directive per line (e.g. ProxyJump jump-host).

The private key behaves like a provider API key: write-only, never shown back or sent to the browser. A new host must carry one before it can be saved; editing an existing host shows Configured — paste a new key to replace and keeps the stored key if you leave the field blank. Renaming counts as new, since the old entry's key leaves with it.

Validation. A key must start with a PEM header (-----BEGIN OPENSSH PRIVATE KEY-----, -----BEGIN RSA PRIVATE KEY-----, …). Host names must start with a letter or digit and use only letters, digits, ., _, - — they double as directory and file names on disk.

What it writes

$DSH_HOME/.ssh/
  config                  flat ssh_config; only a managed Include region is
                          added, everything else is preserved
  config.d/<host>/
    config                the Host block, fenced with managed markers (0600)
    <host>                the private key (0600)
    <host>.pub            the derived public key (0644)

Each host owns its files, so concurrent editors never contend on one file. Removing a host deletes its whole config.d/<host>/ directory. Anything the plugin did not write — a seeded default config, known_hosts, manually placed keys — is never touched. In the DSH container, /etc/ssh/ssh_config.d/99-dsh-container.conf already Includes $DSH_HOME/.ssh/config, so the managed blocks take effect for git.

Keys live in the settings document as role('secret'): never serialized into a describing response, and written to disk with mode 0600.

Development

npm install       # tsdown + schemastery, build inputs only
npm run build     # host bundle (tsdown) + client wrap
  • src/index.js → lib/index.js — host half: schema, validation, and the reconcile that writes and cleans the ssh files. Bundled self-contained (schemastery inlined): the harness imports it with plain Node resolution from wherever it is installed, so a non-bundled copy fails to load. build.mjs refuses to emit one that isn't.
  • src/client/index.js → lib/client.js — browser half: the settings card in plain React.createElement (no JSX), wrapped into the loader's closure-factory artifact. package.json's dsh.client declares it.
  • cordis.patch.yml — the patch inserting the loader row.

The card talks to the harness through ctx.settingsScope (revision-fenced writes), the built-in client modules (react, @deepseek-ai/dsh-client-*), and one host route for the Include check: GET|POST /dsh-ssh-manager/ssh-import (loopback-guarded, same-origin).

Both halves are committed prebuilt, so keep lib/ in step with src/ — the prepublishOnly hook rebuilds and refuses to publish if that changes anything under lib/. Host-side changes need a harness restart; client-only changes apply on a page refresh.

License

MIT — see LICENSE.