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

psst-cli

v0.5.1

Published

AI-native secrets manager. Agents use secrets without seeing them.

Readme

psst 🤫

Tests codecov License

Because your agent doesn't need to know your secrets.


The Hall of Shame

I keep pasting API keys into Claude Code. Or just letting it cat .env. Every time I tell myself I'll stop doing that. I never do.

# "just read the .env"
cat .env

# "here, use this key"
sk-live-4wB7xK9mN2pL8qR3...

Your secrets are now:

  • 📜 In the model's context window
  • 📟 In your terminal history
  • 📁 In that log file you forgot about
  • 🎓 Training data (maybe?)
  • 📸 Screenshot material for your coworker's Slack

There's a better way.


What if agents could use secrets without seeing them?

# Agent writes this:
psst STRIPE_KEY -- curl -H "Authorization: Bearer $STRIPE_KEY" https://api.stripe.com

# What the agent sees:
# ✅ Command executed successfully

# What actually ran:
# curl -H "Authorization: Bearer sk_live_abc123..." https://api.stripe.com

The secret never touches the agent's context. It's injected into the subprocess environment at runtime.

The agent orchestrates. psst handles the secrets.


For Humans

You set up psst once. Then your agent handles the rest.

Installation

npm install -g psst-cli

Setup (one-time)

# Create vault (stores encryption key in your OS keychain)
psst init

# Add your secrets
psst set STRIPE_KEY          # Interactive prompt, value hidden
psst set OPENAI_API_KEY
psst set DATABASE_URL

# Verify
psst list

That's it. Now onboard your agent:

psst onboard

This adds psst instructions to your CLAUDE.md or AGENTS.md file, teaching your agent:

  • How to use psst SECRET -- command
  • To ask you to add missing secrets
  • To shame you if you try to paste secrets in plain text 🤫

Managing Secrets

psst set <NAME>               # Add/update secret (interactive)
psst set <NAME> --stdin       # Pipe value in (for scripts)
psst get <NAME>               # View value (debugging only)
psst list                     # List all secret names
psst rm <NAME>                # Delete secret

# Import/export
psst import .env              # Import from .env file
psst import --stdin           # Import from stdin
psst import --from-env        # Import from environment variables
psst export                   # Export to stdout (.env format)
psst export --env-file .env   # Export to file

# Vault encryption (for backups/travel)
psst lock                     # Encrypt vault at rest with password
psst unlock                   # Decrypt vault

Environments

Organize secrets by environment (dev/staging/prod):

psst init --env prod          # Create vault for "prod" environment
psst --env prod set API_KEY   # Set secret in prod
psst --env prod list          # List secrets in prod
psst --env prod API_KEY -- curl https://api.example.com

# List all environments
psst list envs

Environments are stored in ~/.psst/envs/<name>/vault.db.

You can also use the PSST_ENV environment variable:

export PSST_ENV=prod
psst list                     # Uses prod environment

Note: Existing vaults at ~/.psst/vault.db continue to work as the "default" environment.

Global Flags

All commands support:

-g, --global                  # Use global vault (~/.psst/)
--env <name>                  # Use specific environment
--tag <name>                  # Filter by tag (repeatable)
--json                        # Structured JSON output
-q, --quiet                   # Suppress output, use exit codes

Local vs Global Vaults

By default, psst creates a local vault in your project directory:

psst init                     # Creates .psst/ in current directory
psst init --env dev           # Creates .psst/envs/dev/ in current directory

For user-wide secrets, use the global vault:

psst init --global            # Creates ~/.psst/
psst --global set API_KEY     # Store in global vault
psst --global list            # List global secrets

Secret Scanning

Prevent accidentally committing secrets to git:

# Scan files for leaked secrets
psst scan                     # Scan all tracked files
psst scan --staged            # Scan only git staged files
psst scan --path ./src        # Scan specific directory

# Install pre-commit hook (runs scan automatically)
psst install-hook

The scanner checks for actual vault secret values — no regex false positives. If a secret is found:

✗ Secrets found in files:

  config.js:12
    Contains: STRIPE_KEY

Found 1 secret(s) in 1 file(s)
  Tip: Use PSST_SKIP_SCAN=1 git commit to bypass

Bypass the hook when needed:

PSST_SKIP_SCAN=1 git commit -m "message"
# or
git commit --no-verify

Secret History & Rollback

Accidentally overwritten a secret? psst keeps the last 10 versions automatically.

# View version history
psst history API_KEY

# History for API_KEY
#
# ● current (active)
# ● v2  01/15/2026 14:30
# ● v1  01/10/2026 09:15
#
# 2 previous version(s)
#   Rollback: psst rollback API_KEY --to <version>

# Restore a previous version
psst rollback API_KEY --to 1
# ✓ Rolled back API_KEY to v1

