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

towns-agent

v7.3.1

Published

CLI for creating and managing Towns Protocol bot projects

Readme

towns-agent

CLI for creating and managing Towns Protocol bot projects.

Getting Started

  1. create — Create an app account. This gives you an APP_ADDRESS and APP_PRIVATE_KEY.
  2. init — Scaffold a new project. Use the app private key from step 1 to configure your server.
  3. setup — Once your app server is running, register its webhook URL and notification settings.

Commands

init [project-name]

Create a new bot project from a template.

bun run cli init my-agent
bun run cli init my-agent --template quickstart

Options:

  • -t, --template <name> — Template to use (default: quickstart)

create

Create a new bot/app account. Prompts interactively for any values not provided as flags.

# Interactive
bun run cli create --ownerPrivateKey 0xac09...

# Non-interactive
bun run cli create \
  --ownerPrivateKey 0xac09... \
  --username my-bot \
  --displayName "My Bot" \
  --description "A helpful bot" \
  --image ./avatar.png

Options:

  • -k, --ownerPrivateKey <key> — Owner private key for authentication
  • -b, --bearerToken <token> — Bearer token for authentication (prompted if neither key nor token provided)
  • -u, --username <name> — Bot username
  • -n, --displayName <name> — Bot display name
  • -d, --description <text> — Bot description
  • -p, --botPrivateKey <key> — Private key for the bot account (optional; generates a random key if omitted)
  • -i, --image <path> — Local image file to upload as the bot profile image
  • --imageUrl <url> — Bot image URL (used when not uploading a local file)

Outputs APP_ADDRESS, APP_PRIVATE_KEY, and APP_PRIVATE_DATA.

delegate <chain>

Delegate (EIP-7702 upgrade) an existing app account on a specific chain. This is required for cross-chain operations — after creating an app on the base chain, use delegate to extend it to other chains like Polygon.

The chain can be specified by name or numeric chain ID.

# By chain name (natively supported)
bun run cli delegate polygon --env prod
bun run cli delegate base-sepolia --env local_dev

# By numeric chain ID (for chains without native support)
bun run cli delegate 42161 --env prod \
  --rpc-url https://arb1.arbitrum.io/rpc \
  --account-proxy 0x...

Supported chain names: base, base-sepolia, polygon

For chains without native support (no bundled deployment), pass a numeric chain ID along with --rpc-url and --account-proxy.

