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

@ebay-dt/bonfire-node

v0.1.0

Published

Node.js adapters for Bonfire.

Downloads

813

Readme

@ebay-dt/bonfire-node

Node.js adapters for Bonfire. It provides an injectable GitHub CLI client for identity lookup and web/device-login startup, safe prototype catalog discovery, and development-only local prototype lifecycle services from an explicit repository root.

The client invokes gh with argument arrays, captures both output streams, returns a safe device URL, and classifies missing, unauthenticated, and unknown failures without exposing command output or credentials. Configure the GitHub hostname per application; the adapter does not assume a particular host.

PrototypeCatalog scans the conventional src/app/(prototypes) root, reads validated metadata.json documents, skips invalid entries safely, and returns path-free summaries. Pass an explicit repositoryRoot; catalog operations do not use ambient working-directory discovery.

The Next.js integration creates the GitHub CLI client and catalog automatically. Applications can provide a GitHubCliClientLike implementation to createBonfireNext for controlled testing.

Lifecycle runtime context

Lifecycle services use explicit repository and prototype roots, with origin and main as the default remote and primary branch. Repository mutations are serialized by one HMR-safe, process-global gate per canonical repository path. A competing mutation returns repository-busy immediately rather than waiting. The gate covers the supported local Node process only; coordination across multiple processes or machines is not provided.

Deployment provider

Deployment is an optional development capability. Configure the generic provider only in a server-only host module with a complete HTTP endpoint; never expose the endpoint or provider to browser code:

import { createDeploymentProvider } from "@ebay-dt/bonfire-node";

const deploymentProvider = createDeploymentProvider({
  endpoint: process.env.BONFIRE_DEPLOYMENT_ENDPOINT!,
  timeoutMs: 120_000,
});

The provider sends exactly { applicationId, login }. Bonfire supplies the application ID from trusted application configuration and the login from the verified authenticated identity; instances never provide owner/branch values. The application ID must exactly match the application's DT deployment-service registration; Bonfire does not validate that registration locally. A mismatch is returned as a safe deployment failure rather than exposing provider details. The documented success response is returned with HTTP 201 and contains repository, ref, commitSha, sourceFileCount, project, deployed, deploymentId, url, and readyState. readyState is one of BLOCKED, BUILDING, CANCELED, ERROR, INITIALIZING, QUEUED, or READY. HTTP 201 means deployment creation succeeded, not that the preview is ready. A failure response contains repository, optional ref, commitSha, project, and stage, plus deployed: false, statusCode, and details; those diagnostics are validated and then intentionally hidden behind a safe provider error.

The provider preserves the deployment ID and reported ready state, but Bonfire does not poll for later status. Provider failures are reduced to safe typed lifecycle errors; response diagnostics, credentials, Vercel credentials, and deployment-target selection remain outside Bonfire in the deployment service. If the deployment service exposes a registration-specific status, hosts may map it to a generic message such as “Deployment is not configured for this application.” They should not infer that classification from an arbitrary failure or forward provider response bodies, endpoint details, repository or branch data, or filesystem diagnostics to the browser. The provider validates the endpoint, response, HTTPS preview URL, and timeout without exposing service details to the browser.

Prototype shape and duplication

Duplicate sources must contain valid metadata.json plus regular, nonsymlink page.tsx, app.tsx, and app.module.css files. Sources with the legacy page.module.css shape or missing canonical files are rejected; missing implementation files are never synthesized. A source components/ directory is optional and validated recursively. Destination metadata, tsconfig.json, and css-modules.d.ts are regenerated, while canonical implementation and component files are copied byte-for-byte.

Preparing prototype-local files

A trusted server host may provide one preparePrototypeFiles callback when constructing LocalPrototypeLifecycle. It receives a validated, normalized, read-only request for the new destination and may write files only inside that destination:

import { writeFile } from "node:fs/promises";
import { join } from "node:path";
import { LocalPrototypeLifecycle } from "@ebay-dt/bonfire-node";

const lifecycle = new LocalPrototypeLifecycle({
  repositoryRoot,
  preparePrototypeFiles: async (request) => {
    await writeFile(join(request.prototypePath, "instructions.md"), "...");
  },
});

The callback runs once after scaffold or duplication and before the initial path-scoped commit. Bonfire validates the destination afterward, includes valid callback files in the commit, and removes the newly owned destination if preparation or validation fails. A commit or push failure preserves the completed destination. The default callback is a no-op.

LocalPrototypeLifecycle.getDirtyState validates the authenticated owner and prototype reference, then returns a clean or dirty observation based only on Git status within that prototype path. LocalPrototypeLifecycle.save creates a local, path-scoped checkpoint without pushing; .discard restores tracked files and removes untracked files within that path. LocalPrototypeLifecycle.create, .duplicate, .edit, and .delete return typed results and serialize repository mutations through one process-local operation gate. Edit updates only title, description, and updatedAt while preserving the existing ref/URL. Delete removes the complete owned prototype directory, including uncommitted files, after ownership and path validation. These operations prepare the authenticated identity branch when automatic switching is enabled; BF_DISABLE_AUTO_BRANCH_SWITCH=true disables every automatic switch and leaves the current branch untouched. Git remains behind the Node-owned repository adapter, and simple-git is not part of the public API.

This is a server-only host extension: it must not perform repository-wide projection, package installation, skills or MCP setup, or write outside the prototype destination. Host-specific form fields and metadata require separate contracts.

Dirty observation is available from the separate @ebay-dt/bonfire-node/watcher subpath. It shares one configured Chokidar watcher across prototype subscribers, debounces filesystem events, and reports only clean/dirty transitions. The watcher subpath is intentionally separate so importing @ebay-dt/bonfire-node does not load Chokidar.

Agent launch preferences

PrototypeAgentService stores a user's selected Claude Code terminal at <prototypeRoot>/<login>/preferences.json, using the explicit runtime context provided by the host. This is a local preference file, not prototype source: consuming applications must add their prototype-root preference pattern to .gitignore, for example:

/src/app/(prototypes)/*/preferences.json

The service writes the file atomically and only after authenticated ownership and command preflight have succeeded. Cursor launching requires cursor on the Bonfire server process's inherited PATH. Claude Code launching requires claude and, on macOS, osascript on that PATH; the service checks these commands without executing them. GUI-launched Node processes may have a different PATH from an interactive shell, so restart Bonfire after changing shell profiles.

Claude Code supports the explicit terminal values terminal (Terminal.app), iterm (iTerm2), and warp (Warp). Unsupported platforms, missing commands, missing preferences, ownership failures, and launch failures are returned as safe typed results; raw process output and absolute paths are never public results. No skill, clipboard fallback, or copy/paste setup flow is involved. Production hosts must not construct the service or expose its local preference store.

From the repository root, use Turbo filters so package dependencies are prepared in dependency order:

pnpm exec turbo run lint --filter=@ebay-dt/bonfire-node
pnpm exec turbo run check --filter=@ebay-dt/bonfire-node
pnpm exec turbo run test --filter=@ebay-dt/bonfire-node
pnpm exec turbo run build --filter=@ebay-dt/bonfire-node