Rollback is reversible — the current value is archived before restoring, so you can always undo.

Secret Tags

Organize secrets with tags for easier management:

# Add tags when setting secrets
psst set AWS_KEY --tag aws --tag prod
psst set STRIPE_KEY --tag payments --tag prod

# Manage tags on existing secrets
psst tag DB_URL prod                  # Add tag
psst untag DB_URL dev                 # Remove tag

# List secrets filtered by tag
psst list --tag aws                   # Only aws-tagged secrets
psst list --tag prod                  # Only prod-tagged secrets

# Run commands with tagged secrets only
psst --tag aws -- aws s3 ls           # Inject only aws-tagged secrets
psst --tag prod run ./deploy.sh       # Run with only prod secrets

Tags use OR logic when filtering — psst list --tag aws --tag payments returns secrets with either tag.


For Agents

You don't read secrets. You use them.

The Simple Way

psst run <command>

This injects all vault secrets into the command's environment. You never see the values.

# Run any command with all secrets available
psst run ./deploy.sh
psst run python my_script.py
psst run docker-compose up

Specific Secrets

If you only need certain secrets:

psst <SECRET_NAME> [SECRET_NAME...] -- <command>
# Single secret
psst STRIPE_KEY -- curl -H "Authorization: Bearer $STRIPE_KEY" https://api.stripe.com

# Multiple secrets
psst AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY -- aws s3 ls

What You Get Back

  • Exit code of the command
  • stdout/stderr of the command (with secrets automatically redacted)
  • Not the secret value

Secrets are automatically replaced with [REDACTED] in command output. Use --no-mask if you need to see the actual output for debugging.

Checking Available Secrets

psst list                     # See what's available
psst list --json              # Structured output

If a Secret is Missing

psst will automatically check environment variables as a fallback. If neither the vault nor the environment has the secret, the command will fail.

Ask the human to add it:

"I need STRIPE_KEY to call the Stripe API. Please run psst set STRIPE_KEY to add it."


How It Works

┌───────────────────────────────────────────────────────┐
│  Agent Context                                        │
│                                                       │
│  "I need to deploy the app"                           │
│  > psst run ./deploy.sh                               │
│                                                       │
│  [Command executed, exit code 0]                      │
│                                                       │
│  (Agent never sees any secret values)                 │
└───────────────────────────────────────────────────────┘
                          │
                          ▼
┌───────────────────────────────────────────────────────┐
│  psst                                                 │
│                                                       │
│  1. Retrieve encryption key from OS Keychain          │
│  2. Decrypt STRIPE_KEY from local vault               │
│  3. Inject into subprocess environment                │
│  4. Execute: curl ... (with $STRIPE_KEY expanded)     │
│  5. Return exit code to agent                         │
└───────────────────────────────────────────────────────┘

Security model:

  • Secrets encrypted at rest (AES-256-GCM)
  • Encryption key stored in OS Keychain (macOS Keychain, libsecret, Windows Credential Manager)
  • Secrets automatically redacted in command output ([REDACTED])
  • Optional vault lock with password for backups/travel
  • Secrets never exposed to agent context
  • Zero friction for legitimate use

CI / Headless Environments

When keychain isn't available, use the PSST_PASSWORD environment variable:

export PSST_PASSWORD="your-master-password"
psst STRIPE_KEY -- ./deploy.sh

FAQ

Q: Why not just use environment variables?

Because export STRIPE_KEY=sk_live_... puts the secret:

  • In your shell history
  • In your agent's context (if it ran the export)
  • Visible to env and printenv

psst keeps secrets out of the agent's context entirely.

Q: Why not use a .env file?

.env files are fine for local dev, but:

  • Agents can cat .env and see everything
  • Easy to accidentally commit
  • No encryption at rest

Q: Is this like HashiCorp Vault?

Vault is for teams and infrastructure. psst is for your laptop and your AI agent. Different tools, different problems.

Q: What if the agent runs psst get STRIPE_KEY?

It'll print the value. That's a feature for human debugging. If you're worried, don't give your agent shell access. But honestly, if an agent has shell access, it can already do much worse things.

Q: How is the encryption key stored?

In your OS keychain:

  • macOS: Keychain.app (unlocked when you log in)
  • Linux: libsecret / gnome-keyring
  • Windows: Credential Manager

Philosophy

  • Local-first: Your secrets never leave your machine. No cloud, no sync, no account.
  • Agent-first: Designed for AI agents to use, not just humans.
  • Zero friction: No passwords to type (keychain handles it).
  • Single binary: Works everywhere Bun runs.

Development

# Install dependencies
bun install

# Run locally
bun run src/main.ts --help

# Build single binary
bun run build

License

MIT