Skip to content

feat(multi-account): codev account CLI + global-default (Batch 2a + 2e)#123

Merged
grimmerk merged 10 commits into
mainfrom
feat/codev-account-cli
Jul 8, 2026
Merged

feat(multi-account): codev account CLI + global-default (Batch 2a + 2e)#123
grimmerk merged 10 commits into
mainfrom
feat/codev-account-cli

Conversation

@grimmerk

@grimmerk grimmerk commented Jul 6, 2026

Copy link
Copy Markdown
Owner

Summary

Batch 2a + 2e of multi-account support (follows #122 / Batch 1).

  • 2a — codev account CLI: manage the account registry + shell integration from the terminal, replacing Batch 1's hand-editing of ~/.config/codev/accounts.json + accounts.sh.
  • 2e — configurable global-default: codev account default <label> makes bare claude resolve to a chosen account; CodeV resume now bypasses the shell dispatcher so it can't be misrouted.
  • Test infra: introduces Vitest + a generator test suite and a real CI workflow (the repo had none — test_ci.yaml was a placeholder).

What's included

  • src/cli/account-manager.ts — the single shared generator: reads/writes accounts.json, generates accounts.sh (per-account launchers + claude <account> dispatcher + claude-whoami + claude-accounts). The Batch 2b Settings UI will reuse this same module (no second generator).
  • src/cli/codev-account.ts — the CLI entry.
  • src/cli/account-manager.test.ts — Vitest suite (13 tests).
  • vitest.config.ts, .github/workflows/test_ci.yaml (real CI), package.json (yarn account, yarn test).
  • src/claude-session-utility.ts — 2e: buildResumeCommand emits command claude.

How to use

codev account CLI (all commands)

Run in dev via yarn account <cmd> (a real codev binary on PATH lands in Batch 2b):

yarn account list                 # accounts + identity; '*' = bare-claude default  (alias: ls)
yarn account add <label>          # register account; dir defaults to ~/.claude-<label>
yarn account add <label> --dir D  # …with a custom config dir (validated: no shell metachars)
yarn account default <label>      # bare `claude` now resolves to <label>
yarn account remove <label>       # unregister; leaves the dir on disk  (alias: rm)
yarn account regenerate           # rewrite ~/.config/codev/accounts.sh from the registry  (alias: regen)
yarn account show                 # dry run: print the generated accounts.sh, writes nothing  (alias: preview)
yarn account install              # append the marker-guarded source block to ~/.zshrc (idempotent)
yarn account uninstall            # remove the ~/.zshrc block (keeps registry + dirs)
yarn account help                 # usage

After add/default/remove/regenerate: open a new shell or source ~/.zshrc.

Generated shell commands (what accounts.sh gives you)

claude                  # → the configured default account
claude <label> […]      # → that account, full passthrough (e.g. `claude work -r`)
claude-<label> […]      # function form (e.g. `claude-work mcp list`)
claude-whoami           # which account bare `claude` resolves to here + its auth status
claude-accounts         # list configured accounts

Launchers use env so the default account runs with CLAUDE_CONFIG_DIR explicitly
unset (env -u) and extra accounts with it explicitly set — a stray exported
CLAUDE_CONFIG_DIR can't hijack either.

Gotcha: checking the account from inside a Claude Code session

Claude Code snapshots your interactive shell — functions included — and sources it
for Bash-tool / ! commands. So inside any session, bare claude is the accounts.sh
dispatcher function, not the binary:

  • !claude auth statusauth matches no account label → dispatcher *) → the
    global default account. It reports the default's identity no matter which account
    the session itself runs under — a misleading probe.
  • !command claude auth status ✅ → command bypasses shell functions → the real
    binary inherits the session process's own CLAUDE_CONFIG_DIR → reports the session's
    actual account.
  • !echo ${CLAUDE_CONFIG_DIR:-unset} ✅ → the session's own config dir (unset = the
    anchor/default account).

Same rule for scripting: nested claude invocations from inside a session go through
the dispatcher to the global default — use command claude or an explicit
claude <label> when the account matters. (Documented in design doc §6.A.)

Cross-account sharing (Batch 3 preview — mechanism verified)

Verified while building this PR (full policy in design doc §5):

