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

agentprofile-cli

v0.1.0

Published

Manage configuration profiles for LLM agent tools via direnv

Readme

agentprofile-cli

Manage per-project configuration profiles for LLM agent tools via direnv.

Currently supports Claude Code and OpenCode.


The Problem

You use an AI coding assistant. Maybe Claude Code, maybe OpenCode. You have multiple contexts where you work—personal projects, work repos, client codebases—and you want different settings, histories, or API keys for each.

The tools support this. Both Claude Code and OpenCode read their configuration from a directory specified by an environment variable (CLAUDE_CONFIG_DIR, OPENCODE_CONFIG_DIR). Point the variable at a different directory, and you get a completely isolated profile.

But managing this manually is tedious:

  • You can't just set the variable in your shell config—that's global, one profile for everything.
  • You can't add it to each project's dotfiles—that's not portable across projects with similar needs.
  • You don't want to remember to export variables before launching your editor every time.

agentprofile-cli solves this. It gives you named profiles, stores them centrally, and uses direnv to automatically activate the right profile when you enter a project directory.

# Create profiles once
agentprofile add claude work
agentprofile add claude personal

# Activate per-project
cd ~/work/client-project
agentprofile set claude work --allow

cd ~/personal/side-project
agentprofile set claude personal --allow

# Now "cd" handles everything. Enter a directory, get the right profile.

FAQ

"Just use your global config"

The problem: There's only one global config. If you work across multiple contexts (personal/work/clients), you're constantly mixing histories, API keys, and settings that shouldn't mix.

Some people create separate user accounts on their machine for this. That works, but it's heavy-handed for what should be a simple configuration switch.

"Just use project-local config"

The problem: Project-local configs aren't portable. If you have 10 work repos that should all use your "work" profile, you'd need to copy the same configuration into all 10. When you update it, you update it in 10 places.

A profile should be defined once and applied to projects, not duplicated into each one.

"Just set the env var before launching"

The problem: This works for one-off commands, but breaks down for real workflows:

  • Interactive sessions that spawn subprocesses inherit the environment—but only if you remembered to set it.
  • Multiple terminals need the same treatment.
  • You have to remember which profile goes with which project, every time.

Humans are bad at remembering things. Computers are good at it. Let the computer remember.

"Why direnv specifically?"

direnv is a mature, widely-used tool for per-directory environment management. It:

  • Automatically loads/unloads environment variables when you cd in and out
  • Has a security model (direnv allow) so you explicitly trust changes
  • Works with any shell (zsh, bash, fish, etc.)
  • Is already installed on many developer machines

We didn't want to reinvent this. direnv does one job well; agentprofile-cli just makes it easy to use for agent tool profiles.

"Do I really need another CLI tool?"

Fair question. You could manage this yourself with handwritten .envrc files. agentprofile-cli is worth it if you value:

  • Named profiles you can list, create, and remove
  • Consistent file structure without thinking about it
  • Clean .envrc files that only contain a small bootstrap block
  • Guardrails like profile name validation and direnv hook detection

If you're comfortable managing raw env vars yourself, you don't need this. But if you want the convenience of agentprofile set claude work, this is for you.


Requirements

Node.js 20+

This is a Node.js CLI tool.

direnv (required)

agentprofile-cli generates direnv-compatible files. Without direnv installed and hooked into your shell, those files won't do anything.

Install direnv:

# macOS
brew install direnv

# Ubuntu/Debian
sudo apt install direnv

# Or see https://direnv.net/docs/installation.html

Hook it into your shell (add to your shell's rc file):

# ~/.zshrc
eval "$(direnv hook zsh)"

# ~/.bashrc
eval "$(direnv hook bash)"

# ~/.config/fish/config.fish
direnv hook fish | source

After adding the hook, restart your shell or source the rc file.

Verify it works:

direnv --version

When you cd into a directory with an .envrc, you should see direnv print a message about loading or blocking the file.


Installation

npm install -g agentprofile-cli

Getting Started

1. Initialize

agentprofile setup

This creates the config directory (~/.config/agentprofile/ by default) and sets up subdirectories for each supported agent tool.

2. Create profiles

agentprofile add claude work
agentprofile add claude personal
agentprofile add opencode work

Or let it prompt you for a name:

agentprofile add claude
# Suggests a random name like "jolly-curie", or enter your own

3. Activate a profile in a project

cd /path/to/your/project
agentprofile set claude work --allow

This writes two files:

  • .envrc — with a small bootstrap block
  • .envrc.agentprofile — with the actual export statements

The --allow flag runs direnv allow automatically. Without it, you'll need to run direnv allow manually.

4. Work normally

Now every time you cd into that project, direnv automatically exports CLAUDE_CONFIG_DIR pointing to your "work" profile. When you cd out, it unloads.

5. Switch or remove profiles

# Switch to a different profile
agentprofile set claude personal --allow

# Remove a profile from this project (keeps the profile itself)
agentprofile unset claude --allow

Commands

| Command | Description | | ----------------------- | -------------------------------------------------- | | setup | Initialize the agentprofile system (alias: init) | | list [agent] | List profiles, optionally filtered by agent | | add <agent> [name] | Create a new profile | | edit <agent> <name> | Open a profile's directory in your editor | | remove <agent> [name] | Delete a profile (alias: rm) | | set <agent> [name] | Activate a profile for the current directory | | unset <agent> | Deactivate a profile for the current directory |

Common flags

  • --allow / -y — Auto-run direnv allow after modifying files (for set and unset)
  • --quiet / -q — Suppress the banner

How It Works

Files in your project

When you run agentprofile set claude work, it creates/updates:

.envrc — Contains a small bootstrap block:

### agentprofile:begin
watch_file .envrc.agentprofile
source_env_if_exists .envrc.agentprofile
### agentprofile:end

.envrc.agentprofile — Contains the actual exports:

# tool-generated; do not edit

### agentprofile:begin claude
export CLAUDE_CONFIG_DIR="$HOME/.config/agentprofile/claude/work"
### agentprofile:end claude

Only the block between ### agentprofile:begin and ### agentprofile:end in .envrc is managed by this tool. Your other environment variables are left alone.

Profile storage

Profiles are stored in your config directory:

~/.config/agentprofile/
├── config.json
├── claude/
│   ├── .gitignore          # Ignores runtime artifacts
│   ├── work/
│   │   └── meta.json       # Profile metadata
│   └── personal/
│       └── meta.json
└── opencode/
    ├── .gitignore
    └── work/
        └── meta.json

Each profile directory is the config directory for that tool. When CLAUDE_CONFIG_DIR points to ~/.config/agentprofile/claude/work, Claude Code reads its settings, history, and cache from there.


Troubleshooting

"Nothing happens when I cd into the project"

direnv isn't hooked into your shell.

  1. Verify direnv is installed: direnv --version
  2. Add the hook to your shell rc file (see Requirements)
  3. Restart your shell or source the rc file
  4. Re-enter the directory or run direnv reload

"direnv says the .envrc is blocked"

This is direnv's security model. Run:

direnv allow

Or use --allow when running agentprofile set or agentprofile unset.

"The env var isn't set correctly"

Debug checklist:

  1. Check the files exist: cat .envrc and cat .envrc.agentprofile
  2. Verify direnv loaded: direnv status
  3. Check the variable: echo $CLAUDE_CONFIG_DIR
  4. Look for conflicts: Are you exporting the same variable elsewhere?

Force direnv to reload:

direnv reload

I already have a .envrc

That's fine. agentprofile only manages the section between its markers. Keep your existing content outside that block.

If you export the same variable elsewhere in the file, the last assignment wins.


What to Commit

This depends on your team, but common approaches:

| File | Recommendation | | --------------------- | ------------------------------------------------------------------------------------------------------------------------- | | .envrc | Commit it. The bootstrap block is generic and portable. | | .envrc.agentprofile | Usually gitignore. It contains paths that may differ per machine. Have each developer run agentprofile set locally. |

If your team uses identical paths (e.g., everyone uses defaults), committing .envrc.agentprofile is fine.


Configuration

Default locations

  • Config directory: ~/.config/agentprofile/ (or $XDG_CONFIG_HOME/agentprofile/)
  • Content directory: Same as config directory by default

Environment variable overrides

| Variable | Purpose | | -------------------------- | --------------------------------------- | | AGENTPROFILE_CONFIG_DIR | Override where config.json lives | | AGENTPROFILE_CONTENT_DIR | Override where profile directories live |

You can also set contentDir in config.json to point to a different location.


Removing agentprofile from a project

To stop using agentprofile in a specific project:

# Remove all agent blocks
agentprofile unset claude --allow
agentprofile unset opencode --allow

# Then manually remove the bootstrap block from .envrc
# and delete .envrc.agentprofile if it's now empty

Or manually:

  1. Delete the ### agentprofile:begin / ### agentprofile:end block from .envrc
  2. Delete .envrc.agentprofile
  3. Run direnv allow

Development

# Install dependencies
npm install

# Run in development
npm run start -- --help

# Build
npm run build

# Run all checks (matches CI)
npm run format:check && npm run lint && npm run typecheck && npm run test

| Script | Description | | ------------------- | ----------------------------- | | npm run build | Compile TypeScript to dist/ | | npm run typecheck | Type-check without emitting | | npm run start | Run via tsx (no build needed) | | npm run test | Run tests | | npm run lint | Lint with ESLint | | npm run format | Format with Prettier |


License

MIT