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

hal-walk

v1.1.0

Published

CLI tool for exploring HAL APIs via HATEOAS link-following

Readme

hal-walk

A CLI tool for exploring hyperlinked APIs through link-following. It records every step as a directed multigraph in a session file, which can be rendered as a diagram or exported as a deterministic path spec.

The idea

There are two phases to building an API integration:

Phase 1: Exploration (non-deterministic). An AI agent navigates an unfamiliar API by following hypermedia links. It reads relation documentation, reasons about what method to use and what data to send, and makes choices about which paths to explore. This is inference-heavy — the agent is building a mental model of the API through progressive disclosure.

Phase 2: Distillation (deterministic). Once the agent has completed a workflow — say, creating a wiki page, editing it, and adding a comment — the entire traversal is recorded in the session graph. The export command extracts the path as a declarative spec: a sequence of steps with exact relations, methods, and input shapes. This spec can be executed by a simple runner with no LLM involved.

The CLI is the bridge between these two phases. It gives the agent a structured way to explore (every action is recorded) and a way to crystallize what it learned into reusable, deterministic code.

Progressive disclosure for APIs

Traditional API clients need complete knowledge upfront — an OpenAPI spec, a client library, hardcoded URLs. hal-walk takes the opposite approach:

  1. npx hal-walk start — the agent sees only the root resource and its links
  2. npx hal-walk describe — the agent reads the documentation for a link relation (a markdown prompt file served by the API)
  3. npx hal-walk follow — the agent acts on what it learned
  4. Repeat — each response reveals new links to explore

The agent never needs a complete map of the API. It discovers capabilities incrementally, just like a human clicking through a website. The difference is that every click is recorded, and the recording can be compiled into a repeatable workflow.

Usage

All commands output JSON to stdout (except describe, which outputs markdown, and render, which outputs Mermaid). Errors go to stderr.

Start a session

npx hal-walk start -s session.json https://agent-wiki.mikekelly321.workers.dev/

Fetches the root resource, creates a session file, and stores any CURIE definitions.

Explore available links

npx hal-walk position -s session.json

Shows the current position, the stored HAL response, and all available link relations.

Read relation documentation

npx hal-walk describe -s session.json wiki:v1:create-page

Expands the CURIE and fetches the relation's documentation — a markdown file describing the method, input schema, and expected response. This is what the agent reads to figure out how to use a link.

Follow a link

# GET (default)
npx hal-walk follow -s session.json wiki:v1:pages \
  --note "List all pages to see what exists"

# POST with body and schema (method inferred from --body)
npx hal-walk follow -s session.json wiki:v1:create-page \
  --body '{"title": "My Page", "body": "Content here"}' \
  --body-schema '{"type":"object","properties":{"title":{"type":"string","description":"Page title"},"body":{"type":"string","description":"Page content (markdown)"}},"required":["title","body"]}' \
  --note "Create a new wiki page"

# Templated link with URI template values
npx hal-walk follow -s session.json wiki:v1:version \
  --uri-template-values '{"vid": "2"}'

# Explicit method override
npx hal-walk follow -s session.json wiki:v1:edit-page \
  --method PUT \
  --body '{"body": "Updated content"}' \
  --note "Update page body with corrections"

The --body-schema flag captures the JSON Schema the agent learned from the relation docs (via describe). This preserves the contract — required vs optional fields, types, descriptions — in the session log and exported path specs. If omitted, a basic schema is auto-inferred from the body data.

The body is validated against the schema before sending. If they don't match, the command fails with a descriptive error.

The --note flag provides a brief, human-readable description of why this step is being taken — semantic breadcrumbs that make the session graph self-documenting.

Navigate the session graph

# Jump back to a previous position (local, no HTTP request)
npx hal-walk goto -s session.json p1

Visualize the traversal

npx hal-walk render -s session.json

Outputs a Mermaid diagram of the session graph:

graph LR
  p1["/\n(p1)"]
  p2["/pages\n(p2)"]
  p3["/pages\n(p3)"]
  p1 -->|"wiki:v1:pages\nGET"| p2
  p2 -->|"wiki:v1:create-page\nPOST"| p3

Export a deterministic path spec

npx hal-walk export -s session.json
npx hal-walk export -s session.json --from p1 --to p5

Extracts the shortest path between two positions and outputs a declarative workflow spec:

{
  "name": "exported-path",
  "entryPoint": "https://agent-wiki.mikekelly321.workers.dev",
  "steps": [
    { "id": "step1", "action": "start", "url": "/" },
    {
      "id": "step2", "action": "follow", "from": "step1",
      "relation": "wiki:v1:pages", "method": "GET",
      "note": "List all pages to see what exists"
    },
    {
      "id": "step3", "action": "follow", "from": "step2",
      "relation": "wiki:v1:create-page", "method": "POST",
      "note": "Create a new wiki page",
      "input": {
        "body": { "title": "My Page", "body": "Content" },
        "bodySchema": {
          "type": "object",
          "properties": {
            "title": { "type": "string", "description": "Page title" },
            "body": { "type": "string", "description": "Page content (markdown)" }
          },
          "required": ["title", "body"]
        }
      }
    }
  ]
}

This spec contains no ambiguity. The bodySchema preserves the contract the agent learned during exploration — a developer reading the export can see which fields are required, their types, and descriptions. The body is an example. The note on each step explains the agent's intent. A runner executes each step mechanically, using the schema to understand the input contract and prompting for values at each step that needs them.

Inspect the session visually

npx hal-walk session-viewer -s session.json

Opens a web UI on a free port showing:

  • The session graph rendered with Mermaid (positions as nodes, transitions as edges)
  • Current position highlighted
  • Click a node to inspect the HAL response
  • Click an edge to see the transition details: relation, method, note, URI template values, body schema, body data, headers

Also exposes GET /api/session returning the raw session JSON.

Session file

The session is a JSON file representing a directed multigraph:

  • Positions — nodes in the graph, each storing the URL, HTTP method, status code, and full HAL response
  • Transitions — directed edges labeled with the link relation, method, and any input data
  • CURIEs — stored from the root response so the CLI can expand wiki:v1:pages to its documentation URL throughout the session

The graph structure means the agent can explore branching paths (via goto to revisit earlier positions) and the export can find optimal paths through BFS.

How an agent uses this

An LLM agent operating hal-walk doesn't need prior knowledge of the target API. A typical session:

  1. Start at the root — see what links are available
  2. Describe an interesting relation — read the markdown to understand method, input, behavior
  3. Follow the relation — provide the body schema (from docs), the body data, and a note explaining the intent
  4. Observe the response — see new links that weren't visible before
  5. Repeat until the task is done
  6. Export the successful path — produce a spec that preserves schemas, example data, and semantic notes

The agent's inference is only needed during exploration. The exported artifact is pure data.