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

tabby-ssh-config-groups

v1.0.1

Published

Auto-groups SSH hosts imported from ~/.ssh/config by regex rules.

Readme

tabby-ssh-config-groups

A Tabby plugin that automatically groups SSH hosts imported from ~/.ssh/config by regex rules, so a frequently-regenerated config (e.g. produced by an AWS inventory script) always shows up organized in Tabby's profile list — no manual re-grouping needed.

Example: any host whose alias matches prod-cass (e.g. prod-cass23) is placed into a group named PROD-CASS instead of Tabby's default flat "Imported from .ssh/config" group.

How it works

Tabby already parses ~/.ssh/config itself (via its built-in OpenSSHImporter, including Include directives and cache invalidation on file changes) and exposes every host as a builtin SSH profile. This plugin doesn't re-parse the file or add a second importer (which would duplicate every host) — instead, at startup it wraps the existing importer's getProfiles() and rewrites each profile's group field according to your rules, read fresh from config on every call. Tabby's profile-group tree already creates a group per distinct group string on builtin profiles, so this is all that's needed.

Rules are evaluated in order; the first matching rule wins. A rule matches if its regex tests true against the host's ~/.ssh/config alias (and, optionally, its resolved HostName/IP). Hosts matching no rule keep Tabby's default group, or a configurable fallback group.

Only profiles actually imported from ~/.ssh/config are regrouped. Tabby also ships a separate StaticFileImporter (for a manually-curated ssh-profiles.yaml) registered under the same importer mechanism — this plugin leaves those profiles' groups untouched.

It also patches two more Tabby core services so your groups consistently sort before Tabby's other builtin profiles (shells, serial ports, unmanaged imports) instead of after them — see "Where grouped hosts show up" below for why both patches are needed.

Where grouped hosts show up

Your regex groups appear in:

  • Settings → Profiles & connections
  • The New Tab profile dropdown
  • The quick Ctrl+Shift+E profile selector

By default, Tabby sorts builtin profiles (shells, serial ports, and ~/.ssh/config imports alike) alphabetically by group name, and an empty group name (e.g. the "OS default" shell, which has none) always sorts first — so without this plugin's help, any regex-grouped host sorts after the ungrouped shell/serial entries everywhere. Two separate Tabby behaviors need patching to fix this, since they use unrelated ordering logic:

  • ProfilesService.getProfiles() is patched to move profiles in one of your configured groups (rule groups, or fallbackGroup) ahead of the rest of the builtin bucket. This is what Settings → Profiles & connections and the New Tab dropdown build their order from.
  • SelectorService.show() is patched to bump the sort weight of options in one of your groups. The Ctrl+Shift+E quick selector ignores the order of the profile list entirely and always re-sorts its own way (by weight, then group name, then profile name), so the getProfiles() fix alone has no effect there.

Configuration

Edit via Settings → SSH Config Groups in Tabby, or directly in config.yaml:

sshConfigGroup:
  enabled: true
  matchHostname: false        # also test rules against the resolved HostName/IP
  fallbackGroup: null         # null keeps Tabby's original group for unmatched hosts
  rules:
    - group: PROD-CASS
      match: prod-cass
      flags: i
    - group: ZABBIX
      match: zabbix
      flags: i

Invalid regexes are skipped safely rather than breaking profile loading.

Install

Development (loads the plugin without installing it permanently — quit Tabby first if it's already running):

git clone <this repo>
cd tabby-ssh-config-groups
npm install --legacy-peer-deps
npm run build

# macOS, if `tabby` isn't on PATH:
TABBY_PLUGINS=$(pwd) /Applications/Tabby.app/Contents/MacOS/Tabby
# if `tabby` is on PATH (Linux/Windows, or a CLI install):
TABBY_PLUGINS=$(pwd) tabby --debug

Plugins load once at startup, so after editing/rebuilding you need to quit and relaunch Tabby the same way to pick up changes.

Permanent install: build (npm run build), then copy the whole plugin folder (including node_modules and dist) into Tabby's plugins directory (Settings → Plugins → Open Plugins Directory), and restart Tabby normally.

Why there's no tabby-ssh devDependency

Tabby only redirects require() calls for a fixed whitelist of module names (tabby-core, tabby-settings, tabby-terminal, tabby-local, @angular/*, rxjs, etc.) to its own already-running singletons — tabby-ssh is not on that list. If a plugin has its own node_modules/tabby-ssh installed, plain Node module resolution finds that copy before ever falling back to Tabby's real, already-bootstrapped tabby-ssh, loading a second, independent instance of the whole module — including its own private bundle of NgxFilesizeModule (used by the SFTP panel) — which collides with the app's own instance and throws Error: NgxFilesizeModule does not have a module def (ɵmod property) at startup.

The published tabby-ssh package ships no typings anyway (see src/tabby-ssh.d.ts), so this plugin never installs it — npm install alone is safe to smoke-test against a real Tabby.app. Don't add tabby-ssh back to package.json, and if you ever copy node_modules wholesale for a permanent install, exclude any tabby-ssh directory that might land in it (the build already inlines every other runtime dependency, e.g. pug-runtime, directly into dist/index.js).

After either method, check Settings → Profiles & connections or the New Tab dropdown for the regrouped hosts, and Settings → SSH Config Groups for the rule editor. It flags rules with an invalid regex inline, and includes a live test box (with an optional HostName field, shown once "Also match HostName" is on) to check what group a given alias/hostname resolves to.

Development

npm run build   # one-off webpack build -> dist/index.js
npm run watch   # rebuild on change (still needs a Tabby restart, see above)
npm test        # jest unit tests for the grouping logic (src/grouping.spec.ts)

The regex-matching core (src/grouping.ts) has no Angular/Tabby runtime dependency and is covered by table-driven unit tests independent of a running Tabby instance.

Publishing

Tabby's Settings → Plugins → Available tab has no submission/approval process — it just live-queries the npm registry's search API for packages named tabby-* with the tabby-plugin keyword (see tabby-plugin-manager's PluginManagerService.listAvailable). So "publishing to the plugin page" means publishing to npm; nothing else to configure.

This repo already satisfies what that search needs:

  • package name starts with tabby- (tabby-ssh-config-groups)
  • "keywords": ["tabby-plugin"] in package.json
  • prepublishOnly rebuilds dist/ automatically before every publish

To publish:

npm login      # one-time, needs your own npm account
npm publish    # rebuilds dist/, then uploads to the npm registry

Then in Tabby: Settings → Plugins → Available, search "ssh-config-groups" (Tabby strips the tabby- prefix when displaying the name), click Get, and restart Tabby. It usually takes a few minutes (occasionally up to ~30) for npm's search index to pick up a new package or version after publishing.

This repo being a private GitHub repo doesn't stop npm publish from working — npm doesn't check git hosting at all, it just uploads the built tarball. But publishing an unscoped package like this makes it and its contents public on npm regardless of GitHub visibility (and it must be public for Tabby's marketplace search to find it at all). package.json's files field is deliberately scoped to dist/**/*.js and dist/**/*.d.ts only — it excludes dist/index.js.map, which would otherwise embed the full original TypeScript source (via sourcesContent) in every published version. Run npm pack --dry-run before publishing to double-check exactly what would ship.

Bumping a release: update version in package.json, then npm publish again — Tabby's Installed tab shows an "Upgrade" button once npm has indexed the new version.

References