agentprofiles-cli 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE.md ADDED
@@ -0,0 +1,5 @@
1
+ # License
2
+
3
+ Licensed under either of the [Apache License, Version 2.0](LICENSE-APACHE.md) or [MIT license](LICENSE-MIT.md) at your option.
4
+
5
+ For more information about contributing to this project, see our top-level [CONTRIBUTING](https://github.com/hashintel/labs/blob/main/.github/CONTRIBUTING.md) policy.
package/README.md CHANGED
@@ -1,47 +1,46 @@
1
1
  # agentprofiles-cli
2
2
 
3
- **Manage per-project configuration profiles for LLM agent tools via `direnv`.**
3
+ **Manage named configuration profiles for LLM agent tools.**
4
4
 
5
- Currently supports [Claude Code](https://claude.ai/code) and [OpenCode](https://opencode.ai/).
5
+ Supports 6 agents: [Claude Code](https://claude.ai/code), [Amp](https://amp.dev/), [OpenCode](https://opencode.ai/), [Codex](https://codex.dev/), [Gemini](https://gemini.google.com/), and [Augment](https://augment.dev/).
6
6
 
7
7
  ---
8
8
 
9
9
  ## The Problem
10
10
 
11
- 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.
11
+ You use AI coding assistants. You have multiple contexts where you work—personal projects, work repos, client codebases—and you want different settings, histories, or API keys for each.
12
12
 
13
- **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.
13
+ **The tools support this.** Each agent reads its configuration from a directory. Point that directory at a different location, and you get a completely isolated profile.
14
14
 
15
15
  **But managing this manually is tedious:**
16
16
 
17
- - You can't just set the variable in your shell config—that's global, one profile for everything.
18
- - You can't add it to each project's dotfiles—that's not portable across projects with similar needs.
19
- - You don't want to remember to export variables before launching your editor every time.
17
+ - You can't just set a global symlink—that's one profile for everything.
18
+ - You can't add symlinks to each project's dotfiles—that's not portable across projects with similar needs.
19
+ - You don't want to remember to update symlinks before launching your editor every time.
20
20
 
21
- **agentprofiles-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.
21
+ **agentprofiles-cli solves this.** It gives you named profiles, stores them centrally, and switches each agent's global config symlink to the profile you choose.
22
22
 
23
23
  ```sh
24
24
  # Create profiles once
25
25
  agentprofiles add claude work
26
26
  agentprofiles add claude personal
27
+ agentprofiles add opencode work
27
28
 
28
- # Activate per-project
29
- cd ~/work/client-project
30
- agentprofiles set claude work --allow
31
-
32
- cd ~/personal/side-project
33
- agentprofiles set claude personal --allow
29
+ # Activate when needed
30
+ agentprofiles set claude work
31
+ agentprofiles set opencode work
34
32
 
35
- # Now "cd" handles everything. Enter a directory, get the right profile.
33
+ # Switch to a different context
34
+ agentprofiles set claude personal
36
35
  ```
37
36
 
38
37
  ---
39
38
 
40
39
  ## FAQ
41
40
 
42
- ### "Just use your global config"
41
+ ### "Just use your global symlink"
43
42
 
44
- **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.
43
+ **The problem:** There's only one global symlink. If you work across multiple contexts (personal/work/clients), you're constantly mixing histories, API keys, and settings that shouldn't mix.
45
44
 
46
45
  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.
47
46
 
@@ -51,106 +50,75 @@ Some people create separate user accounts on their machine for this. That works,
51
50
 
52
51
  A profile should be defined once and _applied_ to projects, not duplicated into each one.
53
52
 
54
- ### "Just set the env var before launching"
53
+ ### "Just update the symlink manually"
55
54
 
56
55
  **The problem:** This works for one-off commands, but breaks down for real workflows:
57
56
 
58
- - Interactive sessions that spawn subprocesses inherit the environment—but only if you remembered to set it.
59
- - Multiple terminals need the same treatment.
60
57
  - You have to remember which profile goes with which project, every time.
58
+ - Multiple projects with the same profile need manual coordination.
59
+ - Switching between projects means manually updating symlinks.
61
60
 
62
61
  Humans are bad at remembering things. Computers are good at it. Let the computer remember.
63
62
 
64
- ### "Why direnv specifically?"
63
+ ### "Why symlinks instead of environment variables?"
65
64
 
66
- [direnv](https://direnv.net/) is a mature, widely-used tool for per-directory environment management. It:
65
+ Symlinks are simpler and more direct:
67
66
 
68
- - Automatically loads/unloads environment variables when you `cd` in and out
69
- - Has a security model (`direnv allow`) so you explicitly trust changes
67
+ - No shell hooks or environment variable management needed
70
68
  - Works with any shell (zsh, bash, fish, etc.)
71
- - Is already installed on many developer machines
72
-
73
- We didn't want to reinvent this. direnv does one job well; agentprofiles-cli just makes it easy to use for agent tool profiles.
69
+ - Agents read config from their standard directory (e.g., `~/.claude`)
70
+ - No need for external tools like direnv
71
+ - Portable across machines (just update the symlink)
74
72
 
75
73
  ### "Do I really need another CLI tool?"
76
74
 
77
- Fair question. You could manage this yourself with handwritten `.envrc` files. agentprofiles-cli is worth it if you value:
75
+ Fair question. You could manage this yourself with handwritten symlinks. agentprofiles-cli is worth it if you value:
78
76
 
79
77
  - **Named profiles** you can list, create, and remove
80
78
  - **Consistent file structure** without thinking about it
81
- - **Clean `.envrc` files** that only contain a small bootstrap block
82
- - **Guardrails** like profile name validation and direnv hook detection
79
+ - **Fast profile switching** with one command
80
+ - **Guardrails** like profile name validation and symlink verification
81
+ - **Cross-agent support** for managing multiple tools at once
83
82
 
84
- If you're comfortable managing raw env vars yourself, you don't need this. But if you want the convenience of `agentprofiles set claude work`, this is for you.
83
+ If you're comfortable managing raw symlinks yourself, you don't need this. But if you want the convenience of `agentprofiles set claude work`, this is for you.
85
84
 
86
85
  ---
87
86
 
88
87
  ## Requirements
89
88
 
90
- ### Node.js 20+
89
+ ### Node.js 18+
91
90
 
92
91
  This is a Node.js CLI tool.
93
92
 
94
- ### direnv (required)
95
-
96
- agentprofiles-cli generates direnv-compatible files. Without direnv installed and hooked into your shell, those files won't do anything.
97
-
98
- **Install direnv:**
99
-
100
- ```sh
101
- # macOS
102
- brew install direnv
103
-
104
- # Ubuntu/Debian
105
- sudo apt install direnv
106
-
107
- # Or see https://direnv.net/docs/installation.html
108
- ```
109
-
110
- **Hook it into your shell** (add to your shell's rc file):
111
-
112
- ```sh
113
- # ~/.zshrc
114
- eval "$(direnv hook zsh)"
115
-
116
- # ~/.bashrc
117
- eval "$(direnv hook bash)"
118
-
119
- # ~/.config/fish/config.fish
120
- direnv hook fish | source
121
- ```
93
+ ### No external dependencies
122
94
 
123
- After adding the hook, restart your shell or source the rc file.
95
+ agentprofiles-cli uses symlinks, which are built into all modern operating systems. No direnv, no environment variable management, no shell hooks needed.
124
96
 
125
- **Verify it works:**
126
-
127
- ```sh
128
- direnv --version
129
- ```
130
-
131
- When you `cd` into a directory with an `.envrc`, you should see direnv print a message about loading or blocking the file.
97
+ Just install the CLI and start creating profiles.
132
98
 
133
99
  ---
134
100
 
135
- ## Installation
101
+ ## Quick Start
102
+
103
+ ### 1. Install
136
104
 
137
105
  ```sh
138
106
  npm install -g agentprofiles-cli
139
107
  ```
140
108
 
141
- ---
142
-
143
- ## Getting Started
144
-
145
- ### 1. Initialize
109
+ ### 2. Initialize
146
110
 
147
111
  ```sh
148
112
  agentprofiles setup
149
113
  ```
150
114
 
151
- This creates the config directory (`~/.config/agentprofiles/` by default) and sets up subdirectories for each supported agent tool.
115
+ This creates the config directory (`~/.config/agentprofiles/` by default) and sets up:
152
116
 
153
- ### 2. Create profiles
117
+ - Subdirectories for each supported agent tool
118
+ - A `_base` profile template for each agent
119
+ - Shared directories for cross-agent resources
120
+
121
+ ### 3. Create profiles
154
122
 
155
123
  ```sh
156
124
  agentprofiles add claude work
@@ -165,32 +133,28 @@ agentprofiles add claude
165
133
  # Suggests a random name like "jolly-curie", or enter your own
166
134
  ```
167
135
 
168
- ### 3. Activate a profile in a project
136
+ ### 4. Activate profiles
169
137
 
170
138
  ```sh
171
- cd /path/to/your/project
172
- agentprofiles set claude work --allow
139
+ agentprofiles set claude work
140
+ agentprofiles set opencode work
173
141
  ```
174
142
 
175
- This writes two files:
176
-
177
- - `.envrc` — with a small bootstrap block
178
- - `.envrc.agentprofiles` — with the actual export statements
143
+ This creates symlinks:
179
144
 
180
- The `--allow` flag runs `direnv allow` automatically. Without it, you'll need to run `direnv allow` manually.
145
+ - `~/.claude` `~/.config/agentprofiles/claude/work`
146
+ - `~/.config/opencode` → `~/.config/agentprofiles/opencode/work`
181
147
 
182
- ### 4. Work normally
148
+ The agents now read config from the active profiles.
183
149
 
184
- 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.
185
-
186
- ### 5. Switch or remove profiles
150
+ ### 5. Switch profiles
187
151
 
188
152
  ```sh
189
153
  # Switch to a different profile
190
- agentprofiles set claude personal --allow
154
+ agentprofiles set claude personal
191
155
 
192
- # Remove a profile from this project (keeps the profile itself)
193
- agentprofiles unset claude --allow
156
+ # Switch back to base profile
157
+ agentprofiles unset claude
194
158
  ```
195
159
 
196
160
  ---
@@ -204,42 +168,41 @@ agentprofiles unset claude --allow
204
168
  | `add <agent> [name]` | Create a new profile |
205
169
  | `edit <agent> <name>` | Open a profile's directory in your editor |
206
170
  | `remove <agent> [name]` | Delete a profile (alias: `rm`) |
207
- | `set <agent> [name]` | Activate a profile for the current directory |
208
- | `unset <agent>` | Deactivate a profile for the current directory |
171
+ | `set <agent> [name]` | Activate a profile for an agent |
172
+ | `unset <agent>` | Switch an agent back to base profile |
173
+ | `status [agent]` | Show current profile status |
174
+ | `release <agent>` | Stop managing an agent (restore original config) |
209
175
 
210
176
  ### Common flags
211
177
 
212
- - `--allow` / `-y` — Auto-run `direnv allow` after modifying files (for `set` and `unset`)
213
178
  - `--quiet` / `-q` — Suppress the banner
214
179
 
215
- ---
180
+ ### Supported agents
216
181
 
217
- ## How It Works
218
-
219
- ### Files in your project
182
+ - `claude` Claude Code
183
+ - `amp` — Amp
184
+ - `opencode` OpenCode
185
+ - `codex` — Codex
186
+ - `gemini` — Gemini
187
+ - `augment` — Augment
220
188
 
221
- When you run `agentprofiles set claude work`, it creates/updates:
189
+ > **Note on `agentprofiles edit` and `$EDITOR`**
190
+ >
191
+ > The `agentprofiles edit` command uses the `$EDITOR` environment variable if it is set. This value may include arguments, and common patterns like `EDITOR="code --wait"` are supported. When present, the editor command (plus its arguments) is invoked with the profile directory path appended.
222
192
 
223
- **`.envrc`** — Contains a small bootstrap block:
193
+ ---
224
194
 
225
- ```sh
226
- ### agentprofiles:begin
227
- watch_file .envrc.agentprofiles
228
- source_env_if_exists .envrc.agentprofiles
229
- ### agentprofiles:end
230
- ```
195
+ ## How It Works
231
196
 
232
- **`.envrc.agentprofiles`** Contains the actual exports:
197
+ ### Symlink-based activation
233
198
 
234
- ```sh
235
- # tool-generated; do not edit
199
+ When you run `agentprofiles set claude work`, the tool creates a symlink:
236
200
 
237
- ### agentprofiles:begin claude
238
- export CLAUDE_CONFIG_DIR="$HOME/.config/agentprofiles/claude/work"
239
- ### agentprofiles:end claude
201
+ ```
202
+ ~/.claude → ~/.config/agentprofiles/claude/work
240
203
  ```
241
204
 
242
- Only the block between `### agentprofiles:begin` and `### agentprofiles:end` in `.envrc` is managed by this tool. Your other environment variables are left alone.
205
+ The agent reads config from its standard directory (`~/.claude`). The symlink points to the active profile, so switching profiles is just updating the symlink target.
243
206
 
244
207
  ### Profile storage
245
208
 
@@ -250,74 +213,84 @@ Profiles are stored in your config directory:
250
213
  ├── config.json
251
214
  ├── claude/
252
215
  │ ├── .gitignore # Ignores runtime artifacts
216
+ │ ├── _base/ # Base profile (default)
217
+ │ │ └── meta.json
253
218
  │ ├── work/
254
219
  │ │ └── meta.json # Profile metadata
255
220
  │ └── personal/
256
221
  │ └── meta.json
257
- └── opencode/
258
- ├── .gitignore
259
- └── work/
260
- └── meta.json
222
+ ├── opencode/
223
+ ├── .gitignore
224
+ │ ├── _base/
225
+ │ │ └── meta.json
226
+ │ └── work/
227
+ │ └── meta.json
228
+ └── _agents/ # Shared cross-agent resources
229
+ └── meta.json
261
230
  ```
262
231
 
263
- Each profile directory _is_ the config directory for that tool. When `CLAUDE_CONFIG_DIR` points to `~/.config/agentprofiles/claude/work`, Claude Code reads its settings, history, and cache from there.
232
+ Each profile directory _is_ the config directory for that tool. When `~/.claude` points to `~/.config/agentprofiles/claude/work`, Claude Code reads its settings, history, and cache from there.
264
233
 
265
- ---
234
+ ### Shared directories
266
235
 
267
- ## Troubleshooting
236
+ The tool also manages shared resources:
268
237
 
269
- ### "Nothing happens when I cd into the project"
238
+ ```
239
+ ~/.agents → ~/.config/agentprofiles/_agents/
240
+ ```
270
241
 
271
- direnv isn't hooked into your shell.
242
+ This allows all agents to access shared skills, tools, and resources.
272
243
 
273
- 1. Verify direnv is installed: `direnv --version`
274
- 2. Add the hook to your shell rc file (see [Requirements](#direnv-required))
275
- 3. Restart your shell or source the rc file
276
- 4. Re-enter the directory or run `direnv reload`
244
+ ---
277
245
 
278
- ### "direnv says the .envrc is blocked"
246
+ ## Troubleshooting
279
247
 
280
- This is direnv's security model. Run:
248
+ ### "The symlink isn't being created"
281
249
 
282
- ```sh
283
- direnv allow
284
- ```
250
+ Debug checklist:
285
251
 
286
- Or use `--allow` when running `agentprofiles set` or `agentprofiles unset`.
252
+ 1. Check the profile exists: `agentprofiles list claude`
253
+ 2. Check symlink status: `ls -la ~/.claude`
254
+ 3. Verify permissions: Can you write to `~/.`?
255
+ 4. Run `agentprofiles status` to see the current state
287
256
 
288
- ### "The env var isn't set correctly"
257
+ ### "The agent isn't reading the right config"
289
258
 
290
- Debug checklist:
259
+ 1. Verify the symlink points to the right place: `ls -la ~/.claude`
260
+ 2. Check the profile directory exists: `ls -la ~/.config/agentprofiles/claude/work`
261
+ 3. Verify the agent is reading from the symlinked directory (check agent settings)
291
262
 
292
- 1. Check the files exist: `cat .envrc` and `cat .envrc.agentprofiles`
293
- 2. Verify direnv loaded: `direnv status`
294
- 3. Check the variable: `echo $CLAUDE_CONFIG_DIR`
295
- 4. Look for conflicts: Are you exporting the same variable elsewhere?
263
+ ### "I want to use a different config location"
296
264
 
297
- Force direnv to reload:
265
+ You can override the config directory:
298
266
 
299
267
  ```sh
300
- direnv reload
268
+ export AGENTPROFILES_CONFIG_DIR=/path/to/config
269
+ export AGENTPROFILES_CONTENT_DIR=/path/to/content
301
270
  ```
302
271
 
303
- ### I already have a `.envrc`
272
+ Or set `contentDir` in `config.json` to point to a different location.
304
273
 
305
- That's fine. agentprofiles only manages the section between its markers. Keep your existing content outside that block.
274
+ ### "I already have a symlink at ~/.claude"
306
275
 
307
- If you export the same variable elsewhere in the file, the last assignment wins.
276
+ agentprofiles will overwrite it. If you have existing config there, move it first:
308
277
 
309
- ---
278
+ ```sh
279
+ mv ~/.claude ~/.claude.backup
280
+ agentprofiles set claude work
281
+ ```
310
282
 
311
- ## What to Commit
283
+ Then migrate your config from the backup to the new location.
312
284
 
313
- This depends on your team, but common approaches:
285
+ ### "How do I see what's currently active?"
314
286
 
315
- | File | Recommendation |
316
- | ---------------------- | -------------------------------------------------------------------------------------------------------------------------- |
317
- | `.envrc` | **Commit it.** The bootstrap block is generic and portable. |
318
- | `.envrc.agentprofiles` | **Usually gitignore.** It contains paths that may differ per machine. Have each developer run `agentprofiles set` locally. |
287
+ Use the `status` command:
319
288
 
320
- If your team uses identical paths (e.g., everyone uses defaults), committing `.envrc.agentprofiles` is fine.
289
+ ```sh
290
+ agentprofiles status
291
+ ```
292
+
293
+ This shows which profiles are active for each agent and the status of all symlinks.
321
294
 
322
295
  ---
323
296
 
@@ -325,7 +298,7 @@ If your team uses identical paths (e.g., everyone uses defaults), committing `.e
325
298
 
326
299
  ### Default locations
327
300
 
328
- - **Config directory:** `~/.config/agentprofiles/` (or `$XDG_CONFIG_HOME/agentprofiles/`)
301
+ - **Config directory:** `~/.config/agentprofiles/`
329
302
  - **Content directory:** Same as config directory by default
330
303
 
331
304
  ### Environment variable overrides
@@ -339,24 +312,31 @@ You can also set `contentDir` in `config.json` to point to a different location.
339
312
 
340
313
  ---
341
314
 
342
- ## Removing agentprofiles from a project
315
+ ## Removing agentprofiles from your machine
343
316
 
344
- To stop using agentprofiles in a specific project:
317
+ To stop using agentprofiles for an agent:
345
318
 
346
319
  ```sh
347
- # Remove all agent blocks
348
- agentprofiles unset claude --allow
349
- agentprofiles unset opencode --allow
320
+ # Switch back to base profile (keeps the symlink, but points to base)
321
+ agentprofiles unset claude
322
+ agentprofiles unset opencode
323
+ ```
350
324
 
351
- # Then manually remove the bootstrap block from .envrc
352
- # and delete .envrc.agentprofiles if it's now empty
325
+ To completely remove agentprofiles (remove symlinks):
326
+
327
+ ```sh
328
+ # Manually remove symlinks
329
+ rm ~/.claude
330
+ rm ~/.config/opencode
331
+ rm ~/.agents
353
332
  ```
354
333
 
355
- Or manually:
334
+ Or use the `release` command (if available in your version):
356
335
 
357
- 1. Delete the `### agentprofiles:begin` / `### agentprofiles:end` block from `.envrc`
358
- 2. Delete `.envrc.agentprofiles`
359
- 3. Run `direnv allow`
336
+ ```sh
337
+ agentprofiles release claude
338
+ agentprofiles release opencode
339
+ ```
360
340
 
361
341
  ---
362
342
 
@@ -387,6 +367,12 @@ npm run format:check && npm run lint && npm run typecheck && npm run test
387
367
 
388
368
  ---
389
369
 
370
+ ## Contributors
371
+
372
+ `agent-profiles-cli` was created by [Lu Nelson](https://github.com/lunelson). It is being developed in conjunction with [HASH](https://hash.dev/) as an open-source project.
373
+
374
+ If you have questions, please create a [discussion](https://github.com/orgs/hashintel/discussions).
375
+
390
376
  ## License
391
377
 
392
- MIT
378
+ `agent-profiles-cli` is available under either of the [Apache License, Version 2.0] or [MIT license] at your option. Please see the [LICENSE] file to review your options.