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

nanoclip

v0.1.5

Published

Official CLI for the NanoClip API — upload footage, quote and approve billed analyses, fetch data packages.

Readme

nanoclip

The official command-line client for the NanoClip API. Upload footage, get an exact quote before anything is billed, approve and dispatch analyses (transcript, vision, retake-removal) one line item at a time, and collect the finished data packages.

nanoclip speaks JSON on stdout and nothing else there — built for scripts and agents first, humans second.

Install

No install needed to try it:

npx nanoclip --version

Or install it globally:

npm i -g nanoclip

Requires Node.js >= 22. ffmpeg and ffprobe must be on PATH for local media preflight and normalization — see System dependencies below.

Authenticate

Don't have a key yet? Run auth login with no arguments — it prints where to create one:

nanoclip auth login          # prints the sign-in link; add --open to launch a browser

Then come back with the key:

nanoclip auth login --key <your-api-key>

This verifies the key live against the API and writes it to ~/.nanoclip/config.json (mode 0600), along with a cached snapshot of your workspace, scopes, and account limits. Everything else reads from this profile.

nanoclip auth status    # offline — reads the cache, no network call
nanoclip auth logout    # removes the active profile

Multiple profiles are supported via --profile <name> on login/logout, or the NANOCLIP_PROFILE env var when running a command.

The golden path

# 1. Upload footage. Output includes the server-probed duration — the billing basis.
nanoclip upload ./interview.mp4
# -> {"project_id": "proj_abc123", "duration": 612.4, ...}

# 2. Quote before you spend anything. Read-only — this never charges.
nanoclip quote -p proj_abc123 --transcript --vision
# -> {"line_items": {"transcript": 102, "vision": 60}, "total_cents": 162, "total_usd": "1.62", ...}

# 3. Dispatch each billed analysis with its own exact approval.
nanoclip transcript start -p proj_abc123 --language en --approve 1.02
nanoclip vision start -p proj_abc123 --approve 0.60

# 4. Collect the result — poll until it's done, write it to disk.
nanoclip transcript get -p proj_abc123 --wait -o transcript.json

You can also get an early, non-final estimate before uploading anything:

nanoclip quote --source ./interview.mp4 --transcript --vision
# -> {"estimate": true, "basis": "local_probe", ...}

Agent-first output convention

Every command writes one JSON document to stdout (an object, trailing newline, nothing else on that stream) and one human-readable summary line to stderr. No tables, no spinners, no interactive prompts. This makes every command safe to pipe, parse, and script:

project_id=$(nanoclip upload ./clip.mp4 | jq -r .project_id)

Errors follow the same rule — structured JSON on stdout, one line on stderr, then the process exits with a code from the taxonomy below:

{"error": {"reason": "approval_insufficient", "message": "...", "status": 402, "detail": {...}}}

Exit codes

| Code | Meaning | |---|---| | 0 | success | | 2 | input error — bad arguments, missing/invalid file, refused approval amount, 4xx validation | | 3 | auth — missing or invalid API key, HTTP 401/403 | | 4 | payment required — HTTP 402. Full stop; nothing overrides it; the request is never retried | | 5 | API/network — timeouts, connection errors, 5xx after retries |

The spend gate

No command both quotes and charges. quote is always read-only. Every command that actually dispatches a billed analysis — transcript start, vision start, retake-removal start — requires its own --approve <USD>, and refuses (exit 2, nothing sent) if the live price at dispatch time exceeds that amount by even a cent. There is no account-level spending threshold and no "trust me" flag: every charge, tiny or large, is approved explicitly on the command line, so it's visible in full in any shell history or agent transcript.

nanoclip transcript start -p proj_abc123 --language en --approve 1.02
# live cost recomputed at dispatch time; > $1.02 -> refused before any request fires

Commands

| Command | What it does | |---|---| | nanoclip auth login [--open] | Print (and optionally open) the link to create an API key | | nanoclip auth login --key <key> [--base-url <url>] [--profile <name>] | Verify a key and store it | | nanoclip auth status | Show the active profile, offline | | nanoclip auth logout [--profile <name>] | Remove a stored profile | | nanoclip me | Live account info: workspace, scopes, balance, pricing, limits | | nanoclip doctor | Check connectivity, key validity, and ffmpeg/ffprobe presence | | nanoclip upload <video> | Preflight, normalize if needed, and upload a video or audio file | | nanoclip quote -p <id> \| --source <video> [--transcript] [--diarize] [--vision] [--retake-removal] | Price one or more analyses, read-only | | nanoclip transcript start -p <id> --language <tag> [--diarize] --approve <USD> | Dispatch a billed transcript analysis (see Languages) | | nanoclip transcript get -p <id> [--wait] [-o <file>] | Collect a transcript analysis | | nanoclip vision start -p <id> --approve <USD> | Dispatch a billed vision analysis | | nanoclip vision get -p <id> [--wait] [-o <file>] | Collect a vision analysis | | nanoclip retake-removal start -p <id> --language <tag> --approve <USD> | Dispatch a billed retake-removal analysis | | nanoclip retake-removal get -p <id> [--wait] [-o <file>] | Collect a retake-removal analysis | | nanoclip status -p <id> | Project status plus every analysis's current status in one call | | nanoclip api <method> <path> [--input <file>\|-] | Raw authenticated request to any API endpoint | | nanoclip --version | Print {name, version} | | nanoclip --help, nanoclip <command> [<subcommand>] --help | Print the command surface (-h works too) |

Every command documents itself. nanoclip --help lists the whole surface, and nanoclip <command> --help (or nanoclip <command> <subcommand> --help) gives that command's flags — as JSON on stdout for a program to read, and as readable usage on stderr for you:

nanoclip transcript start --help
# stdout: {"name":"start","usage":"nanoclip transcript start --project <id> --approve <USD> ...
# stderr: the same surface, formatted to read

The JSON is generated from the same argument definitions the commands parse with, so it always matches what the CLI actually accepts.

get for any analysis: --wait polls until the analysis reaches a terminal status; -o <file> additionally writes the collected data package to a file. A failed analysis is still a successful collection — the failure is in the payload, not the exit code. Collecting an analysis that was never dispatched exits 2 with reason not_started.

Languages

transcript and retake-removal take a --language <tag> — a base tag, lowercase, no region subtag (en, not en-US). The language is stated, never detected from the audio. Supported:

bg cs da de el en es et fi fr he hr hu it lt lv mt nl pl pt ro ru sk sl sv uk

A tag outside that set is refused before any network call (exit 2, unsupported_language). vision takes no language — it looks at pixels, not speech.

System dependencies — doctor

ffmpeg and ffprobe are spawned as system binaries, never bundled. upload uses ffprobe to preflight a file (container, codec, size) before sending a single byte, and spawns ffmpeg to normalize a file into an accepted format when needed. Run:

nanoclip doctor

to check config validity, API key validity, live connectivity, and whether both binaries are on PATH, in one call.

Environment variables

Every value below overrides the corresponding entry in ~/.nanoclip/config.json for the current process — nothing else reads or writes outside that one file.

| Variable | Overrides | |---|---| | NANOCLIP_API_KEY | The active profile's API key | | NANOCLIP_BASE_URL | The active profile's API base URL | | NANOCLIP_PROFILE | Which profile is active | | NANOCLIP_CONFIG_DIR | Where the config file lives (default ~/.nanoclip) |

License

MIT