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

@labelbox/recursion-cli

v0.0.65

Published

`recursion` — the Recursion CLI. It mirrors the TypeScript SDK (`@labelbox/recursion-sdk`) exactly: where the SDK is `rl.synthesizers.create(...)`, the CLI is `recursion synthesizers create …`. Dots become spaces; you get `--help` at every level. The shor

Downloads

2,710

Readme

@labelbox/recursion-cli

recursion — the Recursion CLI. It mirrors the TypeScript SDK (@labelbox/recursion-sdk) exactly: where the SDK is rl.synthesizers.create(...), the CLI is recursion synthesizers create …. Dots become spaces; you get --help at every level. The short rl executable remains a permanently supported convenience alias and runs the same command tree; documentation uses the canonical recursion spelling.

recursion --help                     # list nouns (synthesizers, synthesizer-runs)
recursion synthesizers --help        # list verbs (create, get, list, …)
recursion synthesizers create --help # list flags

How it works (fully live, zero per-operation code)

The CLI ships no baked API reference and has no @labelbox/recursion-sdk dependency. On each run it revalidates the manifest from GET /cli/manifest when the server selected by --base-url is reachable (production by default, or staging, or localhost). If the server is unavailable, it falls back only to a locally cached manifest that was previously validated. From that manifest it builds its entire command tree, --help, request/response shapes, and docs browse surfaces (src/manifest.ts). Dispatch is generic (src/dispatch.ts): each request is built straight from the manifest operation's HTTP method + path template + params + body — there is no hand-written command per operation and no baked client.

The result: adding or changing a backend endpoint needs zero CLI release — the live CLI reflects it as soon as the backend deploys. The CLI is re-released only when its own engine code changes. When the server is reachable, the manifest is revalidated on every run via a conditional fetch (ETag / If-None-Match) and cached per base-url under ~/.cache/recursion/. When the server is unreachable, the CLI may use the last locally validated copy so commands remain available offline. Validated fresh HTTP 200 responses use atomic same-directory rename and therefore retain last-network-writer behavior. Replacement preserves an existing file's POSIX mode bits, but deliberately publishes a new inode and does not preserve its ACLs or extended attributes. Publication requires parent-directory write/search permission; if unavailable, the CLI keeps using the validated in-memory result and never falls back to a partial direct write.

Docs browse surfaces

Beyond the executable recursion <noun> <verb> operations, the manifest carries the docs, exposed as one consistent positional shape — recursion <group> [<id>] (bare lists, an id shows that one):

recursion resources [<id>]    # Reference — resource hubs: object shape, operations, recipes
recursion recipes  [<id>]     # How-to — multi-step user-goal guides (--format cli|ts|curl)
recursion explain  [<concept>] # Explanation — concept pages
recursion tutorials [<id>]    # Tutorials — getting-started docs

Install / run

Published to public npm as @labelbox/recursion-cli — no token, no repo access, no setup beyond Node itself.

npm uninstall -g @recursion/cli @labelbox/rl-cli   # no-op unless a pre-rename package is installed
npm install -g @labelbox/recursion-cli   # old packages also own the `rl` alias — EEXIST otherwise
# or, zero-install:
npx --package @labelbox/recursion-cli recursion --help

The CLI is standalone, so this pulls in no @labelbox/recursion-sdk. Full setup steps and install-failure triage live in apps/horizon/docs/public/docs/cli-getting-started.md — that page owns them; don't restate them here.

The CLI is released independently of the SDK (it no longer depends on it): a packages/cli/** change cuts a CLI release via the Release / CLI GitHub Action — see yarn commands release.

From a monorepo checkout, run the bin directly without installing:

yarn workspace @labelbox/recursion-cli build
node ./packages/cli/dist/bin.js --help

Auth

Set LABELBOX_API_KEY in the environment, or pass --api-key <key>. Override the host with --base-url <url> (defaults to the public Recursion API gateway, see DEFAULT_BASE_URL in src/manifest.ts).

Flags

  • Path / query params are individual flags: --environment-id, --limit, … Required path and query params must be passed as flags. A query param whose type is an array or object (e.g. --models, --enrichment-filters) takes a JSON value (--models '["a","b"]'); its help text is tagged [pass as JSON].
  • Operation headers declared by the API are individual flags too. Required concurrency and replay controls therefore appear as --if-match and --idempotency-key and are forwarded under their declared HTTP names.
  • Request body: scalar top-level fields are individual flags (--name, --system-prompt, …); pass the full body — including complex fields like contextInputs / targetFields — with --from-json <file> or --data <json> (mutually exclusive — pass only one). Scalar flags override values from --from-json/--data. A required scalar body field can be supplied by either its flag or the JSON body.
  • Output: prints the result as JSON by default. An operation may declare one scalar response field as its direct output; those commands print only that value in both normal and quiet mode (for example, the handoff-access command prints its ephemeral URL). Otherwise, --quiet prints only the resulting resource's id (a blank line for results without one, e.g. list or no-content operations).
recursion synthesizers get --synthesizer-job-id sj_01HX...
recursion synthesizers create --environment-id env_01HX... --from-json ./body.json
recursion synthesizer-runs trigger --problem-version-id pv_01HX... --from-json ./run.json

The command surface is the live server

There is nothing to regenerate or commit for the CLI — the command surface is revalidated against the target server's GET /cli/manifest on every run when the server is reachable, with a validated local-cache fallback when it is offline. A backend change therefore flows through automatically after deploy with no CLI step. The manifest itself is assembled by yarn generate cli:manifest (included in yarn generate prerequisites) from the spec-derived reference files and embedded into the backend; to add or change a command, change the backend @SdkRoute — not this package.

The engine (manifest fetch + cache + validation, generic dispatch, flag mapping, help formatting, the request-body / returns shape trees, and the docs browse renderers) is verified by src/*.test.ts, which build the program from a fixture manifest in-memory and assert the realized flags + --help + browse output — no committed golden snapshot to maintain.