ai-accounts
v0.3.15
Published
Reusable account management, login orchestration, chat, and PTY session package for AI CLI backends — **Claude**, **Codex**, **Gemini**, **OpenCode**.
Readme
ai-accounts
Reusable account management, login orchestration, chat, and PTY session package for AI CLI backends — Claude, Codex, Gemini, OpenCode.
Python (Litestar) sidecar API + TypeScript / Vue 3 client packages. Apache-2.0.
Latest release: 0.3.9 (CHANGELOG)
What this is
Many AI CLI tools (claude, codex, gemini, opencode) authenticate via OAuth
and store credentials in per-tool config dirs or the system Keychain. Wiring one
account works; juggling several across multiple backends, isolating their config
dirs, and routing chat/PTY traffic through a unified API gets fiddly fast.
ai-accounts is the layer that does it for you:
- Per-account isolation: each account gets its own
CLAUDE_CONFIG_DIR/CODEX_HOME/ etc., so multiple Codex accounts (for example) don't clobber each other. - Onboarding wizard: a Vue component drives the whole add-account flow — CLI install check, OAuth/device-code, eager paste-code, optional CLIProxyAPI registration.
- Smart chat panel: single backend, fan-out to all backends, or compound-mode synthesis through a primary backend. Live streaming, tool-call process groups, tokens-in/out tracking, and per-backend account labels.
- PTY sessions over WebSocket for interactive CLI work.
- Live model discovery from CLIProxyAPI when registered, with static fallbacks per backend so the dropdown is never empty.
- Pluggable adapters for storage (sqlite/sqlalchemy), vault (env-key AES-GCM, KMS, vault, keychain), and auth (none/api-key/OIDC).
Packages
| Package | Kind | npm / PyPI |
| ------------------------------------ | ---- | ----------------------------------------------------------------------- |
| ai-accounts-core | Py | workspace (depends from ai-accounts-litestar); ships ClaudeBackend, CodexBackend, GeminiBackend, OpenCodeBackend |
| ai-accounts-litestar | Py | workspace |
| @ai-accounts/ts-core | TS | npm |
| @ai-accounts/vue-headless | TS | npm |
| @ai-accounts/vue-styled | TS | npm |
| apps/playground | App | private — local-dev showcase |
Known limitations
- macOS Claude isolation (multi-account). The Claude CLI on darwin stores OAuth credentials in the system Keychain (
service="Claude Safe Storage",account="Claude Key"). Keychain entries are not scoped byCLAUDE_CONFIG_DIR, so adding a second Claude account via the OAuth/loginflow on macOS will replace the first account's credential. Workarounds: use one Claude account per macOS user, or route Claude through CLIProxyAPI (which stores credentials under its ownauth-dir, properly scoped). Tracked for a future release — proper fix likely requires per-account containers or upstream support. The wizard surfaces an informed-consent banner before the 2nd Claude add on darwin.
Quickstart — playground
The playground app is the fastest way to try the wizard, account list, remove button, and chat panel against real CLI accounts.
git clone https://github.com/ca1773130n/ai-accounts.git
cd ai-accounts
# Sets up Python (uv) + JS (pnpm) workspaces.
just setup
# Start both: Python sidecar API on :30000, Vite dev server on :6173.
pnpm --filter playground start
# Open http://localhost:6173/Override the API host/port with env vars:
AIA_HOST=0.0.0.0 AIA_PORT=8080 pnpm --filter playground serverUse as a library — JS
import { AiAccountsClient } from '@ai-accounts/ts-core'
import { AccountWizard, AiChatPanel } from '@ai-accounts/vue-styled'
import { aiAccountsPlugin } from '@ai-accounts/vue-headless'
import '@ai-accounts/vue-styled/styles.css'
const client = new AiAccountsClient({ baseUrl: 'http://localhost:30000' })
app.use(aiAccountsPlugin, { client })
// then in a component:
// <AccountWizard @done="onAccountAdded" />
// <AiChatPanel density="detailed" />Use as a library — Python
from ai_accounts_core.adapters.auth_apikey import ApiKeyAuth
from ai_accounts_core.adapters.storage_sqlite import SqliteStorage
from ai_accounts_core.adapters.vault_envkey import EnvKeyVault
from ai_accounts_core.backends import (
ClaudeBackend, CodexBackend, GeminiBackend, OpenCodeBackend,
)
from ai_accounts_litestar.app import create_app
from ai_accounts_litestar.config import AiAccountsConfig
app = create_app(AiAccountsConfig(
env="production",
storage=SqliteStorage("./accounts.db"),
vault=EnvKeyVault.from_env(env="production"), # AI_ACCOUNTS_VAULT_KEY
auth=ApiKeyAuth(keys={"sk-..."}),
backends=(ClaudeBackend(), CodexBackend(), GeminiBackend(), OpenCodeBackend()),
))Development — just recipes
just setup # uv sync + pnpm install
just test # both Python + JS test suites
just test-py # Python only
just test-js # JS only
just lint # ruff check + format check + pnpm -r lint
just format # ruff format + ruff fix
just typecheck # mypy + vue-tsc
just build # pnpm -r build
just codegen # regen wire types + OpenAPI
# Release
just bump 0.4.0 # version bump in lockstep across all packages
just release 0.4.0 # tag, push, npm publish — refuses dirty tree / non-mainArchitecture
See docs/superpowers/ARCHITECTURE.md for
the package dependency graph, layer protocols, and data flow.
See docs/superpowers/MAINTENANCE.md for
operational knowledge — dependency inventory, upgrade paths, schema migrations,
release process.
Contributing
See CONTRIBUTING.md. Issues and PRs welcome.
License
Apache-2.0. See LICENSE.