Item Shareable? Mechanism Status
Global CLAUDE.md file symlink verified live (work → personal)
skills/ dir symlink — whole-dir (auto-shares future skills) or per-entry (selective, keeps private skills) verified live
commands/ (legacy custom slash commands — functionally unified with skills) same per-config-dir file scan; dir symlink verified live (a linked legacy command appeared in a work-session skills list)
statusLine it's a settings.json key → per-key copy, not a symlink done for work
plugins/ ⚠️ payload dir may symlink, but enabledPlugins lives in each account's settings.json (+ plugin state) untested
.claude.json ❌ never identity + org + per-project trust by design
Session data (history.jsonl, projects/, sessions/) ❌ by design live-written + identity-bound; CodeV's aggregation IS the union view; cross-account resume (2c) = copy-fork a transcript by design

Sharing never silently overwrites: existing target → .codev-bak backup or skip (§5 collision policy).

How to test

Automated: yarn test (13/13). CI runs it on PRs to main.

Manual smoke-test (needs yarn make — 2e is a main-process change):

  1. CLI, read-only/safe: yarn account list, yarn account show.
  2. Generator equivalence: yarn account show output ≈ your current accounts.sh (functionally equal — verified via diff + zsh -n).
  3. 2e resume routing (the important one):
    • yarn account default work (sets bare claude → work), source ~/.zshrc.
    • In CodeV, resume a personal session → must still open under personal (not work). The command claude fix guarantees this.
    • Resume a work session → opens under work.
    • Restore with yarn account default personal when done.

Verification done

  • Generated accounts.sh is functionally equivalent to the hand-written Batch 1 file (diff) and passes zsh -n.
  • tsc --noEmit: 0 errors. yarn test: 13/13.
  • 2e command claude is behavior-unchanged when the default is the anchor, and a no-op for single-account users.
  • Smoke-tested with default work: CLI add/list/show/remove round-trip; CodeV resume of a personal session stayed personal (transcript loaded from ~/.claude/projects proves the account), work sessions resume under work.

Notes

  • This does not overwrite your live accounts.sh — run yarn account regenerate when you want the generated version.
  • 2c (per-launch account picker) is coupled with Batch 3 (cross-account sharing) — see design doc §6.G.

🤖 Generated with Claude Code


Summary by cubic

Adds the codev account CLI with a single shared generator for multi-account setup, plus a configurable global default for bare claude. Shell integration is hardened, resume uses command claude, and docs now confirm symlink-based sharing of global files works for Batch 3.

  • New Features

    • One shared generator reads/writes ~/.config/codev/accounts.json and generates accounts.sh (to be reused by the Settings UI).
    • New CLI: list, add <label> [--dir D], default <label>, remove <label>, regenerate, show, install, uninstall (run in dev with yarn account <cmd>). Global default via codev account default <label>; dispatcher fallback honors it.
    • Vitest suite and a real CI workflow (yarn test) added.
  • Bug Fixes

    • Fixed add --dir parsing; validate labels and reject shell-unsafe or invalid paths in dir and configDirEnv at add time and during accounts.sh generation.
    • Default launches via env -u CLAUDE_CONFIG_DIR claude; others via env CLAUDE_CONFIG_DIR=… claude (bypasses the dispatcher).
    • Resume uses command claude and escapes single quotes in paths. Dropped hardcoded defaultAccount and only set it when valid. claude-whoami now reports the dispatcher default and runs auth status under that account’s env. Docs clarify that inside Claude Code sessions, bare claude routes to the dispatcher default; use command claude to target the session account.

Written for commit 4f030b3. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added codev account command to manage multi-account setup (list, add, set default, remove, regenerate, preview, install/uninstall shell hooks).
    • Introduced automatic generation of account launcher scripts for switching between accounts.
  • Bug Fixes
    • Improved session resume to use the correct configuration directory for non-default accounts.
  • Tests / CI
    • Added a Vitest suite for account script generation and default resolution, plus a real CI workflow to run tests.
  • Documentation
    • Updated the multi-account support design notes and added a new changelog entry.

grimmerk and others added 2 commits July 6, 2026 14:02
Add a `codev account` CLI that manages ~/.config/codev/accounts.json and
regenerates accounts.sh from ONE shared generator, replacing Batch 1's
hand-editing. Run in dev via `yarn account <cmd>`.

- src/cli/account-manager.ts: shared registry read/write + accounts.sh
  generator (the 2b Settings UI will reuse the same generator)
