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

@osdlc/code-host

v0.7.7

Published

The CodeHost port: what a code host (GitHub, Forgejo) answers about pull requests, with GitHub and Forgejo adapters, a host selector keyed on the git remote, doctor auth probes, and PR-reference parsing. Every shell-out goes through an injected command ru

Readme

@osdlc/code-host

The CodeHost port: what a code host must answer about pull requests, plus the GitHub and Forgejo adapters behind it.

Callers that need PR facts (a classifier, a router, an orchestrator) ask the port instead of calling gh or a REST API themselves. Supporting another host means writing a new adapter, not changing every caller.

Install

npm install @osdlc/code-host

ESM only. Node.js ^22.22.2 || ^24.15.0 || >=26.0.0. This is the range of its dependency @osdlc/typed-git, which takes it from hosted-git-info.

pnpm add @osdlc/code-host and yarn add @osdlc/code-host work too.

Quick start

import { selectCodeHost } from '@osdlc/code-host'
import { spawnRunner } from '@osdlc/command-seam'
import { describe, FailureError } from '@osdlc/result'

// Picks the GitHub or Forgejo adapter from the repository's `origin` remote.
const selected = selectCodeHost(process.cwd(), { git: spawnRunner('git'), gh: spawnRunner('gh') })
if (!selected.ok) throw new FailureError(selected.error)
const host = selected.value

const pr = host.getPr(42, { since: null })
if (pr.ok) console.log(pr.value?.title, pr.value?.mergeable)
else console.error(describe(pr.error)) // "gh is not signed in to GitHub. Run `gh auth login`."

host.postComment(42, 'Rebased onto main.')

Tests pass a fake CommandRunner instead, so nothing touches the network.

Failures

A query that can fail returns a Result<T, CodeHostFailure> from @osdlc/result. The failure has a kind to branch on, a message and a hint for a person, the host that failed, and the tool's own output as detail. Both adapters report the same kinds, so a caller handles "not signed in" once.

A declared absence is still a success. getPr of a number that does not exist, and prForBranch of a branch with no PR, return { ok: true, value: null }. On Forgejo, when the comments, reviews or status call inside getPr fails, getPr returns a failure, never a PR with no checks or no reviews.

| kind | Means | hint | | --- | --- | --- | | not-installed | gh or curl is not on PATH | GitHub: install gh and run gh auth login; Forgejo: "Install curl." | | not-authenticated | gh is signed out, or Forgejo answered 401 or 403 | "Run gh auth login." / "Set FORGEJO_TOKEN to a valid token." (the variable forgejoTokenEnv names) | | network | the host could not be reached (DNS, connect, TLS) | "Check your network connection ..." | | not-found | no such repository, or hidden from this account (404) | "Check the repository name ..." | | rate-limited | the API limit was reached (429) | "Wait a few minutes and try again." | | timeout | the tool or request ran out of time | | | http | any other HTTP error status; the status is in status and detail | | | unreadable | the host answered, but the answer could not be read | | | unsupported | the host has no such feature (reviewThreads on Forgejo) | | | no-remote, bad-remote, missing-token | selectCodeHost could not build a Forgejo adapter | | | not-executable, bad-cwd, output-cap, signal, aborted, spawn, exit | the subprocess layer's own kinds, passed through | |

On GitHub the failure's cause is @osdlc/typed-gh's GhFailure. On Forgejo it is @osdlc/command-seam's CommandFailure for a curl that failed.

A mutation (postComment, updateBranch, ...) throws on failure instead. It throws a FailureError carrying the same CodeHostFailure, or a CommandFailed. Both are FailureErrors, so @osdlc/cli-tool's runMain prints them the same way. Three throws are plain Errors instead: setDraft, mergePr and createPr throw CodeHostUnsupported on Forgejo, updateComment throws CommentNotFoundError when the comment is gone (HTTP 404), and GitHub's createPr throws an Error when gh prints a URL naming no PR.

selectCodeHost returns a Result<CodeHost, CodeHostFailure> too (see D-01).

Runtime and platform

Node.js ^22.22.2 || ^24.15.0 || >=26.0.0, ESM only. Bun also runs it, through the compiled dist/. No Bun.* API is used. The GitHub adapter needs the gh CLI on PATH, signed in, at version 2.48 or later: listComments and the review comments getPr folds into activity read every page with gh api --paginate --slurp, and --slurp is new in 2.48. On an older gh, listComments fails and getPr reports no review comments. The Forgejo adapter needs curl and a personal access token in FORGEJO_TOKEN (or the variable named by the forgejoTokenEnv option). Both need git for drift counts. Linux and macOS are the tested platforms.

What is here

| Export | What it is | | --- | --- | | CodeHost | The port: listPrs, listPrDetails, getPr, postComment, updateComment, listComments (optional), setDraft, updateBranch, reviewThreads, mergePr, createPr, parsePrUrl, prForBranch. Every method is synchronous. Queries return a Result | | CodeHostFailure, CodeHostFailureKind | The classified failure the queries report (see Failures) | | CodeHostUnsupported, CommentNotFoundError | The Errors a mutation throws for a verb the code host lacks, and for a deleted comment | | CodeHostPr, PrFacts, Activity, PrInput, ... | The normalized shapes the port speaks (types.ts) | | GithubCodeHost, codeHostPrFrom | GitHub adapter over @osdlc/typed-gh | | ForgejoCodeHost, forgejoPrFrom | Forgejo adapter over curl and the Forgejo REST API. Reads its token from FORGEJO_TOKEN by default. forgejoTokenEnv names another variable | | selectCodeHost, resolveCodeHost, codeHostNameForRemote | Pick the adapter from the git remote. selectCodeHost returns a Result | | githubAuthChecks, forgejoAuthChecks, authChecksFor | The auth checks a doctor command runs | | assemblePrFacts | Adds local-git drift (behind/ahead) to a CodeHostPr | | parsePrInput | Parse a PR argument: a number, #n, owner/repo#n, or a URL (its PrRef keeps the URL's host) |

Boundaries

  • Every shell-out goes through a CommandRunner from @osdlc/command-seam that the caller passes in. selectCodeHost builds a default runner only for curl. Tests pass fakes, so the tests never touch the network.
  • Git and GitHub access goes through @osdlc/typed-git and @osdlc/typed-gh.
  • No verdicts. Classifying a PR stays with the caller; this package only produces the facts it reads.

Not here yet

The port has no write verbs beyond postComment, updateBranch, createPr, setDraft, updateComment and mergePr. The Forgejo adapter does not implement createPr, setDraft or mergePr yet. editPrBody, postReview and replyToThread are the next additions.

When not to use

  • You only target GitHub and want the full API surface: use octokit.
  • You run one-off scripts: call gh directly.
  • You need an async API: every method here is synchronous by design.
  • You need a host other than GitHub or Forgejo (GitLab, Bitbucket): there is no adapter yet.

How it compares

From the author's knowledge, and possibly out of date. octokit is the complete GitHub client, but it covers only GitHub and handles credentials itself. The gh CLI covers GitHub only and has no stable programmatic interface beyond its --json output. This package is a small port with two adapters, so a caller written against CodeHost does not change when the host does. It reads no token for GitHub (gh finds its own). It runs every subprocess through a runner the caller passes in, so callers can be tested offline.

Licence

MIT OR Apache-2.0, at your option. See LICENSE-MIT and LICENSE-APACHE.