Options:

  • --rpc-url <url> — Custom RPC URL (defaults to the chain's public RPC for natively supported chains)
  • --account-proxy <address> — Override accountProxy address (required for chains without bundled deployments)

Requires APP_PRIVATE_KEY (or APP_PRIVATE_DATA) to be set in .env or the environment.

setup [appAddress]

Register a webhook URL, configure notification settings, and declare supported APIs for an app.

The appAddress argument is optional when running inside a project that has a .env file containing APP_ADDRESS or APP_PRIVATE_DATA.

# From a project with .env — no appAddress needed
bun run cli setup --ownerPrivateKey 0xac09...

# Or provide appAddress explicitly
bun run cli setup 0xAPP_ADDRESS --ownerPrivateKey 0xac09...

# Non-interactive
bun run cli setup \
  --ownerPrivateKey 0xac09... \
  --webhookUrl https://example.com/webhook \
  --notify ALL

# Enable the positions API
bun run cli setup \
  --ownerPrivateKey 0xac09... \
  --webhookUrl https://example.com/webhook \
  --features positions

Options:

  • -k, --ownerPrivateKey <key> — Owner private key for authentication
  • -b, --bearerToken <token> — Bearer token for authentication (prompted if neither key nor token provided)
  • -w, --webhookUrl <url> — Webhook URL to register
  • --notify <value> — Notification setting (default: ALL)
    • ALL — Forward all messages
    • MENTION_REPLY_REACTION — Forward mentions, replies, and reactions only
    • NONE — Forward no messages
  • -f, --features <list> — Comma-separated list of supported APIs to declare. Available features:
    • positions — App supports the positions API (returns PositionsResponse via GetAppPositions)

setup view [appAddress]

View the current webhook URL, notification settings, and supported APIs for an app.

# From a project with .env
bun run cli setup view --ownerPrivateKey 0xac09...

# With explicit app address
bun run cli setup view 0xAPP_ADDRESS --ownerPrivateKey 0xac09...

Options:

  • -k, --ownerPrivateKey <key> — Owner private key for authentication
  • -b, --bearerToken <token> — Bearer token for authentication (prompted if neither key nor token provided)

metadata <view|update> [appAddress]

View or update app metadata.

The appAddress argument is optional when running inside a project that has a .env file containing APP_ADDRESS or APP_PRIVATE_DATA.

# From a project with .env — no appAddress needed
bun run cli metadata view
bun run cli metadata update --ownerPrivateKey 0xac09...

# Or provide appAddress explicitly
bun run cli metadata view 0xAPP_ADDRESS
bun run cli metadata update 0xAPP_ADDRESS --ownerPrivateKey 0xac09...

# Update non-interactively
bun run cli metadata update \
  --ownerPrivateKey 0xac09... \
  --displayName "New Name" \
  --description "Updated description"

Options:

  • -k, --ownerPrivateKey <key> — Owner private key for authentication (required for update)
  • -b, --bearerToken <token> — Bearer token for authentication (required for update)
  • -u, --username <name> — Username
  • -n, --displayName <name> — Display name
  • -d, --description <text> — Description
  • -i, --image <path> — Local image file to upload as the profile image
  • --imageUrl <url> — Image URL (used when not uploading a local file)
  • -e, --externalUrl <url> — External URL
  • -m, --motto <text> — Motto

admin [appAddress]

Admin workflow for app metadata updates.

The command:

  1. Authenticates (supports bearer token, same as other commands)
  2. Shows current metadata
  3. Calls UpdateAppMetadata using either a guided editor or a pasted patch

The appAddress argument is optional when running inside a project that has a .env file containing APP_ADDRESS or APP_PRIVATE_DATA. If it is not found, the CLI prompts for it so you can paste the address.

# Fully interactive
bun run cli admin --env prod

# With explicit app address and bearer token
bun run cli admin 0xAPP_ADDRESS --bearerToken <token> --env prod

Options:

  • -k, --ownerPrivateKey <key> — Owner private key for authentication
  • -b, --bearerToken <token> — Bearer token for authentication (prompted if neither key nor token provided)

rotate-secret [appAddress]

Rotate the JWT shared secret for an app. Outputs the new secret as JWT_SECRET=... so it can be copied into your .env file.

The appAddress argument is optional when running inside a project that has a .env file containing APP_ADDRESS or APP_PRIVATE_DATA.

# From a project with .env — no appAddress needed
bun run cli rotate-secret --ownerPrivateKey 0xac09...

# Or provide appAddress explicitly
bun run cli rotate-secret 0xAPP_ADDRESS --ownerPrivateKey 0xac09...

# With bearer token
bun run cli rotate-secret -b <token> --env prod

Options:

  • -k, --ownerPrivateKey <key> — Owner private key for authentication
  • -b, --bearerToken <token> — Bearer token for authentication (prompted if neither key nor token provided)

update

Update @towns-labs/* dependencies and skills to latest versions.

bun run cli update

Options:

  • --skip-agents-md — Skip updating the AGENTS.md file

install-skill

Install Towns Agent Skills into the current project.

bun run cli install-skill

Profile Image Upload

The --image flag (or -i) on create and metadata update commands accepts a path to a local image file (PNG, JPEG, GIF, WebP). The CLI will:

  1. Validate the file type and read image dimensions
  2. Encrypt and upload the image as chunked media to the Towns Protocol
  3. Set the uploaded image as the bot's profile image
  4. Automatically set imageUrl to the stream metadata URL
# Upload during bot creation
bun run cli create --bearerToken <token> --env prod \
  --username my-bot --image ./avatar.png

# Upload when updating metadata
bun run cli metadata update --bearerToken <token> --env prod \
  --image ./new-avatar.jpg

Supported formats: PNG, JPEG, GIF, WebP. SVG is not supported.

Authentication

Commands that modify app state (create, delegate, setup, metadata update, admin, rotate-secret) require authentication via one of:

  • -k, --ownerPrivateKey — A hex-encoded private key that owns the app
  • -b, --bearerToken — A bearer token

If neither flag is provided, the CLI will prompt for a bearer token interactively.

When you enter a bearer token interactively, the CLI can save it per environment. On later runs, if you do not pass --bearerToken or --ownerPrivateKey, the CLI automatically uses the saved token first. If that token is expired/invalid, the CLI prompts you to authenticate again and retries.

Saved tokens are stored at:

  • $XDG_CONFIG_HOME/towns-agent/auth.json (when XDG_CONFIG_HOME is set)
  • ~/.config/towns-agent/auth.json (default)

Environment Resolution

Commands that need an environment (create, delegate, setup, metadata, admin, rotate-secret) resolve it in this order:

  1. --env flag (e.g. --env prod)
  2. RIVER_ENV environment variable
  3. RIVER_ENV in .env file
  4. env field decoded from APP_PRIVATE_DATA in .env file

If none are found, the CLI exits with an error.

Global Options

  • -h, --help — Show help message