@reyanshgupta/ditto-cli 0.3.3 → 0.3.5

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.
Files changed (2) hide show
  1. package/README.md +66 -27
  2. package/package.json +7 -6
package/README.md CHANGED
@@ -5,9 +5,9 @@
5
5
  [![MIT license](https://img.shields.io/badge/license-MIT-6f42c1.svg)](LICENSE)
6
6
  [![Rust 1.85+](https://img.shields.io/badge/rust-1.85%2B-6f42c1.svg)](https://www.rust-lang.org/)
7
7
 
8
- Keep work, personal, and client Claude Code, Codex, opencode, and OMP logins apart.
8
+ Keep work, personal, and client Claude Code, Codex, opencode, OMP, and Prime Agent logins apart.
9
9
 
10
- Ditto CLI gives each profile its own authentication, settings, and session history. Pick a profile in the terminal, then launch any of the four tools. Your existing setup stays available as the `default` profile.
10
+ Ditto CLI gives each profile its own authentication and session history while keeping the capabilities you configured once. Pick a profile in the terminal, then launch any of the five tools. Your existing setup stays available as the `default` profile.
11
11
 
12
12
  Ditto CLI takes its name from the shape-shifting Pokémon: one small tool, whichever coding identity you need.
13
13
 
@@ -24,16 +24,18 @@ Ditto CLI takes its name from the shape-shifting Pokémon: one small tool, which
24
24
  │ ││Claude Code ● Signed in │
25
25
  │ ││Codex ○ Sign in required │
26
26
  │ ││opencode ⠹ Checking │
27
- │ ││OMP · Use /login inside OMP
27
+ │ ││OMP Sign in required
28
+ │ ││Prime Agent ● Signed in │
28
29
  │ ││ │
29
30
  │ ││Profile directories │
30
31
  │ ││Claude Code ~/.ditto/profiles/work/claude │
31
32
  │ ││Codex ~/.ditto/profiles/work/codex │
32
33
  │ ││opencode …/work/opencode/data/opencode │
33
34
  │ ││OMP ~/.omp/profiles/work/agent │
35
+ │ ││Prime Agent …/.ditto/profiles/work/prime-agent │
34
36
  └────────────────────────┘└────────────────────────────────────────────────────┘
35
37
  ┌──────────────────────────────────────────────────────────────────────────────┐
36
- c Claude Code · x Codex · o opencode · p OMP
38
+ c Claude Code · x Codex · o opencode · p OMP · a Prime
37
39
  │ ↑↓ select · n new · e rename · d default │
38
40
  │ l sign in · L sign out · r refresh · q quit │
39
41
  └──────────────────────────────────────────────────────────────────────────────┘
@@ -41,7 +43,7 @@ Ditto CLI takes its name from the shape-shifting Pokémon: one small tool, which
41
43
 
42
44
  ## How it works
43
45
 
44
- Claude Code, Codex, opencode, and OMP keep user-level configuration and login state on disk. That works until you need separate accounts for different jobs. Manually moving auth files around is easy to get wrong, and it is hard to tell which account a new session will use.
46
+ Claude Code, Codex, opencode, OMP, and Prime Agent keep user-level configuration and login state on disk. That works until you need separate accounts for different jobs. Manually moving auth files around is easy to get wrong, and it is hard to tell which account a new session will use.
45
47
 
46
48
  Instead, Ditto CLI launches each tool pointed at the selected profile:
47
49
 
@@ -51,14 +53,17 @@ Instead, Ditto CLI launches each tool pointed at the selected profile:
51
53
  | Codex | `CODEX_HOME=~/.ditto/profiles/<name>/codex` |
52
54
  | opencode | `XDG_DATA_HOME`, `XDG_CONFIG_HOME`, and `XDG_STATE_HOME` under `~/.ditto/profiles/<name>/opencode` |
53
55
  | OMP | `omp --profile <name>` and `OMP_PROFILE=<name>` |
56
+ | Prime Agent | `PRIME_AGENT_CODING_AGENT_DIR=~/.ditto/profiles/<name>/prime-agent` and a matching `PRIME_AGENT_SESSION_DIR` |
54
57
 
55
58
  opencode has no single home variable; it resolves its directories the XDG way, so Ditto CLI pins the three bases that hold credentials, configuration, and session state. `XDG_CACHE_HOME` is deliberately left alone so profiles keep sharing opencode's downloaded tooling. Those variables are set for the launched process and anything it starts, including commands opencode's own tools run.
56
59
 
60
+ Prime Agent's own settings can name a session directory, so managed profiles also set `PRIME_AGENT_SESSION_DIR` explicitly. That keeps transcripts, session artifacts, and local harness state inside the selected profile even while reusable Prime Agent settings and capabilities are linked to yours.
61
+
57
62
  No config files are swapped. Profiles remain independent, and switching only affects the process Ditto CLI launched.
58
63
 
59
64
  ## Install
60
65
 
61
- Ditto CLI needs at least one of the supported CLIs to be useful: [Claude Code](https://code.claude.com/docs/en/setup), [OpenAI Codex CLI](https://github.com/openai/codex), [opencode](https://opencode.ai/docs/), or [Oh My Pi](https://github.com/can1357/oh-my-pi).
66
+ Ditto CLI needs at least one of the supported CLIs to be useful: [Claude Code](https://code.claude.com/docs/en/setup), [OpenAI Codex CLI](https://github.com/openai/codex), [opencode](https://opencode.ai/docs/), [Oh My Pi](https://github.com/can1357/oh-my-pi), or [Prime Agent](https://github.com/PrimeIntellect-ai/prime-agent).
62
67
 
63
68
  On macOS and Linux, Homebrew installs the prebuilt binary for your platform, so it needs no Rust toolchain:
64
69
 
@@ -126,7 +131,7 @@ ditto-cli update --check # compare versions without installing
126
131
  ditto-cli update --git # install from the Git repository instead
127
132
  ```
128
133
 
129
- `update` runs `cargo install` for you, so it needs Rust on your `PATH`. It stops early when you already have the newest release. Asking crates.io for the published version needs a network connection; without one it says so and installs anyway.
134
+ `update` runs `cargo install` for you, so it needs Rust on your `PATH`. It stops early when you already have the newest release. During a build it shows a compact animated status instead of Cargo's full compilation log; if the build fails, it prints that log so the error is not hidden. Asking crates.io for the published version needs a network connection; without one it says so and installs anyway.
130
135
 
131
136
  `update` only replaces a copy in Cargo's own bin directory. Run it against a Homebrew install, or a binary from the [releases page](https://github.com/reyanshgupta/ditto-cli/releases), and it says so before it starts, then leaves that copy alone: a `cargo install` would land in a different directory and shadow the existing binary rather than replace it. Use `brew upgrade ditto-cli` or the newer archive instead.
132
137
 
@@ -143,9 +148,9 @@ ditto-cli
143
148
  Then:
144
149
 
145
150
  1. Press `n` and name the profile, such as `work`.
146
- 2. For Claude Code, Codex, or opencode, select the profile and press `l` to run the official login flow.
147
- 3. Press `c` for Claude Code, `x` for Codex, or `o` for opencode.
148
- 4. Press `p` to launch OMP, then use `/login anthropic` or `/login openai-codex` inside OMP.
151
+ 2. Select the profile and press `l`, then choose Claude Code, Codex, opencode, or Prime Agent. Prime Agent opens directly on its `/login` dialog.
152
+ 3. Press `c` for Claude Code, `x` for Codex, `o` for opencode, or `a` for Prime Agent.
153
+ 4. Press `p` for OMP, then use `/login` inside OMP.
149
154
 
150
155
  Each tool keeps its own credentials. Signing in to one does not copy credentials into another.
151
156
 
@@ -158,7 +163,8 @@ Each tool keeps its own credentials. Signing in to one does not copy credentials
158
163
  | `x` | Launch Codex |
159
164
  | `o` | Launch opencode |
160
165
  | `p` | Launch OMP |
161
- | `l` | Sign in with Claude Code, Codex, or opencode |
166
+ | `a` | Launch Prime Agent |
167
+ | `l` | Sign in with Claude Code, Codex, opencode, or Prime Agent |
162
168
  | `L` | Sign out, with confirmation |
163
169
  | `n` | Create a profile |
164
170
  | `e` | Rename the selected profile |
@@ -170,7 +176,7 @@ Sign-in status is checked in the background, so the list stays responsive while
170
176
 
171
177
  The selected profile is remembered for the next run. The `★` default is separate and stays put: it is the profile every command uses when you leave the name out, and running `ditto-cli claude personal` once does not move it. Any profile can be the default, including the built-in `default` one. See [which profile a command uses](#which-profile-a-command-uses).
172
178
 
173
- Renaming keeps the profile's settings, session history, and its Codex and opencode logins. Claude Code is the exception, and the rename dialog says so before you commit to it: see [renaming a profile signs Claude Code out](#renaming-a-profile-signs-claude-code-out). The built-in `default` profile cannot be renamed.
179
+ Renaming keeps the profile's settings, session history, and its Codex, opencode, and Prime Agent logins. Claude Code is the exception, and the rename dialog says so before you commit to it: see [renaming a profile signs Claude Code out](#renaming-a-profile-signs-claude-code-out). The built-in `default` profile cannot be renamed.
174
180
 
175
181
  ## Command-line usage
176
182
 
@@ -182,21 +188,23 @@ ditto-cli create work
182
188
  ditto-cli rename work client-a
183
189
  ditto-cli delete work --yes # removes credentials and sessions for good
184
190
  ditto-cli list
185
- ditto-cli status client-a # sign-in state for all four tools
191
+ ditto-cli status client-a # sign-in state for all five tools
186
192
  ditto-cli paths client-a
187
193
  ditto-cli sync client-a # re-copy your Claude Code settings into it
188
194
 
189
- # Launch a tool, with short aliases for the first three
195
+ # Launch a tool, with short aliases where shown
190
196
  ditto-cli claude client-a # or: cc
191
197
  ditto-cli codex client-a # or: cx
192
198
  ditto-cli opencode client-a # or: oc
193
199
  ditto-cli omp client-a
200
+ ditto-cli prime-agent client-a # or: pa
194
201
 
195
202
  # Pass arguments to the underlying CLI after --
196
203
  ditto-cli claude client-a -- --model opus
197
204
  ditto-cli codex client-a -- --search
198
205
  ditto-cli opencode client-a -- --model anthropic/claude-opus-5
199
206
  ditto-cli omp client-a -- --model opus
207
+ ditto-cli prime-agent client-a -- --model claude-opus-4-1
200
208
 
201
209
  # Bind a directory to a profile
202
210
  ditto-cli workspace # what this directory launches with
@@ -226,6 +234,13 @@ The native authentication commands can be called through a profile too:
226
234
  ditto-cli claude client-a -- auth login
227
235
  ditto-cli codex client-a -- login
228
236
  ditto-cli opencode client-a -- auth login
237
+ ditto-cli prime-agent client-a -- /login
238
+ ```
239
+
240
+ OMP exposes login only inside its interface. Launch the selected profile, then run `/login` or `/logout` there:
241
+
242
+ ```bash
243
+ ditto-cli omp client-a
229
244
  ```
230
245
 
231
246
  Deleting is the one command that destroys something, so it asks to be meant. Without `--yes` it lists the directories it would remove and stops. The built-in `default` profile cannot be deleted; it is your own configuration, which Ditto CLI never created.
@@ -397,7 +412,7 @@ Every tool also names the profile in the window and tab title:
397
412
  ditto:client-a — Codex — my-repo
398
413
  ```
399
414
 
400
- All four tools write their own titles and keep updating them as you work, so a title set once before handing over is overwritten within moments. Instead, Ditto CLI runs the tool in a pseudoterminal and rewrites the title sequences on their way to the terminal, adding `ditto:<profile>` in front of whatever the tool called itself. You keep the tool's own title and gain the profile.
415
+ All five tools write their own titles and keep updating them as you work, so a title set once before handing over is overwritten within moments. Instead, Ditto CLI runs the tool in a pseudoterminal and rewrites the title sequences on their way to the terminal, adding `ditto:<profile>` in front of whatever the tool called itself. You keep the tool's own title and gain the profile.
401
416
 
402
417
  Everything else is forwarded byte for byte. Colours, hyperlinks, clipboard writes, mouse reporting, and anything the tool draws are untouched, and the tool still gets a real terminal, the right window size, and your keystrokes as it always did. Ditto CLI exits with the tool's own exit status.
403
418
 
@@ -430,7 +445,10 @@ ditto-cli --json status client-a
430
445
  "managed": true,
431
446
  "tools": [
432
447
  { "tool": "claude", "label": "Claude Code", "status": "signed_in", "signed_in": true },
433
- { "tool": "codex", "label": "Codex", "status": "signed_out", "signed_in": false }
448
+ { "tool": "codex", "label": "Codex", "status": "signed_out", "signed_in": false },
449
+ { "tool": "opencode", "label": "opencode", "status": "signed_in", "signed_in": true },
450
+ { "tool": "omp", "label": "OMP", "status": "signed_out", "signed_in": false },
451
+ { "tool": "prime-agent", "label": "Prime Agent", "status": "signed_in", "signed_in": true }
434
452
  ]
435
453
  }
436
454
  ```
@@ -471,8 +489,9 @@ A profile exists to be signed in as somebody else, not to be a different working
471
489
  | Codex | `skills`, `rules`, `prompts`, `plugins`, `config.toml`, `hooks.json`, `AGENTS.md`, `instructions.md` |
472
490
  | opencode | the whole configuration directory |
473
491
  | OMP | `config.yml`, `extensions` |
492
+ | Prime Agent | `settings.json`, `keybindings.json`, instructions, prompts, skills, extensions, themes, packages, and the global harness |
474
493
 
475
- These are symbolic links, so a skill you write tomorrow is in every profile the moment you save it, with nothing to sync and no copies to drift apart. Everything else — `.claude.json`, `auth.json`, sessions, history, `agent.db` — stays inside the profile, which is the whole of what a profile keeps to itself.
494
+ These are symbolic links, so a skill you write tomorrow is in every profile the moment you save it, with nothing to sync and no copies to drift apart. Everything else — `.claude.json`, `auth.json`, sessions, session artifacts, history, `agent.db` — stays inside the profile, which is the whole of what a profile keeps to itself. Prime Agent's `models.json` also stays private because custom provider definitions are allowed to contain literal API keys and secret headers.
476
495
 
477
496
  What is shared is a named list rather than everything-but-the-credentials. Ditto CLI learning about a new extension directory late costs you a missing feature; sharing a new credential file by accident would cost you the isolation the tool exists for.
478
497
 
@@ -483,14 +502,31 @@ ditto-cli sync client-a # link what can be linked, report what cannot
483
502
  ditto-cli sync client-a --adopt # replace the profile's own copies too
484
503
  ```
485
504
 
505
+ ### Downloaded skills
506
+
507
+ Sharing a directory by linking it has one cost, and Ditto CLI pays it for you.
508
+
509
+ A skill installer — `npx skills add`, and anything else that installs into more than one agent — puts the skill somewhere central and then records it in each agent's skills directory as a *relative* link, computed from the directory the agent was pointed at. Under a profile that directory is one of the links above, so the operating system writes the record into your own configuration instead, where the same relative path leads somewhere else. The skill lands on disk intact and is readable from nowhere, in every profile at once.
510
+
511
+ Ditto CLI is what moved the directory, so Ditto CLI is what can say where those links meant to point. Launching a tool repairs its own, which is the moment before it reads them, and says so:
512
+
513
+ ```
514
+ ditto-cli: repaired claude/skills/apple-design; it was installed pointing at nothing
515
+ ```
516
+
517
+ `ditto-cli sync <profile>` does the same for every tool at once and reports them under `repaired`. A link is only rewritten when reading it against the path the installer was given names something that exists, so a link that is relative and broken for reasons of its own is left exactly as it is.
518
+
486
519
  ## Where credentials and files are stored
487
520
 
488
- Ditto CLI does not ask for passwords, parse OAuth tokens, or keep credentials in its state file. Claude Code, Codex, and opencode authentication still runs through their installed CLIs, and OMP authentication through `/login` inside OMP. Each tool stores the result wherever it normally would, under the directory Ditto CLI pointed it at:
521
+ Ditto CLI does not ask for passwords, parse OAuth tokens, or keep credentials in its state file. Claude Code, Codex, and opencode authentication still runs through their installed CLIs, and OMP and Prime Agent authentication through `/login` inside their interfaces. Each tool stores the result wherever it normally would, under the directory Ditto CLI pointed it at:
489
522
 
490
523
  - **Claude Code** uses the selected `CLAUDE_CONFIG_DIR`. On macOS the credentials themselves stay in the system Keychain, keyed to that directory's path, which is what keeps two profiles from sharing one login — and why [renaming a profile signs Claude Code out](#renaming-a-profile-signs-claude-code-out).
491
524
  - **Codex** keeps its auth state under the selected `CODEX_HOME`.
492
525
  - **opencode** writes `auth.json` into the selected data directory.
493
526
  - **OMP** keeps auth, settings, sessions, and caches under `~/.omp/profiles/<name>/agent`.
527
+ - **Prime Agent** keeps ordinary provider credentials in the selected agent directory's `auth.json`; its sessions and session artifacts stay below the same profile.
528
+
529
+ Prime Agent currently has two upstream exceptions to that boundary. Prime Inference login uses the Prime CLI credential at `~/.prime/config.json`, for which Prime Agent exposes no path override; that one provider therefore remains shared across Ditto profiles. `PRIME_API_KEY` and other API-key environment variables are shared for the same reason any inherited environment credential is. Prime Agent also uses one user-wide background-service socket, so its `agents`, `list`, and `attach` views can see running agents from other profiles even though each agent receives its selected auth and session roots. Ditto's status report counts provider credentials in the isolated `auth.json`, not these ambient sources.
494
530
 
495
531
  Ditto CLI's own files are laid out like this:
496
532
 
@@ -502,21 +538,23 @@ Ditto CLI's own files are laid out like this:
502
538
  ├── work/
503
539
  │ ├── claude/
504
540
  │ ├── codex/
505
- └── opencode/
506
- ├── config/opencode/
507
- ├── data/opencode/ # auth.json lives here
508
- └── state/opencode/
541
+ ├── opencode/
542
+ ├── config/opencode/
543
+ ├── data/opencode/ # auth.json lives here
544
+ └── state/opencode/
545
+ │ └── prime-agent/ # auth.json and sessions live here
509
546
  └── personal/
510
547
  ├── claude/
511
548
  ├── codex/
512
- └── opencode/
549
+ ├── opencode/
550
+ └── prime-agent/
513
551
  ```
514
552
 
515
553
  The nested `opencode/` directory is opencode's own doing: it appends its name to every XDG base it is given. OMP profiles are the one thing kept outside this tree, since OMP manages its own profile directory.
516
554
 
517
555
  Directories are created with user-only permissions on macOS and Linux; see [Windows notes](#windows-notes) for the difference there.
518
556
 
519
- The `default` profile points to `~/.claude`, `~/.codex`, opencode's own `~/.local/share/opencode` and `~/.config/opencode` (or wherever your `XDG_*` variables already send them), and OMP's native `~/.omp/agent` profile. It exposes your existing setup without copying or migrating anything. For opencode the `default` profile resolves the same XDG bases opencode would pick on its own, so pointing at it changes nothing.
557
+ The `default` profile points to `~/.claude`, `~/.codex`, opencode's own `~/.local/share/opencode` and `~/.config/opencode` (or wherever your `XDG_*` variables already send them), OMP's native `~/.omp/agent` profile, and Prime Agent's `~/.prime/agent` directory (or `PRIME_AGENT_CODING_AGENT_DIR` when set). It exposes your existing setup without copying or migrating anything. For opencode the `default` profile resolves the same XDG bases opencode would pick on its own, so pointing at it changes nothing.
520
558
 
521
559
  ## Environment variables
522
560
 
@@ -527,6 +565,7 @@ The `default` profile points to `~/.claude`, `~/.codex`, opencode's own `~/.loca
527
565
  | `DITTO_CODEX_BIN` | Override the `codex` executable |
528
566
  | `DITTO_OPENCODE_BIN` | Override the `opencode` executable |
529
567
  | `DITTO_OMP_BIN` | Override the `omp` executable |
568
+ | `DITTO_PRIME_AGENT_BIN` | Override the `prime-agent` executable |
530
569
  | `DITTO_PROFILE` | Selected profile name exported to every launched tool, and what Claude Code's status line reports |
531
570
  | `DITTO_NO_PROXY` | Hand the terminal straight to the tool, leaving the title to it (macOS and Linux) |
532
571
  | `HERDR_PANE_ID` | Read, not set: herdr names the pane it opened, and Ditto CLI steps aside and reports the profile to herdr. See [Under herdr](#under-herdr) |
@@ -538,7 +577,7 @@ Example:
538
577
  DITTO_HOME="$HOME/.config/ditto" ditto-cli
539
578
  ```
540
579
 
541
- `ANTHROPIC_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, `OPENAI_API_KEY`, and `OPENCODE_API_KEY` are inherited by launched tools. They may override a saved subscription login, so Ditto CLI shows a warning when one is set.
580
+ API-key variables such as `ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `OPENCODE_API_KEY`, and `PRIME_API_KEY` are inherited by launched tools. They may override a saved subscription login, so Ditto CLI warns when it sees an `*_API_KEY`, `ANTHROPIC_AUTH_TOKEN`, or `HF_TOKEN` in the environment.
542
581
 
543
582
  ## Renaming a profile signs Claude Code out
544
583
 
@@ -550,7 +589,7 @@ Ditto CLI warns before the rename and tells you how to get back in:
550
589
  ditto-cli claude client-a -- auth login
551
590
  ```
552
591
 
553
- Codex and opencode keep their credentials in files inside the profile, so they survive a rename untouched.
592
+ Codex, opencode, and Prime Agent keep their ordinary credentials in files inside the profile, so they survive a rename untouched.
554
593
 
555
594
  ## Windows notes
556
595
 
@@ -584,4 +623,4 @@ cargo clippy --all-targets -- -D warnings
584
623
 
585
624
  Ditto CLI is available under the [MIT License](LICENSE).
586
625
 
587
- Ditto CLI is an independent project. It is not affiliated with Anthropic, OpenAI, Nintendo, or The Pokémon Company.
626
+ Ditto CLI is an independent project. It is not affiliated with Anthropic, OpenAI, Prime Intellect, Nintendo, or The Pokémon Company.
package/package.json CHANGED
@@ -1,12 +1,13 @@
1
1
  {
2
2
  "name": "@reyanshgupta/ditto-cli",
3
- "version": "0.3.3",
4
- "description": "Switch between multiple Claude Code, Codex, opencode, and OMP accounts on one machine",
3
+ "version": "0.3.5",
4
+ "description": "Switch between Claude Code, Codex, opencode, OMP, and Prime Agent accounts",
5
5
  "keywords": [
6
6
  "claude-code",
7
7
  "codex",
8
8
  "opencode",
9
9
  "omp",
10
+ "prime-agent",
10
11
  "profiles",
11
12
  "cli"
12
13
  ],
@@ -32,9 +33,9 @@
32
33
  "node": ">=18"
33
34
  },
34
35
  "optionalDependencies": {
35
- "@reyanshgupta/ditto-cli-darwin-arm64": "0.3.3",
36
- "@reyanshgupta/ditto-cli-darwin-x64": "0.3.3",
37
- "@reyanshgupta/ditto-cli-linux-x64": "0.3.3",
38
- "@reyanshgupta/ditto-cli-win32-x64": "0.3.3"
36
+ "@reyanshgupta/ditto-cli-darwin-arm64": "0.3.5",
37
+ "@reyanshgupta/ditto-cli-darwin-x64": "0.3.5",
38
+ "@reyanshgupta/ditto-cli-linux-x64": "0.3.5",
39
+ "@reyanshgupta/ditto-cli-win32-x64": "0.3.5"
39
40
  }
40
41
  }