{"id":46097925,"url":"https://github.com/yuanchuan/aivo","last_synced_at":"2026-04-29T08:03:37.842Z","repository":{"id":340931941,"uuid":"1167252967","full_name":"yuanchuan/aivo","owner":"yuanchuan","description":"Any model in your coding agent","archived":false,"fork":false,"pushed_at":"2026-04-22T10:38:10.000Z","size":2312,"stargazers_count":9,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-22T12:29:34.923Z","etag":null,"topics":["claude-code","codex","gemini-cli","github-copilot","openrouter","vercel-ai-gateway"],"latest_commit_sha":null,"homepage":"https://getaivo.dev","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yuanchuan.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-26T05:08:24.000Z","updated_at":"2026-04-22T10:38:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"07df5ccd-a069-4c85-8159-fbee21a4c4a1","html_url":"https://github.com/yuanchuan/aivo","commit_stats":null,"previous_names":["yuanchuan/aivo"],"tags_count":40,"template":false,"template_full_name":null,"purl":"pkg:github/yuanchuan/aivo","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuanchuan%2Faivo","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuanchuan%2Faivo/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuanchuan%2Faivo/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuanchuan%2Faivo/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yuanchuan","download_url":"https://codeload.github.com/yuanchuan/aivo/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yuanchuan%2Faivo/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32161325,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-22T17:06:48.269Z","status":"ssl_error","status_checked_at":"2026-04-22T17:06:19.037Z","response_time":58,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["claude-code","codex","gemini-cli","github-copilot","openrouter","vercel-ai-gateway"],"created_at":"2026-03-01T19:07:13.165Z","updated_at":"2026-04-29T08:03:37.836Z","avatar_url":"https://github.com/yuanchuan.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"# aivo\n\nA CLI for managing API keys and running Claude Code, Codex, Gemini, OpenCode, and Pi across providers.\n\n## What it does\n\n- Stores multiple provider API keys, encrypted at rest.\n- Runs `claude`, `codex`, `gemini`, `opencode`, and `pi` against any saved key.\n- Includes a chat TUI and a one-shot `-x` mode.\n- Can expose the active provider as a local OpenAI-compatible server.\n\n## Install\n\nHomebrew:\n\n```bash\nbrew install yuanchuan/tap/aivo\n```\n\nInstall script:\n\n```bash\ncurl -fsSL https://getaivo.dev/install.sh | bash\n```\n\nVia npm (recommended for Windows users):\n\n```bash\nnpm install -g @yuanchuan/aivo\n```\n\nOr download a binary from [GitHub Releases](https://github.com/yuanchuan/aivo/releases).\n\n\n## Quick Start\n\naivo ships with a free built-in provider (`aivo/starter`) that activates on first run — no API key needed:\n\n```bash\naivo -x hello\naivo claude\n```\n\nAdd your own provider key for access to more models:\n\n```bash\n# 1) Add a provider key (OpenRouter, Vercel AI Gateway, etc.)\naivo keys add\n\n# 2) Launch your tool\naivo claude\n\n# 3) Optionally pin a model\naivo claude --model moonshotai/kimi-k2.5\n```\n\nUse your GitHub Copilot subscription.\n\n```bash\naivo keys add        # pick \"GitHub Copilot\" from the provider list\naivo claude\n```\n\nUse local models via Ollama.\n\n```bash\naivo keys add        # pick \"Ollama\" from the provider list\n\n# auto-pulls the model if not present\naivo claude --model llama3.2\n```\n\n## Commands\n\n| Command | Description |\n| ------- | ----------- |\n| [run](#run) | Launch an AI tool (claude, codex, gemini, opencode, pi) |\n| [keys](#keys) | Manage API keys (add, use, rm, cat, edit, ping) |\n| [models](#models) | List available models from the active provider |\n| [alias](#alias) | Create short names for models |\n| [chat](#chat) | Interactive chat TUI or one-shot `-x` mode |\n| [image](#image) | Generate images from a text prompt |\n| [serve](#serve) | Local OpenAI-compatible API server |\n| [info](#info) | Show system info, keys, tools, and directory state |\n| [logs](#logs) | Query local SQLite logs for chat, run, and serve |\n| [stats](#stats) | Show usage statistics |\n| [context](#context) | Show recent cross-CLI activity for this project |\n| [update](#update) | Update to the latest version |\n\n## run\n\nLaunch an AI tool with the active provider key. All extra arguments are passed through to the underlying tool.\n\nSupported tools:\n\n- `claude` [Claude Code](https://github.com/anthropics/claude-code)\n- `codex` [Codex](https://github.com/openai/codex)\n- `gemini` [Gemini CLI](https://github.com/google-gemini/gemini-cli)\n- `opencode` [OpenCode](https://github.com/anomalyco/opencode)\n- `pi` [Pi Coding Agent](https://github.com/badlogic/pi-mono/tree/main/packages/coding-agent)\n\nThe `run` keyword is optional — tool names work directly as shortcuts, so `aivo claude` is equivalent to `aivo run claude`.\n\n```bash\naivo run claude\naivo claude \"fix the login bug\"\naivo claude --dangerously-skip-permissions\naivo claude --resume 16354407-050e-4447-a068-4db222ff841\n```\n\n#### `--model, -m`\n\nPick a model for one run, or omit the value to open the model picker:\n\n```bash\naivo claude --model moonshotai/kimi-k2.5\naivo claude --model                      # opens model picker\naivo claude -m                           # short form\n```\n\n#### `--key, -k`\n\nSelect a saved key by ID or name:\n\n```bash\naivo claude --key openrouter\naivo claude --key copilot\naivo claude --key                        # opens key picker\n```\n\n#### `--refresh, -r`\n\nBypass cache and fetch a fresh model list for the picker:\n\n```bash\naivo claude -r\n```\n\n#### `--dry-run`\n\nPreview the resolved command and environment without launching:\n\n```bash\naivo claude --dry-run\n```\n\n#### `--env, -e`\n\nInject extra environment variables into the child process:\n\n```bash\naivo claude --env BASH_DEFAULT_TIMEOUT_MS=60000\n```\n\n#### Claude per-slot model overrides\n\nPin a different model to one of Claude Code's named slots without touching the others. Bare flag opens the model picker:\n\n```bash\naivo claude --reasoning-model claude-opus-4-6\naivo claude --subagent-model claude-haiku-4-5\naivo claude --haiku-model    claude-haiku-4-5\naivo claude --sonnet-model   claude-sonnet-4-6\naivo claude --opus-model                       # picker\n```\n\n#### `--1m` / `--2m` / `--max-context`\n\nClaude only. Append the canonical `[1m]`/`[2m]` suffix to the resolved model so Claude Code uses the 1M or 2M context window:\n\n```bash\naivo claude --1m\naivo claude --max-context=2m\naivo claude -m claude-sonnet-4-6 --1m          # equivalent to -m 'claude-sonnet-4-6[1m]'\n```\n\n#### `--debug`\n\nJSONL HTTP logger. Records every upstream request/response from this launch to a file (default path printed at startup, or pass an explicit path):\n\n```bash\naivo claude --debug\naivo claude --debug=/tmp/aivo-http.jsonl\n```\n\n#### `--context, -c`\n\nInject a past session from another CLI as background context for this launch. Bridges cross-tool handoffs that each tool's native `--resume` can't span — e.g. pick up in Claude where Codex left off:\n\n```bash\naivo claude --context                    # opens session picker\naivo claude --context=abc123             # specific session (prefix match)\n```\n\nUse `aivo context` to see available session IDs.\n\n#### `--as \u003cname\u003e`\n\nGive this launch a nickname so other tools in the same directory can query its live session by name instead of juggling session IDs:\n\n```bash\naivo claude --as reviewer\naivo codex --as coder\n```\n\nCross-tool MCP is enabled by default — each tool auto-registers under its CLI name (`claude`, `codex`, etc.), incrementing on collision (`claude-2`, `claude-3`). Use `--as` only to override. Claude and Codex can call each other via `list_sessions` / `get_session`; Pi, Gemini, and OpenCode are read-only peers (queryable, but they can't query others).\n\n#### `aivo run`\n\nWithout a tool name, `aivo run` opens the interactive start flow and remembers your last key + tool selection. The next `aivo run` skips the picker and launches that tool directly.\n\n```bash\naivo run\n```\n\n## keys\n\nManage saved API keys. Keys are stored locally and encrypted in the user config directory.\n\n```bash\naivo keys                                # list all keys\naivo keys --ping                         # list with live ping status\naivo keys --json                         # machine-readable list (secret excluded)\n```\n\n#### `keys add`\n\nAdd a new provider key. Interactive by default, or pass `--name`, `--base-url`, and `--key` for scripted setup:\n\n```bash\naivo keys add\naivo keys add --name openrouter --base-url https://openrouter.ai/api/v1 --key sk-xxx\naivo keys add --name groq --base-url https://api.groq.com/openai/v1 --key sk-xxx\naivo keys add --name deepseek --base-url https://api.deepseek.com/v1 --key sk-xxx\n```\n\nAny endpoint that speaks a supported protocol can be saved — you are not limited to the providers above.\n\nRunning `aivo keys add` with no flags opens an interactive picker that covers the built-in OAuth flows:\n\n- **GitHub Copilot** — uses your Copilot subscription via OAuth device flow\n- **OpenAI Codex (ChatGPT)** — browser login, multi-account\n- **Claude Code (Anthropic)** — browser login, multi-account\n- **Gemini (Google)** — browser login, multi-account\n- **Ollama** — connects to a local Ollama instance (auto-starts if needed)\n- **aivo starter** — free built-in provider (auto-created on first run, re-add if removed)\n\nTyping a matching name as the label (e.g. `aivo keys add codex`) pre-focuses the picker on that row, so it's still a one-keypress confirm.\n\n```bash\naivo keys add                  # open the picker\naivo keys add codex            # picker with Codex pre-focused\naivo keys add aivo-starter     # non-interactive re-add\n```\n\n#### `keys use`\n\nSwitch the active key by name or ID:\n\n```bash\naivo keys use openrouter\naivo keys use                            # opens key picker\naivo use openrouter                      # shortcut\n```\n\n#### `keys cat`\n\nPrint the decrypted key details:\n\n```bash\naivo keys cat\naivo keys cat openrouter\n```\n\n#### `keys edit`\n\nEdit a saved key interactively:\n\n```bash\naivo keys edit\naivo keys edit openrouter\n```\n\n#### `keys rm`\n\nRemove a saved key:\n\n```bash\naivo keys rm openrouter\n```\n\n#### `keys ping`\n\nHealth-check the active key, or all keys:\n\n```bash\naivo keys ping\naivo keys ping --all\naivo ping                                # shortcut\n```\n\n## models\n\nList models available from the active provider. Model lists are cached for one hour.\n\n```bash\naivo models\n```\n\n#### `--refresh, -r`\n\nBypass the cache and fetch a fresh model list:\n\n```bash\naivo models --refresh\n```\n\n#### `--key, -k`\n\nList models for a different saved key:\n\n```bash\naivo models --key openrouter\n```\n\n#### `--search, -s`\n\nFilter models by substring:\n\n```bash\naivo models -s sonnet\n```\n\n#### `--json`\n\nOutput the model list as JSON:\n\n```bash\naivo models --json | jq '.models[].id'\n```\n\n## chat\n\n`aivo chat` starts the full-screen chat UI.\n\n```bash\naivo chat\n```\n\n#### `--model, -m`\n\nSpecify or change the chat model. Omit the value to open the model picker. The selected model is remembered per saved key.\n\n```bash\naivo chat --model gpt-4o\naivo chat -m claude-sonnet-4-5\naivo chat --model                        # opens model picker\n```\n\n#### `--key, -k`\n\nUse a different saved key for this chat session:\n\n```bash\naivo chat --key openrouter\naivo chat -k                             # opens key picker\n```\n\n#### `--execute, -x`\n\nSend a single prompt and exit. When `-x` has a message, piped stdin is appended as context. When `-x` has no message, the entire stdin becomes the prompt.\n\n```bash\naivo chat -x \"Summarize this repository\"\ngit diff | aivo -x \"Write a one-line commit message\"\ncat error.log | aivo -x\naivo -x                                 # type interactively, Ctrl-D to send\n```\n\n`aivo -x` is a shortcut for `aivo chat -x`.\n\n#### `--attach`\n\nAttach text files or images to the next message (repeatable):\n\n```bash\naivo chat --attach README.md --attach screenshot.png\n```\n\n#### `--refresh, -r`\n\nBypass the model cache when opening the model picker:\n\n```bash\naivo chat -r\n```\n\n#### `--json`\n\nWith `-x`, print the provider's raw response body (same shape as `curl`).\n\n```bash\naivo chat -x \"hello\" --json | jq -r '.choices[0].message.content'\n```\n\n#### Slash commands\n\nInside the chat TUI:\n\n| Command | Description |\n| ------- | ----------- |\n| `/new` | Start a fresh chat with the current key and model |\n| `/resume [query]` | Resume a saved chat from this directory |\n| `/model [name]` | Switch the current chat model |\n| `/key [id\\|name]` | Switch to another saved key for this chat |\n| `/attach \u003cpath\u003e` | Attach a text file or image to the next message |\n| `/detach \u003cn\u003e` | Remove one queued attachment by number |\n| `/help` | Open command help |\n| `/exit` | Leave chat |\n| `//message` | Send a literal leading slash |\n\n## image\n\nGenerate images from a text prompt against the active provider's image API (e.g. `gpt-image-1`, `dall-e-3`, Gemini image models). Experimental.\n\n```bash\naivo image \"a red panda in space\"\naivo image \"logo sketch\" -m dall-e-3 -o logo.png\n```\n\n#### Common flags\n\n```bash\naivo image \"...\" --model gpt-image-1\naivo image \"...\" --key openrouter\naivo image \"...\" --output ./out/{ts}-{model}.png   # path or template\naivo image \"...\" --size 1792x1024 --quality hd\naivo image \"...\" --url                              # print provider URL, skip download\naivo image \"...\" --json                             # machine-readable\n```\n\n## serve\n\n`aivo serve` exposes the active provider as a local OpenAI-compatible endpoint, for scripts and tools that already speak the OpenAI API.\n\n```bash\naivo serve                               # http://127.0.0.1:24860\n```\n\n#### `--port, -p`\n\nListen on a custom port (default: 24860):\n\n```bash\naivo serve --port 8080\naivo serve -p 8080\n```\n\n#### `--host`\n\nBind to a specific address (default: 127.0.0.1):\n\n```bash\naivo serve --host 0.0.0.0               # expose on all interfaces\n```\n\n#### `--key, -k`\n\nUse a different saved key:\n\n```bash\naivo serve --key openrouter\naivo serve -k                            # opens key picker\n```\n\n#### `--log`\n\nEnable request logging. Logs to stdout by default, or to a file if a path is given:\n\n```bash\naivo serve --log | jq .                  # JSONL to stdout\naivo serve --log /tmp/requests.jsonl     # JSONL to file\n```\n\n#### `--failover`\n\nEnable multi-key failover on 429/5xx errors. Automatically retries with other saved keys:\n\n```bash\naivo serve --failover\n```\n\n#### `--cors`\n\nEnable CORS headers for browser-based clients:\n\n```bash\naivo serve --cors\n```\n\n#### `--timeout`\n\nUpstream request timeout in seconds (default: 300, 0 = no timeout):\n\n```bash\naivo serve --timeout 60\n```\n\n#### `--auth-token`\n\nRequire a bearer token. Auto-generated if no value given:\n\n```bash\naivo serve --auth-token                  # auto-generated token\naivo serve --auth-token my-secret        # specific token\n```\n\n## alias\n\nCreate short names. Two flavors share one namespace:\n\n- **Model alias** — short name → model name, accepted anywhere `-m`/`--model` works.\n- **Launch alias** — short name → preset (tool + flags), invoked via `aivo run \u003cname\u003e` or just `aivo \u003cname\u003e`.\n\n```bash\naivo alias                                                 # list all aliases\n```\n\n#### Model aliases\n\n```bash\naivo alias fast=claude-haiku-4-5\naivo alias best claude-sonnet-4-6                          # positional form\n```\n\nUse anywhere a model name is accepted:\n\n```bash\naivo claude -m fast\naivo chat -m best\n```\n\n#### Launch aliases\n\nWhen the first arg after the name is a known tool (`claude`, `codex`, `gemini`, `opencode`, `pi`), the alias becomes a launch preset:\n\n```bash\naivo alias quick claude --key work --model fast --max-context 1m\naivo alias dev   codex  --key openrouter --model claude-sonnet-4-6\n```\n\nRun them:\n\n```bash\naivo run quick                    # full form\naivo quick                        # top-level shortcut\n```\n\nOverride individual flags by re-typing them on the command line — explicit user flags win over the bundle's preset. `-k`/`--key`, `-m`/`--model`, and `--1m`/`--2m`/`--max-context` are recognized as equivalent for the override:\n\n```bash\naivo run quick --model other      # bundle's --model swapped out, --key still applies\naivo quick -k personal            # bundle's --key overridden via short form\n```\n\nA launch alias's `--model` can itself reference a model alias — `quick --model fast` resolves through `fast` to `claude-haiku-4-5`.\n\n#### Remove an alias\n\n`rm` works for both kinds:\n\n```bash\naivo alias rm fast\naivo alias rm quick\n```\n\n#### `--json`\n\nOutput the alias list as JSON. Model entries are JSON strings; launch entries are `{\"tool\": ..., \"args\": [...]}` objects:\n\n```bash\naivo alias --json\n```\n\n#### Reserved names\n\nAlias names that collide with built-in subcommands, shortcut keywords (`use`, `ping`), or AI tool names (`claude`, `codex`, etc.) are rejected at definition time so they don't shadow `aivo \u003cname\u003e` dispatch.\n\n## info\n\nShow an overview of saved keys, installed tools, the last remembered tool/model selection, and the cached model count for the active key. (`ls` is accepted as an alias.)\n\n```bash\naivo info\n```\n\n#### `--ping`\n\nAlso health-check all keys:\n\n```bash\naivo info --ping\n```\n\n#### `--json`\n\nOutput info as JSON (combines with `--ping`):\n\n```bash\naivo info --json\naivo info --ping --json | jq '.keys[] | select(.ping.ok==false)'\n```\n\n## logs\n\nQuery the local SQLite log database used by aivo chat, run, and serve. Chat logs include turn content and token usage. `run` logs record launch metadata only. `serve` logs record request metadata only.\n\n`aivo logs` prints entries newest-first.\n\n```bash\naivo logs\n```\n\n#### `show \u003cid\u003e`\n\nShow one entry in detail:\n\n```bash\naivo logs show 7m2q8k4v9cpr\n```\n\n#### `status`\n\nShow entry counts, database size, and path:\n\n```bash\naivo logs status\n```\n\n#### Filters\n\n```bash\naivo logs --by chat -n 5\naivo logs --by claude --errors\naivo logs -s \"rate limit\"\naivo logs --model sonnet\naivo logs --key openrouter\naivo logs --cwd /path/to/project\naivo logs --since \"2025-01-01\" --until \"2025-02-01\"\naivo logs --json\n```\n\n#### Live watch\n\nPoll and refresh matching logs continuously:\n\n```bash\naivo logs --by run --watch\naivo logs --watch --jsonl\n```\n\n## stats\n\nShow usage statistics across all tools. Aggregates token counts from aivo chat, Claude Code, Codex, Gemini, OpenCode, and Pi by reading each tool's native data files. Per-file caching makes subsequent runs fast.\n\n```bash\naivo stats\n```\n\n#### Positional argument\n\nShow stats for a single tool:\n\n```bash\naivo stats claude\naivo stats chat\n```\n\n#### `--numbers, -n`\n\nShow exact numbers instead of human-readable approximations:\n\n```bash\naivo stats -n\n```\n\n#### `--search, -s`\n\nFilter by key, model, or tool name:\n\n```bash\naivo stats -s openrouter\n```\n\n#### `--refresh, -r`\n\nBypass cache and re-read all data files:\n\n```bash\naivo stats -r\n```\n\n#### `--all, -a`\n\nShow all models (default: top 20, rest grouped as \"others\"):\n\n```bash\naivo stats -a\n```\n\n#### `--top-sessions`\n\nShow the heaviest native session files:\n\n```bash\naivo stats --top-sessions\n```\n\n#### `--since \u003cDURATION\u003e`\n\nFilter to a recent time window. Accepts `Nm`, `Nh`, `Nd`, `Nw`:\n\n```bash\naivo stats --since 7d\naivo stats claude --since 24h\naivo stats --since 2w\n```\n\n#### `--json`\n\nOutput stats as JSON (all models, exact numbers):\n\n```bash\naivo stats --json | jq '.totals.tokens'\n```\n\n## context\n\nShow recent cross-CLI activity for the current project. Sessions are derived on demand from each tool's native storage (Claude, Codex, Gemini, Pi, OpenCode) — aivo keeps no duplicate state.\n\n```bash\naivo context\n```\n\nPair with `aivo run \u003ctool\u003e --context` to inject one of these sessions into your next launch.\n\n#### `--all, -a`\n\nShow all sessions, bypassing the default 14-day age cap:\n\n```bash\naivo context --all\n```\n\n#### `--last-days \u003cN\u003e`\n\nOverride the default age cap:\n\n```bash\naivo context --last-days 30\n```\n\n#### `--json`\n\nDump every available thread as JSON:\n\n```bash\naivo context --json | jq '.threads'\n```\n\n## update\n\nUpdate to the latest version. Delegates to Homebrew or npm when installed by those package managers.\n\n```bash\naivo update\n```\n\n#### `--force`\n\nForce update even if installed via a package manager:\n\n```bash\naivo update --force\n```\n\n#### `--rollback`\n\nRestore the previous version from the last update backup:\n\n```bash\naivo update --rollback\n```\n\n## Development\n\n```bash\nmake build\nmake build-debug\nmake check\nmake test\nmake clippy\nmake build-release\n```\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuanchuan%2Faivo","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyuanchuan%2Faivo","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyuanchuan%2Faivo/lists"}