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

@voicethere/cli

v0.10.0

Published

VoiceThere cloud CLI — login, projects, and agent bundle upload

Downloads

1,929

Readme

@voicethere/cli

VoiceThere cloud CLI for API login, project management, and agent bundle upload.

Website: voicethere.io

Requires Node.js 22+.

Release flow: build upload stores a bundle in history; build promote <buildId> sets the active build in the control plane only; deploy --wait promotes (if needed) and rolls out to cloud runners.

Install

npm install -g @voicethere/cli

Or run without a global install:

npx @voicethere/cli <command>

Debugging

Commands print resolved paths on stderr at startup:

[voicethere] project: 550e8400-… (project config (/path/.voicethere/config.json))
[voicethere] bundle: /path/to/dist/agent.js (project config (/path/.voicethere/config.json))

Use this when a command fails to confirm which project and bundle file were picked up.

Project selection

The CLI remembers the active project in .voicethere/config.json (safe to commit — no API keys).

| Situation | What happens | | ------------------------------- | ---------------------------------------------------------------------------------------- | | Config file present | build upload, build list, build promote use its project_id automatically | | No config, interactive terminal | projects use shows a numbered project picker | | No config, CI / script | Run voicethere projects use <projectId> once (or commit config from projects create) |

You do not need to run projects use on every command when the config file is already in the repo.

Typical workflow

1. One-time login (per machine)

Credentials live in ~/.config/voicethere/credentials.json (mode 0600) — not in your agent repo. Never put API keys in .voicethere/config.json.

Default — browser login (recommended for interactive machines):

voicethere login
# Opens the dashboard approval page, then stores a personal API key (vthu_…)
# and active organization. If a project is linked in .voicethere/config.json,
# login also checks that your account can access that project.

| Flag | Behavior | | ------------------ | ----------------------------------------------------------------------- | | (none) | Validate existing credentials; skip if they still work (see below) | | --force | Start a new browser authorization even when local credentials are valid | | --no-open | Print the verification URL and user code; do not open a browser | | --api-base <url> | Override API base for this login (also honored from env / saved file) |

If credentials already work, voicethere login skips creating another authorization:

  • With a linked project (.voicethere/config.json): requires a successful project fetch.
  • Without a linked project: requires a successful project list.
  • Auth failures (401 / 403 / 404 / TOS not accepted) start browser login again.
  • Network / server errors abort without rewriting credentials — fix connectivity, or use --force.

Manual API key login (CI, automation, or when you already have a key):

voicethere login --api-key vth_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
# personal key for org/account commands (dashboard Settings → API keys):
voicethere login --api-key vth_… --user-api-key vthu_…
# staging / custom API host:
voicethere login --api-key "$VOICETHERE_API_KEY" --api-base https://app.voicethere.dev/api/v1

Default API base: https://app.voicethere.dev/api/v1

Credentials & environment precedence (env wins over the credentials file):

| Variable | Overrides | | ----------------------------- | ------------------------------------------------- | | VOICETHERE_API_KEY | Org / project API key (vth_ / vthc_) | | VOICETHERE_USER_API_KEY | Personal API key (vthu_) | | VOICETHERE_API_BASE | API base URL | | VOICETHERE_ORG_ID | Active organization for personal keys | | VOICETHERE_CREDENTIALS_PATH | Credentials file location (tests / isolated runs) | | VOICETHERE_PROJECT_CONFIG | Path to .voicethere/config.json |

After browser login, if those env vars are set, the CLI prints a warning that they override the newly saved file. Personal-key requests send x-voicethere-org-id when an active org is selected (orgs use).

Security notes

  • Credentials file is written atomically with mode 0600.
  • Browser login mints a personal key (vthu_), clears any stored org/project api_key from the credentials file (so interactive commands use the new personal key), and does not put secrets in project config. Explicit VOICETHERE_API_KEY / VOICETHERE_USER_API_KEY remain authoritative when set — browser login aborts if those env vars are present so a saved key cannot silently lose to a broken env override.
  • After approval, the CLI verifies a linked project with the minted personal key + returned active org before reporting success.
  • --force replaces the local personal key for this machine; it does not revoke keys on other devices.
  • Linked-project mismatch: the CLI keeps .voicethere/config.json unchanged and fails login (nonzero) if the new personal key cannot access that project.
  • Prefer personal keys over the legacy --dashboard-cookie path.

More detail: CLI login guide on the VoiceThere docs site.

2. New agent repo — create project and commit config

From your agent project root (where you build dist/agent.js):

npm install @voicethere/agent
npx @voicethere/agent build

