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

hooklane

v0.1.0

Published

Composable hook pipelines for coding agents

Readme

Hooklane

Hooklane is a small JavaScript runtime for composing deterministic hook pipelines for coding agents.

The host decides the event and matcher. A Hooklane entry only describes execution:

native hook -> Hooklane entry -> series / parallel -> one native result

Status

This repository is a tested prototype. It currently provides:

  • entry(), series(), and parallel()
  • ordinary async functions as pipeline steps
  • sequential context propagation
  • parallel snapshot isolation and deterministic result joining
  • explicit conflicts when parallel branches rewrite the same input field
  • short-circuiting on deny, block, or continue: false
  • Codex and Claude Code input/output adapters
  • a hooklane run command

It intentionally does not install or edit host configuration yet.

Requirements

  • Node.js 20 or newer

The runtime has no production dependencies.

Installation

npm install --global hooklane

For library usage inside a project:

npm install hooklane

Entry DSL

import { entry, parallel, series } from "hooklane";

import validate from "./validate.mjs";
import audit from "./audit.mjs";
import metrics from "./metrics.mjs";
import finalize from "./finalize.mjs";

export default entry(
  series(
    validate,
    parallel(audit, metrics),
    finalize,
  ),
);

An entry does not declare an event or matcher. Those come from the native hook configuration that launches it.

Step functions

A step is an ordinary async function:

export default async function validate(context) {
  const command = context.current.toolInput.command;

  if (/\brm\s+-rf\b/.test(command)) {
    return {
      decision: "deny",
      reason: "Destructive command detected.",
    };
  }

  return {
    updatedInput: {
      ...context.current.toolInput,
      command: command.trim(),
    },
  };
}

Step names come from named JavaScript functions. A later step can read earlier results:

export default async function finalize(context) {
  const audit = context.results.audit;
  const metrics = context.results.metrics;

  return {
    additionalContext: [
      `Audit: ${audit.status}`,
      `Metrics: ${metrics.status}`,
    ],
  };
}

Context behavior

In series(a, b, c), each step observes the current state produced by all previous steps.

In parallel(b, c), both branches receive the same snapshot. They cannot see each other's in-flight changes. After both finish, their results are joined and made available to the next step.

If two parallel branches return different values for the same updatedInput field, execution fails instead of choosing one nondeterministically.

Canonical result

Steps return a platform-neutral partial result:

{
  decision: "allow" | "ask" | "block" | "deny",
  reason: "...",
  updatedInput: {},
  additionalContext: "..." | ["..."],
  systemMessage: "...",
  continue: true | false,
  stopReason: "...",
  data: {}
}

data is stored in context.results.<step>.data for later steps but is never sent to the host.

The selected host adapter converts the merged canonical result into the event-specific native result.

Codex

Configure one command hook in .codex/hooks.json:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "hooklane run --host codex ./hooks/security.entry.mjs",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

Codex launches the command and writes the event JSON to stdin. Hooklane runs the entry and writes one native result JSON to stdout.

Claude Code

The equivalent command is:

{
  "type": "command",
  "command": "hooklane run --host claude-code ./hooks/security.entry.mjs"
}

Place it under the desired event and matcher in the relevant Claude Code hook configuration.

CLI

hooklane run --host <codex|claude-code> <entry.mjs>

--host is explicit because Codex and Claude Code event payloads are intentionally similar and should not be guessed.

All diagnostic messages go to stderr. Stdout is reserved for the single native JSON result.

Run the example

npm run example:codex
npm run example:claude

Test

npm test

The test suite covers context propagation, parallel joining, input conflicts, short-circuiting, adapter encoding, and full CLI stdin/stdout execution.

Next implementation steps

  • host configuration installer and uninstaller
  • timeout and error policies for individual steps
  • command and HTTP step helpers
  • native output escape hatch
  • additional event codecs and compatibility fixtures
  • prompt, agent, and MCP-backed steps