- src/cli/codev-account.ts: CLI — list/add/default/remove/regenerate/
  show/install/uninstall
- src/cli/account-manager.test.ts: Vitest suite for the generator
  (default -> no env, extra -> CLAUDE_CONFIG_DIR, dispatcher * ->
  defaultAccount, whoami mapping, bash -n validity)
- Replace the placeholder CI with a real test workflow (yarn test)
- Bump 1.0.77 + CHANGELOG + design-doc §6.A/§7

Verified: generated accounts.sh is functionally equivalent to the
hand-written one (diff) and passes `zsh -n`; 9/9 tests green.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
buildResumeCommand now emits `command claude` (bypassing the accounts.sh
`claude` dispatcher) so a configured non-anchor global-default can't
re-route an anchor-account resume to the wrong account. Behavior is
unchanged when the default IS the anchor; a no-op for single-account
users (command claude == claude).

2e's shell + CLI side already shipped in 2a (`codev account default`
plus the dispatcher `*)` -> defaultAccount). Also documents the
2c <-> Batch 3 coupling (cross-account resume needs shared session data).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
@coderabbitai

coderabbitai Bot commented Jul 6, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds shared account-management logic and a codev account CLI, updates resume command generation, adds Vitest coverage/config, replaces CI, and refreshes versioning and design docs.

Changes

Multi-account management feature

Layer / File(s) Summary
Registry contract and persistence
src/cli/account-manager.ts
Defines registry/account types, path constants, shell-path helpers, identity parsing, and registry read/write normalization.
Shell script generation and hook management
src/cli/account-manager.ts
Generates accounts.sh, regenerates it to disk, and installs or removes the zsh source block in ~/.zshrc.
Account mutation operations
src/cli/account-manager.ts
Implements add, remove, default selection, and account listing against the registry, with regeneration after changes.
codev-account CLI entrypoint
src/cli/codev-account.ts
Adds command parsing, list output, subcommand dispatch, usage/help text, reload hints, and error handling for codev account.
account-manager Vitest test suite
src/cli/account-manager.test.ts
Adds Vitest coverage for shell generation, shell-safety validation, and default-account resolution.
Resume command routing fix
src/claude-session-utility.ts
Changes resume command generation to call command claude --resume and escape embedded quotes in config paths.
CI workflow, config, and docs
.github/workflows/test_ci.yaml, vitest.config.ts, package.json, CHANGELOG.md, docs/multi-account-support-design.md
Replaces the workflow with a Yarn test job, adds Vitest config, updates version/scripts/dev dependency, and revises changelog/design notes for Batch 2 progress.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Sequence Diagram(s)

sequenceDiagram
  participant codev_account as codev account
  participant account_manager as account-manager
  participant accounts_json as accounts.json
  participant accounts_sh as accounts.sh
  participant zshrc as ~/.zshrc

  codev_account->>account_manager: add/remove/default/list/install/uninstall
  account_manager->>accounts_json: readRegistry/writeRegistry
  account_manager->>accounts_sh: generateAccountsSh/regenerate
  codev_account->>account_manager: installShellHook/uninstallShellHook
  account_manager->>zshrc: append or remove guarded source block
Loading

