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

assurgent

v0.5.0

Published

A lightweight bridge between any **chat platform** and any **coding agent** — talk to your AI coding agent from anywhere.

Readme

assurgent

A lightweight bridge between any chat platform and any coding agent — talk to your AI coding agent from anywhere.

Warning: This project is under active development. APIs may introduce breaking changes at any time. Use at your own risk.

The name assurgent carries two meanings: a botanical term for a branch that grows upward (like this project, still growing), and a nod to agent hiding in plain sight — assur·gent.

You (Chat) → assurgent → Coding Agent → Response → You (Chat)

Not an agent itself. A thin bridge with automatic session management, pluggable on both sides.

Currently Supported

| Chat Platform | Coding Agent | |---|---| | Telegram | Claude Code CLI |

Quick Start

Prerequisites

Install & Configure

bunx assurgent init

This creates ~/.assurgent/config.json from the bundled template. Edit it:

{
  "chat": {
    "adapter": "telegram",
    "telegram": {
      "botToken": "YOUR_BOT_TOKEN_HERE",
      "allowedUserIds": ["YOUR_TELEGRAM_USER_ID"]
    }
  },
  "agent": {
    "adapter": "claude-code",
    "claude-code": {
      "model": "sonnet",
      "maxTurns": 10,
      "flags": ["--dangerously-skip-permissions"]
    }
  },
  "session": {
    "turnLimit": 20
  },
  "workspacePath": "/path/to/your/workspace"
}

To find your Telegram user ID, message @userinfobot.

If claude is not in your PATH (common on servers), set claudePath to the full path, e.g. /home/user/.local/bin/claude.

Run

bunx assurgent

Then message your bot on Telegram.

Custom Config Location

Set ASSURGENT_HOME to use a different config directory:

ASSURGENT_HOME=/custom/path bunx assurgent

Default: ~/.assurgent/

Bot Commands

| Command | Description | |---|---| | /new | Archive current session, start fresh | | /extend [N] | Extend session by N turns (default: turnLimit) | | /model [opus\|sonnet\|haiku\|default] | Show or change model for current session | | /session list | List all sessions with turn usage | | /session info | Show current session details | | /session resume <name> | Resume a session by name | | /session rename <name> | Rename current session | | /session pin <name> <slot> | Pin a session to quick-switch slot (1-3) | | /s | Show pinned sessions as inline keyboard buttons | | /help | Show all commands |

Any other text is forwarded to the coding agent in the current session.

Sessions

Sessions resume automatically until you start a new one with /new.

When turns reach the configured turnLimit, the bot pauses and asks you to /extend or /new.

Session names are auto-generated from the first message (e.g. fix-bug-4821, max 20 chars). Override the model per-session with /model opus — persists until reset or new session.

Pin your most-used sessions for quick switching:

/session pin fix-bug-4821 1
/session pin api-work-7392 2
/s                              ← tap a button to switch

Sessions persist across restarts in ~/.assurgent/state/sessions.json.

Secret Proxy

Assurgent includes a local proxy server that injects secrets into outgoing requests — so the AI agent never sees raw credentials.

The proxy binds to 127.0.0.1 only, enforces a whitelist, and resolves ${{secretRef.*}} handlebars in headers, query params, and request body before forwarding. The x-assurgent-upstream header is stripped and never forwarded to the upstream server.

The whitelist supports two entry formats:

  • Domain only (e.g. "googleapis.com") -- matches by hostname.
  • Host:port (e.g. "127.0.0.1:3000") -- matches by hostname and port. Useful for local services.

How it works

  1. Configure secrets and proxy in config.json:
{
  "secrets": {
    "providers": {
      "my-env": { "type": "env" }
    },
    "entries": {
      "apiKey": { "provider": "my-env", "key": "MY_API_KEY" }
    }
  },
  "proxy": {
    "port": 9090,
    "whitelist": ["googleapis.com", "graph.microsoft.com", "127.0.0.1:3000"]
  }
}
  1. Set env vars (e.g. in .env):
MY_API_KEY=sk-your-real-key
  1. Tell the AI agent to use the proxy by setting the x-assurgent-upstream header:
When calling Google Calendar, use http://127.0.0.1:9090 as the base URL
and set the header x-assurgent-upstream: https://googleapis.com

When calling Microsoft Graph, use http://127.0.0.1:9090 as the base URL
and set the header x-assurgent-upstream: https://graph.microsoft.com

Example request the agent would make:

GET http://127.0.0.1:9090/calendar/v3/events
x-assurgent-upstream: https://googleapis.com
Authorization: Bearer ${{secretRef.apiKey}}

