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

@eliware/knit

v2.3.3

Published

GitHub webhook handler and SSH deployment automation service with Discord notifications, delivery-aware presence, and metadata-aware validation workflows.

Readme

@eliware/knit

GitHub webhook handler and SSH deployment automation service.

Runtime

  • Node.js >=26; ESM.
  • POST / receives signed GitHub webhooks.
  • GET / serves the Knit project landing page.
  • GET /health returns service status and version.
  • Trusted target profiles are YAML mounted at KNIT_CONFIG_PATH (default ./repos).
  • Repository deployment workflows live in each repository at .knit/deploy.yaml.
  • Knit fetches and validates that file at the webhook commit SHA; there is no central repository configuration or legacy fallback.

Configuration

For a complete agent-oriented tutorial, see the Knit configuration guide.

Repository workflow configuration uses target-specific command sets:

version: 1
on:
  push:
    deployments:
      - target: dev
        cwd: /opt/repo
        commands:
          - git pull --ff-only
          - npm install
          - npm test
  tags:
    "v*":
      deployments:
        - target: dev
          cwd: /opt/repo
          commands:
            - npm run release

Repository workflows are intentionally plaintext YAML and contain no credentials. The GitHub read token, Discord bot token, and SSH assets remain runtime secrets. Pushes and matching v* tags select separate actions; there is no fallback from a tag to the push action.

The main target configuration contains one Discord guildId, not project channel IDs. Knit finds an Announcement channel named after the repository, creating it on demand. New channels are public but read-only for public GitHub repositories and hide @everyone for private repositories. Repository descriptions and keywords from package.json are synchronized into the channel topic, and v* tag announcements are cross-posted.

While idle, the bot displays 🧶 knit v<version> as its activity. When a webhook begins, it displays ⏳ knitting <repository>, then displays ✅ <repository> success or ❌ <repository> failure when processing finishes. Intentionally unmatched tag deliveries display ℹ️ <repository> ignored instead of being retried as failures. Presence updates are throttled to Discord's presence limit; when the bucket is full, Knit waits for capacity instead of dropping the start or terminal result. Delivery IDs prevent stale terminal results from replacing the active delivery's status. After ten minutes without work, the version activity returns.

Kubernetes uses a content-hashed ConfigMap for repository configuration. Updating a config through GitOps changes the ConfigMap name and the Deployment reference, causing Kubernetes to restart Knit with the new configuration. Knit does not monitor mounted files for changes while running.

Targets execute commands over SSH with strict host verification through @eliware/ssh-client. GitOps target profiles own connection details and may restrict repository access and working-directory roots. CA-signed host certificates are trusted through an @cert-authority record in known_hosts or a mounted hostCa public-key file.

Each SSH command receives the triggering webhook metadata as environment variables:

| Variable | Value | |---|---| | KNIT_COMMIT_SHA | Exact webhook after SHA, or empty when absent/malformed | | KNIT_REPOSITORY | Full repository name, such as eliware/gitops-k8s | | KNIT_REF | Webhook ref, such as refs/heads/main | | KNIT_EVENT | GitHub event name | | KNIT_DELIVERY_ID | Webhook delivery correlation ID |

Workflows may set timeoutMs on a deployment, from 1 through 300000 milliseconds, to bound each remote command. Metadata values are passed through SSH environment requests and safely exported in the remote shell so they work even when sshd does not accept arbitrary AcceptEnv values. Knit does not interpolate arbitrary environment variables or secrets into command strings. Commands should enforce their own cleanup and must not print secrets. Output is truncated for Discord limits; secret redaction remains the responsibility of the command and runtime configuration.

New configurations must use YAML and SSH targets. Local Compose requires the target inventory, Discord credentials, and read-only mounts for the SSH identity, strict known_hosts, and host CA; systemd requires equivalent mounted/provisioned configuration and secrets.

Operations

Knit validates target profiles before opening the Discord connection. Repository workflows are evaluated per signed event and pinned to the webhook commit. The encrypted runtime Secret is owned and recovered through the GitOps secret-management process; never copy workstation private keys, decrypted secrets, or GitHub tokens into this repository.

Knit self-deployment and organization events

Organization-level events are ignored unless they include a repository. Repository pushes fetch and execute only that repository's committed .knit/deploy.yaml. Knit code changes are delivered as immutable container releases through GitOps; source push handling does not restart the running service.

Environment

| Variable | Purpose | |---|---| | PORT | Listen port; default 3456 | | GITHUB_WEBHOOK_SECRET | GitHub signature secret | | LOG_LEVEL | Logger level | | KNIT_CONFIG_PATH | Mounted configuration directory | | KNIT_TARGETS_PATH | Optional explicit path to the trusted target inventory; otherwise KNIT_CONFIG_PATH/targets.yaml | | NODE_ENV | Runtime mode; use test only for test execution | | GITHUB_READ_TOKEN | GitHub Contents API token for private repository workflow files | | DISCORD_TOKEN | Discord bot token, supplied from a runtime Secret | | DISCORD_CLIENT_ID | Discord application/client ID |

Development

npm install
npm test
npm run lint
npm start

npm test uses @eliware/test for the baseline Jest coverage and Oxlint checks. It requires 100×4 coverage and zero lint warnings; project-specific integration, smoke, regression, or end-to-end checks remain separate.

Development now takes place on the Windows workstation under C:\Users\russe\src\knit; the former OVH dev VM is a legacy deployment target. Kubernetes releases use immutable container images and Argo CD GitOps. New Knit code is delivered by releasing an image, not by runtime self-updating. The notifier implementation is organized under src/notifier/, and webhook command-environment construction is isolated in src/webhookEnvironment.mjs.