# Creates the cloud project and uses it (.voicethere/config.json)
voicethere projects create "My Voice Agent"

git add .voicethere/config.json
git commit -m "chore: use VoiceThere project"

3. Upload a build (store artifact)

Upload stores a new immutable build in history — it does not go live yet.

voicethere build validate    # optional; uses config bundle or dist/agent.js
voicethere build upload -m "Add Spanish greeting and fix barge-in"

-m / --message is like a git commit message: a short label so you can tell builds apart in build list and the dashboard.

4. Promote a build (set active in control plane)

Promote sets the active build in the VoiceThere control plane only. To roll out to cloud runners, run voicethere deploy --wait (promote + cluster rollout in one step).

Pass the build UUID from build upload or build list, or omit it in an interactive terminal to pick from a list:

voicethere build list
voicethere build promote <build-uuid>
# interactive: voicethere build promote

Typical release loop:

npx @voicethere/agent build
voicethere build upload -m "v0.2 — shorter silence timeout"
voicethere build promote <build-uuid-from-upload-or-list>

5. Clone an existing repo (config already in git)

git clone <your-agent-repo>
cd <your-agent-repo>
voicethere login --api-key "$VOICETHERE_API_KEY"

npx @voicethere/agent build
voicethere build upload
voicethere build list
voicethere build promote <build-uuid>

No projects use needed — the active project travels with the repo.

6. Use a different cloud project

voicethere projects list
voicethere projects use <uuid> --slug my-agent --bundle dist/agent.js
git add .voicethere/config.json && git commit -m "chore: use VoiceThere project"

Re-run voicethere projects use with no args to confirm the current project (reads existing config).

Inspect the selection anytime:

voicethere projects show

7. CI / automation

With committed .voicethere/config.json (typical agent repo):

voicethere login --api-key "$VOICETHERE_API_KEY"
npx @voicethere/agent build
voicethere build upload -m "$GITHUB_SHA — $GITHUB_REF_NAME" --skip-validate
voicethere build promote <build-uuid-from-upload>

No projects use step — the config file is the active project.

Without a config file (one-off job cwd):

voicethere login --api-key "$VOICETHERE_API_KEY"
voicethere projects use <project-uuid>
npx @voicethere/agent build
voicethere build upload --skip-validate
voicethere build promote <build-uuid-from-upload>

Other CI notes:

  • Credentials: VOICETHERE_CREDENTIALS_PATH for isolated test runs
  • Config override: VOICETHERE_PROJECT_CONFIG=/path/to/config.json

Split upload and promote across jobs if you want a human approval gate between them.

8. Deploy to cloud runners

voicethere deploy --wait promotes the build (when needed) and rolls out to cloud runners, blocking until the deployment is active (or failed).

voicethere build upload -m "v0.2 — shorter silence timeout"
voicethere deploy --wait
# or pin a build: voicethere deploy --wait --build-id <build-uuid>

Use build promote alone when you only need to update the control plane (e.g. smoke tests); use deploy --wait for anything that must run on staging runners.

Repo config (version control)

Per-agent-repo file: .voicethere/config.json

| Field | Purpose | | ---------------------- | --------------------------------------------- | | project_id | Active platform project UUID | | project_slug, name | Human-readable metadata (optional) | | bundle | Default bundle path (default dist/agent.js) |

Secrets stay global: ~/.config/voicethere/credentials.json (from voicethere login).

Example: .voicethere/config.json.example

Commands

| Command | Description | | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------- | | login [--force] [--no-open] [--api-base <url>] | Browser device login (default); skip if credentials still work | | login --api-key <key> [--user-api-key <vthu>] [--api-base <url>] [--dashboard-cookie <cookie>] | Manual key login (CI / automation); optional personal key | | orgs list | List organizations (* = active); requires user API key or legacy cookie | | orgs use <orgId> | Set active organization (persists active_org_id for user keys) | | org transfer-ownership <userId> | Transfer org ownership (owner only) | | account deletion preview | JSON preview of owned orgs + deletion job | | account deletion request-code | Email 6-digit deletion verification code | | account deletion confirm <code> [--wait] | Queue account deletion; --wait blocks until teardown completes | | projects list | List org projects | | projects create <name> [--slug <slug>] | Create project; uses it (writes config) | | projects use [projectId] | Use project (picker or existing config when omitted) | | projects show | Print .voicethere/config.json | | projects delete [projectId] [--force] [--wait] | Delete project + builds (type name to confirm, or --force; --wait polls async deletion) | | projects settings list | set Runner pool settings (warm pool, scale-down) | | projects session-settings list | set WebRTC idle timeout + crash error message (see below) | | projects conversation list [--q] [--json] | Stored voice transcripts; --q searches turn text or session id | | projects conversation get <sessionId> | Full turn timeline for one session | | projects conversation search <query> | Alias for conversation list --q | | projects logs list [--session] [--level\|--severity] [--q] [--json] | Searchable agent logs; use --severity error for session failures (dual-written) | | projects voice catalog | show STT/TTS vendors and models | | build list | Builds for the active project | | build validate [file] | Sandbox verify (default bundle from config) | | build upload [file] [-m <msg>] | Upload to active project | | build promote [buildId] | Promote on active project (picker when omitted in TTY) | | deploy [--wait] [--build-id] | Promote (if needed) + cloud rollout; --wait blocks |