The proxy resolves handlebars, combines the upstream header with the request path, and forwards to https://googleapis.com/calendar/v3/events. Auth headers are stripped from responses.

Using secrets without the proxy

You can also use secret references directly in config values without enabling the proxy:

{
  "secrets": {
    "providers": {
      "my-env": { "type": "env" },
      "vault": { "type": "azure-keyvault", "vaultUrl": "https://my-vault.vault.azure.net" }
    },
    "entries": {
      "botToken": { "provider": "vault", "key": "telegram-bot-token" }
    }
  },
  "chat": {
    "telegram": {
      "botToken": "${{secretRef.botToken}}"
    }
  }
}

Each provider has a user-chosen name (e.g. "vault", "my-env") and a type field ("azure-keyvault" or "env"). You can have multiple instances of the same type -- for example, separate Key Vaults for production and staging. Secrets are resolved once at startup from the configured provider.

Security Recommendations

The coding agent (Claude Code) runs as a child process with filesystem and shell access. To reduce secret exposure:

Run assurgent as a non-root user. Set service principal credentials (e.g. AZURE_CLIENT_ID, AZURE_CLIENT_SECRET, AZURE_TENANT_ID) as system-level env vars owned by root or a dedicated service account. If the agent runs as a non-root user, it cannot read /etc/environment or root-owned systemd service configs.

Use security.blacklistEnv to strip sensitive env vars from the agent's child process:

{
  "security": {
    "blacklistEnv": ["AZURE_CLIENT_ID", "AZURE_CLIENT_SECRET", "AZURE_TENANT_ID"]
  }
}

Prefer Azure Key Vault over env vars for production. Env vars are convenient for development, but Key Vault provides access control, audit logging, and rotation. The agent never sees the vault credentials — assurgent resolves secrets at startup and only exposes them through the proxy.

Use the proxy whitelist to limit which upstream servers receive your secrets. Even if the agent is tricked via prompt injection, secrets only flow to whitelisted domains.

Config Reference

| Field | Description | |---|---| | Secrets | | | secrets.providers.<name> | Named provider instance with type discriminator | | secrets.providers.<name>.type | Provider type: "env" or "azure-keyvault" | | secrets.providers.<name>.vaultUrl | Azure Key Vault URL (when type is "azure-keyvault") | | secrets.entries.<name> | Named secret: { "provider": "<instance-name>", "key": "..." } | | Security | | | security.blacklistEnv | Array of env var names to strip from child processes | | Chat | | | chat.adapter | Chat platform ("telegram") | | chat.telegram.botToken | Telegram bot token (supports ${{secretRef.*}}) | | chat.telegram.allowedUserIds | Array of allowed Telegram user IDs | | chat.telegram.placeholder.enabled | Show placeholder while agent thinks | | chat.telegram.placeholder.text | Placeholder text (default: "thinking...") | | Agent | | | agent.adapter | Agent backend ("claude-code") | | agent.claude-code.model | Default model ("opus", "sonnet", "haiku") | | agent.claude-code.maxTurns | Max agent turns per invocation | | agent.claude-code.flags | Extra CLI flags | | agent.claude-code.claudePath | Path to claude binary (default: "claude") | | Session | | | session.turnLimit | Pause after N turns, ask to extend or start new | | Proxy | | | proxy.port | Local proxy port (binds to 127.0.0.1) | | proxy.whitelist | Allowed upstream targets: domain names (e.g. "googleapis.com") or host:port (e.g. "127.0.0.1:3000") | | proxy.bypassWhitelist | Skip whitelist enforcement (default: false) | | General | | | workspacePath | Absolute path to workspace for Claude Code |

Development

git clone https://github.com/thaitype/assurgent.git
cd assurgent
bun install
bun run dev            # Start with --watch
bun run typecheck      # tsc --noEmit
bun test               # Run tests
bun run lint           # Biome check
bun run lint:fix       # Auto-fix

For local development, config is read from ~/.assurgent/config.json (same as production). Use ASSURGENT_HOME to point to a dev-specific config.

Architecture

ChatAdapter (e.g. Telegram) → Wrapper Core → AgentAdapter (e.g. Claude Code CLI)
                                    │
                              Session Manager

Both sides are pluggable interfaces. Adding a new chat platform or coding agent is just implementing an adapter — no changes to the core.

Claude Code Agent Setup

This project includes Claude Code skills (.claude/skills/) for common workflows like releasing. If you want the agent to self-edit skills, add this to .claude/settings.local.json:

{
  "permissions": {
    "allow": [
      "Edit(.claude/skills/**)",
      "Write(.claude/skills/**)",
      "Update(.claude/skills/**)",
      "Create(.claude/skills/**)"
    ]
  }
}

License

MIT