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

axi-sdk-js

v0.1.8

Published

Shared Node.js primitives for building AXI CLIs

Readme

Every Node-based AXI ends up redoing the same work: top-level dispatch, structured errors, TOON output, and optional hook installation for a few agents.

axi-sdk-js pulls those shared runtime pieces into one package. Your AXI can stay focused on business logic, work with plain JavaScript objects, and let the runtime handle official TOON serialization. If you want agent session context plumbing, wire installSessionStartHooks() into an explicit setup command.

runAxiCli() assumes a command-first CLI shape: <bin> <command> ...args ...flags. Bare --help is still supported, but flags are not allowed before the top-level command.

Every tool built on runAxiCli() also gets a built-in update self-update command for free (alongside --help and -v/--version). See Built-in self-update.

If your executable boundary needs to normalize loader-specific arguments before dispatch, pass argv explicitly to runAxiCli() instead of relying on process.argv.slice(2).

Quick Start

$ npm install axi-sdk-js
added 1 package
import { runAxiCli } from "axi-sdk-js";

await runAxiCli({
  description: "Manage GitHub state in the current repository",
  version: "1.2.3",
  argv: process.argv.slice(2),
  topLevelHelp: TOP_LEVEL_HELP,
  resolveContext: ({ command, args }) =>
    command === "issue" || command === "pr"
      ? resolveRepoFromArgs(args)
      : undefined,
  home: async () => ({
    issues: [{ number: 12, title: "Fix auth bug", state: "open" }],
    help: ["Run `gh-axi issue view <number>` for details"],
  }),
  commands: {
    issue: issueCommand,
    pr: prCommand,
  },
});

Built-in self-update

runAxiCli() reserves update as a built-in command, so every tool gains <tool> update and <tool> update --check with zero per-tool code. <tool> update --dry-run is accepted as an alias for --check.

$ gh-axi update --check
update:
  package: gh-axi
  current: 1.2.3
  latest: 1.3.0
  available: true
help[1]: Run `gh-axi update` to upgrade

$ gh-axi update
running: npm install -g gh-axi@latest
update: gh-axi upgraded 1.2.3 -> 1.3.0
command: npm install -g gh-axi@latest

How it works:

  • Identity is auto-derived. The package name and version are read from the nearest package.json (walking up from the realpath-resolved entrypoint). version from runAxiCli() is preferred when present. No wiring needed.
  • The latest version comes from the registry. It queries https://registry.npmjs.org/<pkg>/latest, falling back to npm view <pkg> version, and compares with proper semver. Network, registry, and not-found failures surface as structured AxiErrors.
  • The upgrade matches the install method, detected from the entrypoint path and environment:
    • npm global -> npm install -g <pkg>@latest
    • pnpm global -> pnpm add -g <pkg>@latest
    • Homebrew (/Cellar/) -> brew upgrade <formula>
    • npx / ephemeral cache -> reports that npx -y <pkg>@latest already runs the latest (print-only)
    • unknown -> prints the recommended command without guessing (print-only)
  • update --check (a/k/a --dry-run) reports current vs latest and whether an update is available, installing nothing. When already on the latest version, update reports up-to-date and exits 0.
  • Discoverability is SDK-owned. Bare --help gets a compact built-in command footer when the tool has not registered its own update, and <tool> update --help shows the command reference.

update is a reserved command name. A tool that registers its own update in commands keeps full control - the built-in never shadows it. Pass packageName to runAxiCli() only as an escape hatch when the package name cannot be derived from package.json:

await runAxiCli({
  // ...other options
  version: "1.2.3",
  packageName: "gh-axi", // optional override; normally auto-derived
});

Reference

axi-sdk-js is a library package. In normal use, runAxiCli() should be the main entry point.

| API | Description | | ------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | runAxiCli() | Shared runtime for command-first dispatch, bare --help/--version fast paths, the built-in update command, lazy context resolution, home header injection, TOON serialization, and errors |

Advanced Exports

Most AXI authors should not need these directly.

| API | Description | | ---------------------------------------- | ----------------------------------------------------------------------------------------------- | | AxiError | Throw structured AXI errors from command handlers | | RESERVED_COMMANDS | SDK-owned built-in command names, currently update | | runUpdate() | The built-in self-update flow (registry lookup, install-method detection, upgrade) | | fetchLatestVersion() | Resolve the latest npm version through the registry endpoint with an npm view fallback | | detectInstallMethod(), planUpgrade() | Inspect an entrypoint path and map it to the upgrade command the built-in updater would use | | compareSemver(), isUpdateAvailable() | Semver helpers used by the updater, including prerelease ordering | | installSessionStartHooks() | Install or repair Claude Code hooks, Codex hooks, and OpenCode ambient context plugins directly | | resolvePortableHookCommand() | Resolve a hook command to a safe binary name or absolute path | | PortableHookCommandContext | Context for resolving portable hook commands | | shouldInstallHooksForNodeAxiExecPath() | Check whether an executable path is safe for hook installation |

Session Hook Setup

runAxiCli() does not install hooks during normal CLI execution. Hook installation should be exposed through an explicit user-invoked setup command, for example my-axi setup hooks.

import { installSessionStartHooks, runAxiCli } from "axi-sdk-js";

await runAxiCli({
  // ...other options
  commands: {
    setup: async (args) => {
      if (args[0] !== "hooks") {
        return {
          error: "Unknown setup command",
          help: "Run `my-axi setup hooks`",
        };
      }

      installSessionStartHooks();
      return { setup: "hooks installed or already up to date" };
    },
  },
});

Calling installSessionStartHooks() without identity options infers the current CLI from process.argv[1]. Packaged entrypoints such as dist/bin/gh-axi.js infer marker: "gh-axi", binaryNames: ["gh-axi"], and a safety policy that skips development TypeScript entrypoints. Pass explicit options when your setup command needs custom behavior:

await installSessionStartHooks({
  marker: "my-axi",
  binaryNames: ["my-axi"],
});

Claude Code and Codex receive native SessionStart hooks, while OpenCode receives a managed plugin in ~/.config/opencode/plugins/ that injects the AXI home view as ambient model context.

Hook Command Portability

Hook commands use a plain binary name such as gh-axi only when that name contains the hook marker and binaryNames resolves through the current PATH to the same executable; otherwise they use the absolute execPath.

For custom wrappers, pass binaryNames: ["my-axi"] to installSessionStartHooks().

Development

Repository contributions targeting main must follow the root contributor workflow. Before pushing SDK changes, run the same package checks that CI runs:

pnpm install # Install workspace dependencies
pnpm run format:check # Check formatting
pnpm run lint # Lint SDK sources and tests
pnpm --dir packages/axi-sdk-js test # Run tests
pnpm --dir packages/axi-sdk-js run build # Build dist output