Possibly related PRs

  • grimmerk/codev#102: Also changes resume command construction in src/claude-session-utility.ts, with overlapping claude --resume routing behavior.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: the new account CLI and global-default support for Batch 2a/2e.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/codev-account-cli

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/claude-session-utility.ts`:
- Around line 1081-1093: The resume command builder is interpolating
CLAUDE_CONFIG_DIR without escaping, so paths containing quotes can break the
shell command. Update buildResumeCommand to shell-escape the configDir value
returned by getResumeConfigDirEnv before placing it into the single-quoted
prefix, keeping the rest of the command assembly unchanged.

In `@src/cli/account-manager.ts`:
- Around line 155-210: The generated shell snippet in account-manager’s
formatter block has Prettier violations in the repeated L.push() assembly for
the claude launcher script. Update the code in this section to match Prettier’s
formatting expectations, especially around array-like argument lists and
trailing commas in multiline constructs, so the generated content passes
prettier/prettier checks. Use the L.push sequence that builds the claude,
claude-whoami, and claude-accounts functions as the place to apply the
formatting cleanup.
- Around line 94-102: `readRegistry()` is initializing a new registry with a
hardcoded defaultAccount of 'personal', which prevents `addAccount()` from
selecting the first added account as the default and can leave stale defaults in
place. Update `readRegistry()` so a missing registry starts without any default
account, and ensure `addAccount()` remains responsible for setting the default
only when none exists; use the existing `Registry` shape and `defaultAccount`
handling in `readRegistry` and `addAccount` to locate the change.
- Around line 142-145: The `opts.dir` value is being written into `accounts.sh`
and later sourced, so it must not be interpolated raw into shell content. Update
the account generation flow in `launchPrefix` and the
`claude-whoami`/`claude-accounts` builders to either reject unsafe `--dir`
values up front or escape them with strict shell-safe quoting before persisting.
Make sure the fix covers any path that can contain quotes or shell expansion
characters so the generated wrapper and case entries cannot be broken or
evaluated unexpectedly.

In `@src/cli/codev-account.ts`:
- Around line 73-83: The add command in codev-account.ts is picking the wrong
account label when --dir appears before the label because the label scan
includes the directory value; update the label selection logic in the add case
so it ignores the argument immediately following --dir while still using
getFlag(rest, '--dir') for the directory. Keep the fix local to the add branch
and verify manager.addAccount receives the actual label token (for example, the
work name) instead of the path.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 96ee50bd-1912-4983-be6b-c251cde9bd3f

📥 Commits

Reviewing files that changed from the base of the PR and between ce29c11 and d77f2f9.

⛔ Files ignored due to path filters (1)
  • yarn.lock is excluded by !**/yarn.lock, !**/*.lock
📒 Files selected for processing (9)
  • .github/workflows/test_ci.yaml
  • CHANGELOG.md
  • docs/multi-account-support-design.md
  • package.json
  • src/claude-session-utility.ts
  • src/cli/account-manager.test.ts
  • src/cli/account-manager.ts
  • src/cli/codev-account.ts
  • vitest.config.ts

Comment thread src/claude-session-utility.ts
Comment thread src/cli/account-manager.ts
Comment thread src/cli/account-manager.ts Outdated
Comment thread src/cli/account-manager.ts Outdated
Comment thread src/cli/codev-account.ts

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

7 issues found across 10 files

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/cli/account-manager.ts Outdated
Comment thread src/cli/account-manager.ts Outdated
Comment thread src/cli/account-manager.ts
Comment thread src/cli/codev-account.ts Outdated
Comment thread src/claude-session-utility.ts
Comment thread src/cli/account-manager.ts Outdated
Comment thread vitest.config.ts
- add: skip the --dir value when picking the label, so
  `add --dir /foo work` registers `work` (was misread as `/foo`)
- shell safety: assertSafeDir rejects shell-metachar dirs at add time
  AND at generation, so a crafted --dir / hand-edited registry can't
  inject code into the sourced accounts.sh
- default account: launch via `env -u CLAUDE_CONFIG_DIR claude` so a
  stray exported CLAUDE_CONFIG_DIR can't hijack it; extra accounts use
  `env CLAUDE_CONFIG_DIR=... claude` (env also bypasses the dispatcher)
- resume: single-quote-escape configDir so an apostrophe in the path
  can't break buildResumeCommand
- registry: drop the hardcoded defaultAccount='personal'; set it only
  when it doesn't name a real account (no dangling reference)
- prettier-format the new cli files; +1 injection-rejection test (10/10)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 4 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/cli/account-manager.ts">

<violation number="1" location="src/cli/account-manager.ts:172">
P1: Sourcing generated accounts.sh is still injectable via `configDirEnv` from `accounts.json`. The new guard validates `a.dir` only, so validating `a.configDirEnv` before rendering would close this path.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

Comment thread src/cli/account-manager.ts Outdated
The dir guard didn't cover configDirEnv, which launchCmd embeds as the
launcher's CLAUDE_CONFIG_DIR — a hand-edited registry could pass a clean
dir but an injectable configDirEnv. Validate both at generation.
(cubic P1 follow-up.) +1 test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/cli/account-manager.test.ts (1)

76-90: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test doesn't isolate the dir check.

Both dir and configDirEnv are set to the same unsafe string, so this test can't distinguish whether the thrown error comes from the dir validation or the configDirEnv validation (which is already covered separately at Line 105-119). Use a clean configDirEnv here to truly isolate the dir check.

♻️ Proposed fix
   it('rejects an account dir with shell-unsafe characters', () => {
     const bad = reg({
       defaultAccount: 'evil',
       accounts: [
         {
           label: 'evil',
           dir: '/tmp/$(touch pwned)',
           identityFile: '/tmp/x/.claude.json',
-          configDirEnv: '/tmp/$(touch pwned)',
+          configDirEnv: '/tmp/clean',
           isDefault: false,
         },
       ],
     });
     expect(() => generateAccountsSh(bad)).toThrow(/Unsafe shell characters/);
   });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli/account-manager.test.ts` around lines 76 - 90, The generateAccountsSh