Logging

Progress and resolved paths go to stderr as [voicethere] … so stdout stays clean for JSON/tables (scripts can pipe stdout).

| Mode | Flag / env | What you get | | ----------- | -------------------------------------------- | ----------------------------------------------------------------------------------------- | | Default | (always on) | High-level steps: “Creating project…”, “Uploading bundle…”, resolved project/bundle paths | | Verbose | -v / --verbose or VOICETHERE_VERBOSE=1 | API method + path, request bodies (no secrets), response status + timing, counts |

Examples:

voicethere build upload
# stderr: [voicethere] Uploading agent bundle
#         [voicethere] project: …
#         [voicethere] bundle: …
#         [voicethere] Validating bundle locally before upload
#         [voicethere] Running @voicethere/agent verify on bundle
#         [voicethere] Uploading bundle to control plane API

voicethere -v build upload
# …plus [voicethere:verbose] api: https://…
#           [voicethere:verbose] POST /projects/…/builds
#           [voicethere:verbose] response: 201 (842ms)

Global -v works on any subcommand: voicethere -v projects list.

Session settings (idle timeout)

Per-project WebRTC idle timeout and crash TTS message. Changes apply on the next voicethere deploy --wait (runner env).

voicethere projects session-settings --help   # all keys, defaults, ranges
voicethere projects session-settings list
voicethere projects session-settings set idle_timeout_seconds 90
voicethere projects session-settings set data_only_idle_timeout_seconds 60
voicethere projects session-settings set conversation_history_enabled false
voicethere projects session-settings set error_message "Sorry, something went wrong."

| Key | Type | Default | Notes | | -------------------------------- | ------------------------------------- | -------- | --------------------------------------------- | | idle_timeout_enabled | bool | true | false keeps sessions billable longer | | idle_timeout_seconds | 30–120 (org may allow higher via API) | 30 | Voice / both projects | | data_only_idle_timeout_seconds | 30–120 (org may allow higher via API) | 30 | Data-only: no client→server DC traffic | | idle_timeout_voice_activity | bool | true | Reset on speech / agent TTS (voice / both) | | idle_timeout_dc_inbound | bool | true | Reset on client data-channel sends | | conversation_history_enabled | bool | true | false stops storing new STT/TTS transcripts | | error_message | string | (none) | Crash TTS in voice mode |

Boolean values for set: true / false / 1 / 0 / yes / no.

Conversation history

Search and inspect stored STT/TTS transcripts from completed voice sessions:

voicethere projects conversation list
voicethere projects conversation list --q "inventory check" --limit 20
voicethere projects conversation search "hello world"
voicethere projects conversation get orch-session-abc123 --json

Use projects session-settings set conversation_history_enabled false to stop storing new transcripts.

Sessions and billing

List recent voice sessions (orchestrator session id, status, billable seconds):

voicethere sessions list <projectId> --start 0 --end 50
# or with .voicethere/config.json:
voicethere sessions list --start 0 --end 50

The API returns { sessions, start, end, count } (max 50 rows per page). The CLI prints a Showing X–Y of Z sessions footer.

After a call ends (runner keep-alive billing), fetch billable duration:

voicethere sessions billing <orchestratorSessionId> --project <projectId>
voicethere sessions billing <orchestratorSessionId> --json

These commands call the platform control-plane API (GET /api/v1/projects/:id/sessions).

Development

npm ci
npm run test:ci
node dist/cli.js --help

Contributing: every new command, setting key, or API field needs Vitest coverage in the same PR (src/**/*.test.ts). See workspace rule feature-tests-required.mdc in the development repo.

Credentials path override for tests:

export VOICETHERE_CREDENTIALS_PATH=/tmp/voicethere-credentials.json

License

MIT — see LICENSE.