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

@protocol0/extension-sdk

v0.1.2

Published

Ableton Live extension helper: expose your Ableton Extensions SDK extension's actions as Protocol0 keyboard shortcuts with one call.

Readme

@protocol0/extension-sdk

npm version license

Expose your Ableton Extensions SDK extension's actions to Protocol0 keyboard shortcuts — with one call.

Protocol0 runs a global keyboard hook. If your extension announces its actions, the user can bind any key combo to one of them in the Protocol0 keymapper. When they press the combo, Protocol0 calls your action over localhost HTTP — even when Ableton is not focused.

This package is optional sugar over a plain HTTP + JSON contract (see the integration doc). You can implement that contract by hand in any language; this just removes the boilerplate (HTTP server, /openapi.json, register/unregister, crash-safety).

Install

npm install @protocol0/extension-sdk

Usage

Call exposeToProtocol0 once from your extension's activate():

import { initialize, type ActivationContext } from "@ableton-extensions/sdk";
import { exposeToProtocol0, type Protocol0Handle } from "@protocol0/extension-sdk";

let p0: Protocol0Handle | undefined;

export function activate(activation: ActivationContext) {
  const context = initialize(activation, "1.0.0");

  void exposeToProtocol0({
    name: "my-extension", // namespaces your actions as /action/my-extension/<action>
    actions: {
      randomize_colors: {
        summary: "Randomize the colors of all clips in the set.",
        params: { seed: "integer" }, // string | integer | number | boolean
        handler: async ({ seed }) => {
          await context.withinTransaction(() => {
            // ...recolor using `seed`...
          });
        },
      },
      mute_all: {
        summary: "Mute every track.", // no params → no requestBody in the openapi
        handler: () => {
          for (const track of context.application.song.tracks) track.mute = true;
        },
      },
    },
  }).then((h) => {
    p0 = h;
  });

  // The host has no formal deactivate hook; tear down on process exit.
  process.on("SIGTERM", () => void p0?.close().finally(() => process.exit(0)));
}

That's it. The user can now bind keys to Randomize Colors / Mute All in Protocol0.

What it does for you

  • Starts an HTTP server on an ephemeral 127.0.0.1 port (override with port).
  • Serves GET /openapi.json (the format Protocol0's catalog parser reads) and POST /action/<name>/<action> for each handler.
  • Registers with the Protocol0 agent (POST http://localhost:9010/api/extensions/register) on start and unregisters on close() / process exit. Registration is idempotent soft state — if the agent isn't running yet, it's harmless; re-announce on each activate().
  • Installs uncaughtException / unhandledRejection handlers, because an uncaught error kills the whole Extension Host.

The registerCommand trap

A context-menu command receives a selection Handle (the clicked clip/track). A keyboard-triggered action has no such handle — nothing was clicked. So this SDK exposes a dedicated actions map for context-free, keyboard-bindable actions and deliberately does not auto-expose your context-menu commands.

API

exposeToProtocol0(opts: {
  name: string;                        // unique; namespaces /action/<name>/<action>
  actions: Record<string, ActionDef>;  // your keyboard-bindable actions
  port?: number;                       // default 0 (ephemeral)
}): Promise<Protocol0Handle>;          // { url, close() }

interface ActionDef {
  summary: string;                     // one-line label shown in the keymapper
  params?: Record<string, "string" | "integer" | "number" | "boolean"
                        | { type: ...; required?: boolean }>;
  handler: (args: Record<string, unknown>) => void | Promise<void>;
}

License

MIT