test for shell-unsafe paths is not isolating the dir validation because the
account fixture in account-manager.test.ts sets both dir and configDirEnv to the
same unsafe value. Update the test case around generateAccountsSh to keep dir
unsafe while using a clean configDirEnv, so the assertion specifically exercises
the dir check and does not overlap with the separate configDirEnv validation
already covered elsewhere.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/cli/account-manager.test.ts`:
- Around line 76-90: The generateAccountsSh test for shell-unsafe paths is not
isolating the dir validation because the account fixture in
account-manager.test.ts sets both dir and configDirEnv to the same unsafe value.
Update the test case around generateAccountsSh to keep dir unsafe while using a
clean configDirEnv, so the assertion specifically exercises the dir check and
does not overlap with the separate configDirEnv validation already covered
elsewhere.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7458d333-fe41-4a24-97e7-54d99e40ed3f

📥 Commits

Reviewing files that changed from the base of the PR and between d77f2f9 and 3c9b0a4.

📒 Files selected for processing (4)
  • src/claude-session-utility.ts
  • src/cli/account-manager.test.ts
  • src/cli/account-manager.ts
  • src/cli/codev-account.ts
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/claude-session-utility.ts
  • src/cli/codev-account.ts
  • src/cli/account-manager.ts

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 2 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="src/cli/account-manager.ts">

<violation number="1" location="src/cli/account-manager.ts:177">
P2: A hand-edited accounts.json with a non-string `configDirEnv` can still crash `regenerate` after this validation step. Since this path is explicitly defending against edited registries, it would be safer to reject non-string or empty `configDirEnv` values before calling `expandHome`/`assertSafeDir`.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Re-trigger cubic

Comment thread src/cli/account-manager.ts Outdated
grimmerk and others added 6 commits July 6, 2026 23:47
A hand-edited accounts.json with a non-string or empty configDirEnv
slipped past the truthy guard and would crash toShellPath. assertSafeDir
now rejects non-string/empty values, and the loop validates every
non-null configDirEnv. (cubic P2 follow-up.) +1 test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
whoami read the ambient CLAUDE_CONFIG_DIR (unset -> anchor), but bare
`claude` always routes through the dispatcher `*)` to the configured
default. So after `default work`, whoami wrongly showed personal.
Now it reports the default account and runs auth status under that
account's env. +test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
Inside a Claude Code session, Bash/! commands source the shell snapshot
(functions included), so bare `claude` hits the accounts.sh dispatcher
and routes to the global default — not the session's account. Document
the valid probes (command claude / echo CLAUDE_CONFIG_DIR).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
- generateAccountsSh validates labels (LABEL_RE) alongside dirs — labels
  are embedded as function names and case patterns, and add's check is
  bypassable by hand-editing the registry
- removeAccount returns the new default only when the removal actually
  reassigned it, so `remove` of a non-default account no longer prints
  a misleading 'default account is now X'
- docs §5: per-key settings copy note (statusLine et al.)
+1 test (13 total)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
Probed a work-account -p session: the symlinked skills/ entry appeared
in its skills list and the symlinked global CLAUDE.md's rules were in
context. Batch 3's remaining work is UX, not feasibility.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
Batch 3 share UX: never silently overwrite (.codev-bak or skip);
link/copy/skip per item; symlink-to-dir works (hard links don't) —
per-entry = selective + private skills but new skills need a new link,
whole-dir = zero-maintenance auto-share; plugins untested
(enabledPlugins lives in per-account settings); session data stays
unshared by design — 2c cross-account resume = copy-fork.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
@grimmerk grimmerk merged commit ad781ef into main Jul 8, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant