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

@datalabrotterdam/nova-ai-cli

v1.1.0

Published

CLI for DataLab Rotterdam's Nova AI, with an Agent Client Protocol mode for editors/IDEs, backed by @datalabrotterdam/nova-sdk

Downloads

359

Readme

@datalabrotterdam/nova-ai-cli

CLI for DataLab Rotterdam's Nova AI — also speaks Agent Client Protocol

npm version npm downloads license ACP issues

Talk to DataLab Rotterdam's Nova AI from your terminal, or point your editor/IDE at it via Agent Client Protocol — both modes share the same auth and run on @datalabrotterdam/nova-sdk.

npm · Issues · ACP docs

⚠️ Work in progress. ACP mode (--acp) is the only fully implemented mode today — agentic tool use, permissions, and session persistence all work there. Interactive terminal chat (no flags) and the standalone browser UI (--web) are stubs that print a "not built yet" message. Expect breaking changes before a 1.0.


Installation

No install needed — run directly with npx:

npx @datalabrotterdam/nova-ai-cli --setup   # store your Nova API key
npx @datalabrotterdam/nova-ai-cli           # interactive chat (WIP, stub)
npx @datalabrotterdam/nova-ai-cli --acp     # speak ACP over stdio (editors/IDEs) — fully working
npx @datalabrotterdam/nova-ai-cli --web     # standalone browser UI (WIP, stub)

Or install globally / as a project dependency:

npm install -g @datalabrotterdam/nova-ai-cli

Requires: Node.js >= 18, a Nova AI API key.


Overview

nova-ai-cli is a terminal client for Nova AI, in the same spirit as claude/codex. Pass --acp to run it in Agent Client Protocol mode, where it reads JSON-RPC requests from stdin and writes responses/notifications to stdout so any ACP-aware editor/IDE can drive it like any other coding agent — with tool calling, permission prompts, and persisted session history. Bare/--web modes are placeholders for now. All modes share the same stored credentials.

# 1. one-time setup — opens a browser page to verify the key against Nova AI and store it locally
npx @datalabrotterdam/nova-ai-cli --setup

# 2. point your ACP client at this binary
npx @datalabrotterdam/nova-ai-cli --acp

Most editors invoke --acp for you once configured as an agent — --setup is the one command you run by hand first.

Status: --setup and --acp (including tool calling and session persistence) are fully implemented. Interactive terminal chat (no flags) and --web are stubs — see the WIP note above.


Auth

This agent advertises Agent Auth (per AUTHENTICATION.md): when the client calls authenticate, the agent itself spins up a local HTTP server, opens your browser to it, and resolves once you've connected your account.

{
  "id": "nova-api-key",
  "name": "Nova API Key"
}

Today the page served at that local URL is a small Svelte form that:

  1. Collects your Nova API key.
  2. Validates it against client.models.list().
  3. Picks a default model (first enabled model) and stores { apiKey, defaultModel } in ~/.nova-ai/credentials.json.

You can also trigger this manually:

npx @datalabrotterdam/nova-ai-cli --setup

Overrides, no browser flow required:

| Env var | Purpose | |---|---| | NOVA_API_KEY | Skip stored credentials, use this key | | NOVA_MODEL | Skip stored default model, use this model id |

A future version will swap this for real OAuth once DataLab Rotterdam ships an OAuth provider for Nova AI — same local server (src/acp/auth-server.ts), same lifecycle, just a different page/flow. Credential handling stays isolated in src/acp/credentials.ts either way.


What it implements

| ACP method | Behavior | |---|---| | initialize | Returns protocol version + the nova-api-key agent auth method | | session/new | Allocates a session id with in-memory history | | session/load | Restores a previously-persisted session and replays its turns as *_message_chunk notifications | | session/list | Lists stored sessions, optionally filtered by cwd | | authenticate | Runs the local browser auth flow (src/acp/auth-server.ts) and resolves once a valid key is stored | | session/prompt | Streams a chat.completions.stream() call, forwarding agent_message_chunk updates as text arrives; drives the tool-calling loop below | | session/cancel | Aborts the in-flight Nova AI request via AbortController |

Only text and resource_link content blocks are read from prompts today — images/audio/embeddings supported by nova-sdk aren't wired up yet.

Sessions are persisted to disk (src/acp/sessions.ts) so session/load can rehydrate history, and a title is auto-derived from the conversation.

Tool calling

While streaming a response, the agent watches for a fenced tool-call marker in the model's output (src/acp/tools/marker.ts). When one appears, it stops streaming text and instead:

  1. Reports the pending call via session/update (tool_call with status pending).
  2. Requests permission from the client for any mutating tool (allow_once / reject_once), via session/request_permission.
  3. Executes the tool and reports the result/error via a tool_call_update.
  4. Feeds the tool result back into the conversation and loops (up to 10 rounds per prompt) until the model produces a plain answer.

Built-in tools (src/acp/tools/registry.ts):

| Tool | Mutating | Behavior | |---|---|---| | read_file | No | Reads a file's contents, gated by client fs.readTextFile capability | | write_file | Yes | Writes/overwrites a file, gated by client fs.writeTextFile capability — requires permission | | run_command | Yes | Runs a shell command in the session's cwd — requires permission |

Tools are filtered per-session by the client's advertised clientCapabilities, so a client without filesystem support never sees read_file/write_file offered.


Development

npm install
npm test      # tsc --noEmit + node --test on tests/
npm run build # builds the Svelte setup page, then tsc -> dist/

Releases are automated via semantic-release on push to main (see .github/workflows/ci.yml); commit messages drive version bumps.


License

Apache-2.0 © DataLab Rotterdam