feat(multi-account): codev command via bundled CLI (Batch 2b part 2)#125
Conversation
zsh only for the rc install (accounts.sh itself is bash-compatible, fish unsupported); account-aware resume covers all CodeV terminals; VS Code sessions can't switch accounts (#121). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
`codev account <cmd>` now works in the terminal without a repo checkout: - accounts.sh gains a codev() launcher that runs the CLI bundled inside CodeV.app with ELECTRON_RUN_AS_NODE (app binary doubles as Node — no system Node, no sudo, no PATH edits; rides the existing shell integration) - the app records its real .app bundle root in the registry (appPath) on every launch and regenerates accounts.sh, so moving the app self-heals the path and generator updates propagate automatically (no-op for single-account users — no registry, no writes) - forge generateAssets tsc-compiles src/cli/*.ts into resources/cli (new extraResource); the CLI accepts the `account` prefix so both `codev account list` and dev `yarn account list` work Verified locally: simulated the packaged invocation via the dev Electron binary (ELECTRON_RUN_AS_NODE=1 Electron resources/cli/ codev-account.js account list) against the real registry. tsc 0; 15/15 tests (+2 for codev() emission). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
📝 WalkthroughWalkthroughThis update introduces a bundled ChangesBundled CLI and app-path self-healing
Estimated code review effort: 3 (Moderate) | ~25 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
1 issue found across 9 files
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="forge.config.ts">
<violation number="1" location="forge.config.ts:29">
P3: Stale `.js` files accumulate in `resources/cli` across builds — tsc with `--outDir` and explicit source files never removes old output. If a source file is renamed, both `old-name.js` and `new-name.js` ship in the app bundle because the old `.js` is never cleaned up.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
- registry records appExec (the real binary path) alongside appPath; the codev() launcher prefers it — the executable inside Contents/MacOS keeps its name when the .app bundle is renamed, so deriving it from the bundle name broke on rename (user-spotted) - Accounts tab gains a header clarifying these are Claude Code (Anthropic) accounts, not CodeV accounts +1 test (16 total) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
- syncAccountsAppPath helper runs at launch AND after add/remove/ set-default/install — covers the fresh-install case where the registry is first created mid-run, so the very first accounts.sh already contains the codev() launcher (was: only after next launch) - add-notice tells fresh users to install Shell integration first when the ~/.zshrc block isn't present yet - empty Accounts list shows an explainer instead of a blank area Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
tsc never removes stale output, so a renamed source file would ship both old and new .js in the app bundle (cubic P3). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 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/popup.tsx`:
- Around line 768-776: The new Accounts tab JSX block in popup.tsx needs to be
reformatted to satisfy Prettier. Reflow the descriptive text inside the Accounts
section and the conditional {accounts.length === 0 && (...)} block so the JSX
matches the project’s formatting conventions, keeping the structure around the
Accounts tab content intact.
🪄 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: c463ec38-d87d-49f7-ad0f-18f743e2c494
📒 Files selected for processing (10)
.gitignoreCHANGELOG.mddocs/multi-account-support-design.mdforge.config.tspackage.jsonsrc/cli/account-manager.test.tssrc/cli/account-manager.tssrc/cli/codev-account.tssrc/main.tssrc/popup.tsx
MAS builds are sandboxed and ELECTRON_RUN_AS_NODE is unsupported there, so a codev() launcher pointing at a MAS install could never run — skip recording appPath on MAS (same gating family as auto-update). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
- accounts.sh gains _codev completion: subcommands + account labels (baked in, refreshed on regenerate; remove offers only non-anchor labels). Registration guarded for zsh+compinit so the file stays bash-sourceable — verified with zsh -n AND bash -n - docs: MAS builds can't run the bundled CLI (sandbox + ELECTRON_RUN_AS_NODE unsupported) — appPath skipped there Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
Reflow the header + empty-state blocks per the review's ESLint output (changed lines only — the file as a whole predates the prettier rule). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
There was a problem hiding this comment.
All reported issues were addressed across 7 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
- empty-state renders only after a successful load and never alongside an error (accountsLoaded flag) — no flash while the IPC is in flight - MAS: clear stale appPath/appExec left by a previous direct-download install and regenerate, fully suppressing the codev() launcher - completion: add the rm alias to the subcommand compadd list Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
There was a problem hiding this comment.
All reported issues were addressed across 4 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Re-trigger cubic
clearAppPath()-gated regeneration could leave a stale accounts.sh forever (registry already clean but a prior regenerate failed). Match the non-MAS branch: always regenerate when a registry exists. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017kCK4t5JSVynVZxGcrTGGp
Summary
Batch 2b part 2 (follows #124): the
codevcommand — runcodev account <cmd>from any zsh shell, no repo checkout / no system Node / no sudo required.Also carries the §6.C supported-shells docs note (written during #124, moved here per review-batching).
How it works
Bundled CLI: forge's
generateAssetshook tsc-compilessrc/cli/*.ts(plain fs/os/path — no bundling needed) intoresources/cli/, shipped inside the app viaextraResource→CodeV.app/Contents/Resources/cli/.codev()launcher in accounts.sh: the generator emitsELECTRON_RUN_AS_NODEmakes the app binary act as plain Node (the VS Codecodetrick) — so the CLI runs on the app's own runtime. It rides the existing shell-integration install: zero sudo, zero PATH edits.No hardcoded
/Applications(review point from planning): the app records its real.appbundle root in the registry (appPath) on every launch and regeneratesaccounts.sh. Moving the app self-heals on next CodeV launch; generator-template updates (like the earlierclaude-whoamifix) now propagate automatically too. No-op for single-account users (no registry → no writes).The CLI accepts the
accountprefix, socodev account list(installed form) andyarn account list(dev form) both work.Verification
ELECTRON_RUN_AS_NODE=1 node_modules/electron/dist/.../Electron resources/cli/codev-account.js account listagainst the real registry → correct output.tsc --noEmit0 errors;yarn test15/15 (+2:codev()emitted whenappPathrecorded, omitted otherwise).How to test (needs
yarn make)yarn make→ launch the built app once (it recordsappPathinto~/.config/codev/accounts.jsonand refreshesaccounts.sh— check the file gains thecodev()function).source ~/.zshrc) → runcodev account list→ same output asyarn account list.codev account show,codev account helpetc. all work anywhere (no repo cwd needed).codev account liststill works (self-heal).Tab completion
accounts.shalso ships zsh completion forcodev:codev <TAB>→account,codev account <TAB>→ subcommands,codev account default|remove <TAB>→ account labels (baked in, refreshed on regenerate;removeoffers only non-anchor labels). Registration is guarded (zsh + loaded compinit) so the file stays bash-sourceable — verified with bothzsh -nandbash -n.MAS builds (why the launcher is skipped there)
ELECTRON_RUN_AS_NODEis unsupported in MAS Electron — the bundled CLI could never run from a MAS install (exec'ing the app binary from a terminal still enforces its embedded sandbox).appPathon MAS (!isMAS()gate), so accounts.sh never advertises a brokencodev().~/.claude-reading feature set (Sessions tab etc.) has the same sandbox constraint — pre-existing, not introduced here; and no MAS build with the Claude-sessions feature set has shipped. Build-wise,yarn makeandyarn make_masboth compile/bundle the CLI fine — the gate is runtime-only.Notes
codevfunction only exists in shells that sourceaccounts.sh(consistent with the zsh-only support documented in this PR); a "real file on PATH" shim (/usr/local/bin, admin prompt) can be a later upgrade if scripts need it.resources/cliis a build artifact (gitignored).🤖 Generated with Claude Code
Summary by cubic
Adds a bundled
codevcommand so you can runcodev account <cmd>from any zsh shell without Node, sudo, or PATH edits. The app records its real install path, regeneratesaccounts.shon launch and account changes, adds zsh tab completion, survives.apprenames viaappExec, and fully suppresses the launcher on MAS builds.appPath/appExecand regenerateaccounts.shunconditionally socodev()is never advertised on MAS.rmalias to subcommand suggestions.Written for commit 4266022. Summary will update on new commits.
Summary by CodeRabbit
New Features
Bug Fixes