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

@vertile-ai/gunner

v0.1.0

Published

Config-driven manager for GitHub Actions self-hosted runners

Readme

Gunner

Gunner is a config-driven lifecycle manager for official GitHub Actions self-hosted runners. It creates, observes, reconciles, and removes runner registrations and their host runtime. GitHub Actions remains the workflow control plane.

Product boundary

Gunner is not a CI scheduler, job relay, workflow executor, shell service, or job-log aggregator. The official runner connects directly to GitHub, which queues and assigns jobs. A project repository owns its workflow YAML, scripts, toolchain contract, release and deployment logic, and infrastructure intent. Gunner owns only the generic runner lifecycle and routing inputs: registration, labels, runner groups, repository allowlists, local receipts, and the selected launchd or Docker runtime.

project workflow and scripts -> GitHub Actions -> official runner -> project job
gunner.yaml -> Gunner -> GitHub runner API + host runtime -> official runner

The fuller boundary, including Terraform, Ansible, and provider ownership, is in the architecture.

0.1.0 support status

0.1.0 is an initial macOS-host release for managing official runners. It supports strict v1 configuration, per-target runner policy overrides, non-mutating planning, ownership receipts and state classification, GitHub repository and organization targets, runner groups and selected-repository allowlists.

  • Native macOS runners use launchd. Creation, update, removal, planned replacement, and terminal replacement recovery are supported by the CLI.
  • Docker runners run the official GitHub runner image on the current macOS host. Creation, in-place update, and removal are supported.
  • status, doctor, and apply --dry-run are observation/planning commands; dry-run does not create registration tokens or mutate GitHub, Docker, launchd, or the host filesystem.

The following are deliberately unavailable or blocked rather than silently attempted: Docker replacement or adoption, data-root migration execution, unresolved removal recovery, the Web Console, remote/tunnel access, native Linux-host support, and live Noop cutover. control.enabled: true is rejected. See known limits and the active roadmap.

Requirements

  • macOS on ARM64 for the evidenced native launchd path
  • Node.js 22 or newer
  • GitHub CLI (gh), authenticated for the declared repository or organization
  • tar; Docker and/or declared capabilities such as Tailscale when required by a target
  • repository or organization administration sufficient to manage runners

Docker mounts the host Docker socket into a privileged job environment. Use it only for trusted workflows and repositories that share one host-wide trust domain. Keep fork and untrusted pull-request workloads on GitHub-hosted runners.

Use Gunner for a new project

  1. Install the released package, or use a source checkout:

    npm install --global @vertile-ai/[email protected]
    
    # Source fallback
    pnpm install --frozen-lockfile
    pnpm build
    pnpm gunner --help

    The remaining commands below use gunner. In a source checkout, replace them with pnpm gunner.

  2. Authenticate GitHub CLI and create a tracked, secret-free operator config. gunner init creates a minimal file without overwriting an existing one.

    gh auth login
    gunner init
  3. Declare the runner target. The project chooses the same label in its own workflow; Gunner never copies or executes that workflow logic.

    version: 1
    
    host:
      dataDirectory: ~/.gunner
    
    runner:
      version: 2.335.1
      labels: [trusted-build]
    
    targets:
      - id: my-project-build
        repository: example-org/my-project
        runner:
          runtime: launchd
          labels: [my-project-build]
          requires: []
  4. In example-org/my-project, route an eligible trusted workflow to it:

    jobs:
      build:
        runs-on: [self-hosted, my-project-build]
        steps:
          - uses: actions/checkout@v4
          - run: ./scripts/build-and-test

    The checked-out project supplies ./scripts/build-and-test, dependencies, and deployment policy. actions/checkout populates $GITHUB_WORKSPACE; Gunner does not use a developer's existing clone.

  5. Inspect first, then apply the exact plan. For any plan that interrupts an existing runtime, the CLI requires the printed plan fingerprint, --yes, and confirmation of every interrupted target.

    gunner doctor
    gunner apply --dry-run
    gunner apply
    gunner status

doctor rejects unsafe default-branch workflow routes that send pull_request or pull_request_target code to self-hosted or a configured Gunner label. Review all other triggers and repository trust policy before using a host with privileged capabilities.

Configuration

gunner.yaml is desired state and may be tracked in an operator or project repository. It never contains GitHub, runner, host, provider, or tunnel credentials. Per-target runner values override the top-level defaults.

An organization target can restrict a runner group to selected repositories:

version: 1

runner:
  runtime: docker
  version: 2.335.1
  labels: [trusted-build]
  requires: [docker]

targets:
  - id: shared-build
    organization: example-org
    group: trusted-build
    repositories: [app, api]
    runner:
      labels: [shared-build]

~/.gunner is the recommended root for new installations. Existing ~/.local/share/gunner installations must stay explicitly configured until a future migration executor is released; do not move runtime files manually.

Commands

| Command | Behavior | | --- | --- | | gunner init | Create a minimal v1 configuration without replacing a file. | | gunner doctor | Validate host/config readiness and check unsafe workflow routing. | | gunner apply --dry-run | Observe state and print a deterministic non-mutating plan. | | gunner apply | Reconcile executable lifecycle operations; guarded confirmation is required for interruptions. | | gunner status | Report desired, local, runtime, and GitHub observations with classification. | | gunner remove <id> --yes | Plan and execute explicit receipt-bound removal when its operation is executable. |

All lifecycle commands accept --config <path>. gunner --help and gunner --version work without reading configuration or contacting GitHub; help lists the exact confirmation options emitted for an interrupted plan.

Known limits

  • The package has no Web Console, gunner web command, authentication service, audit UI, ngrok integration, or tunnel support.
  • Docker replacement and adoption fail closed. Do not attempt to take over an existing Docker runner with 0.1.0.
  • The old-root/new-root observation and paired journal protocol exist, but no data-root migration executor is released.
  • Noop is not cut over by this release. Its release lane and all live fleet mutations remain subject to the active roadmap's trust and cutover gates.
  • Native Linux-host and macOS x64 support are not established release claims.
  • Removal and recovery are intentionally conservative; an operation reported blocked or needing recovery requires the reported manual procedure rather than a forced retry.

Development

pnpm test
pnpm typecheck
pnpm build
pnpm pack --pack-destination /tmp/gunner-pack

See the changelog, architecture, and active roadmap.