{"id":50974391,"url":"https://github.com/coder11125/io","last_synced_at":"2026-06-19T06:02:26.997Z","repository":{"id":363814873,"uuid":"1264071332","full_name":"coder11125/io","owner":"coder11125","description":"io – AI coding agent for the terminal. Built in Rust","archived":false,"fork":false,"pushed_at":"2026-06-18T14:32:52.000Z","size":2446,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-18T15:29:20.699Z","etag":null,"topics":["anthropic","gemini","groq","mistral","openai","rust","serde","tokio"],"latest_commit_sha":null,"homepage":"","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/coder11125.png","metadata":{"files":{"readme":"README.md","changelog":null,"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-06-09T14:31:18.000Z","updated_at":"2026-06-18T14:34:42.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/coder11125/io","commit_stats":null,"previous_names":["coder11125/io"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/coder11125/io","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coder11125%2Fio","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coder11125%2Fio/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coder11125%2Fio/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coder11125%2Fio/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/coder11125","download_url":"https://codeload.github.com/coder11125/io/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/coder11125%2Fio/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34519052,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-19T02:00:06.005Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["anthropic","gemini","groq","mistral","openai","rust","serde","tokio"],"created_at":"2026-06-19T06:02:25.833Z","updated_at":"2026-06-19T06:02:26.991Z","avatar_url":"https://github.com/coder11125.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1 align=\"center\"\u003eio\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cstrong\u003eAI coding agent for the terminal\u003c/strong\u003e\u003cbr\u003e\n  \u003cem\u003eBuilt in Rust — powered by 13 LLM providers\u003c/em\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"assets/io.png\" width=\"600\" alt=\"io terminal agent\" /\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ccode\u003eio\u003c/code\u003e is an AI coding assistant that runs directly in your terminal.\n  It reads, writes, edits, and understands code — with support for \u003cstrong\u003e13 LLM providers\u003c/strong\u003e,\n  interactive sessions, tool execution, and permission sandboxing.\n\u003c/p\u003e\n\n---\n\n## Features\n\n- **Multi-provider** — 13 LLM providers supported (Anthropic, OpenAI, Gemini, Groq, DeepSeek, Mistral, Ollama, Azure, Bedrock, OpenRouter, xAI, OpenCode Go, OpenCode Zen)\n- **7 built-in tools** — `read`, `write`, `edit`, `bash`, `glob`, `grep`, `spawn_agent` for full codebase interaction\n- **Cost tracking** — Built-in API cost calculation with `/cost` command for supported providers\n- **Interactive \u0026 single-shot modes** — Full-screen REPL with splash screen, prompt bar, and scrollback\n- **Color themes** — 12 built-in themes (dark/light) with live `/theme` switcher\n- **Permission sandbox** — Allow/deny/prompt modes with granular bash command control and security-hardened command validation\n- **Session persistence** — SQLite-backed conversation history, resume anytime\n- **Streaming responses** — Real-time token-by-token streaming with live indicator\n- **Fast \u0026 lightweight** — Built in Rust, minimal dependencies, no Node.js or Python required\n- **Provider switching** — Change providers on the fly with `/connect` and `/model`\n- **Project-level config** — Per-project `.io/config.toml` initialization with `io init`\n- **Interactive picker** — Arrow-key menus for agents, providers, models, and themes\n- **Agent cycling** — Tab key at empty prompt to swap agents mid-session\n- **@file mentions** — Type `@path/to/file` to inline file or directory contents\n- **Project context** — Reads `AGENTS.md` / `CLAUDE.md` from the project root and injects them as context so agents understand your conventions automatically\n- **Smart write permissions** — Most agents (build, debug, docs, refactor, …) auto-approve `write`/`edit` calls; plan, git, review, security, and test always prompt\n\n## Quick Start\n\n```bash\n# Install\ncargo install --path .\n\n# Start interactive mode\nio\n\n# Or run a single command\nio \"explain this codebase\"\n```\n\nOn first run, `io` creates a default configuration at `~/.io/config.toml`.\nUse `/connect` inside the REPL to set up your preferred LLM provider.\n\n## Security\n\nThe permission sandbox system provides defense-in-depth protection against command injection and unauthorized execution:\n\n**Permission Modes**:\n- `allow` — Auto-approve all tool executions\n- `deny` — Block all tool executions\n- `prompt` — Ask user for approval (default)\n\n**Security Features**:\n- **Semantic command analyzer**: Classifies every bash command as `Safe`, `Caution`, or `Destructive` before execution — `ls`, `git status`, `cargo check` are auto-allowed; `rm -rf`, `dd`, `git reset --hard` always prompt\n- **Granular bash approvals**: \"Always\" approvals are command-specific (approving `ls -la` won't approve `rm -rf`)\n- **Command normalization**: Handles path obfuscation (`/bin/rm` → `rm`, `r\\m` → `rm`)\n- **Injection prevention**: Detects command substitution (`$(rm)`, `` `rm` ``), chaining (`;`, `\u0026`, `|`), and subshells\n- **Conservative denylist**: Any dangerous token denies the entire command\n- **Strict allowlist**: Requires all pipeline heads to be explicitly allowed\n- **Expansion guard**: Commands containing `$`, backtick, or `(` bypass auto-allow (static analysis can't classify them safely)\n\n**Command Safety Classifications**:\n| Level | Examples | Behavior |\n|---|---|---|\n| `Safe` | `ls`, `cat`, `grep`, `git status`, `cargo check`, `find` (no `-delete`) | Auto-allowed in prompt mode |\n| `Caution` | `mv`, `git commit`, `rm file.txt`, `sed -i`, `chmod` | Always prompts |\n| `Destructive` | `rm -rf`, `dd`, `git reset --hard`, `git push --force`, `mkfs.*` | Always prompts with implied risk |\n\n**Ecosystem-agnostic build tool classification** — subcommands are classified consistently across all package managers:\n\n| Subcommand | Ecosystems | Level |\n|---|---|---|\n| `test`, `build`, `check`, `lint`, `fmt`, `doc`, `bench`, `audit` | npm/yarn/pnpm/bun, cargo, go, pip, mvn/gradle, dotnet, … | `Safe` — auto-allowed |\n| `list`, `show`, `freeze`, `outdated`, `tree`, `info` | pip, npm, cargo, go mod | `Safe` — auto-allowed |\n| `install`, `add`, `update`, `upgrade`, `remove` | all | `Caution` — prompts |\n| `publish`, `deploy`, `release` | npm, cargo, mvn | `Caution` — prompts |\n| `run \u003cscript\u003e` | npm/yarn/pnpm/bun | Safe or Caution based on script name |\n| `go mod download/verify/graph/why` | go | `Safe` — read-only module ops |\n| `go mod tidy/edit` | go | `Caution` — rewrites go.sum |\n\n`make`/`cmake`/`ninja` targets are always `Caution` — Makefile rules are opaque to static analysis.\n\n**Defended Attack Vectors**:\n- Path obfuscation, command substitution, environment injection\n- Command chaining with `;`, `\u0026`, `|`, `\u0026\u0026`, `||`\n- Subshells, brace groups, HEREDOC, process substitution\n\n## Modes\n\n### Interactive REPL\n\n```bash\nio\n```\n\nLaunches an interactive session with a streaming agent loop. Commands:\n\n| Command | Description |\n|---|---|---|\n| `/help` | Show available commands |\n| `/new` | Start a new session |\n| `/agent` | Switch agent mode (build, plan, debug, refactor) |\n| `/connect` | Set up a provider interactively (with live model fetching) |\n| `/model` | Switch between configured providers |\n| `/theme` | Switch UI color theme (12 themes) |\n| `/cost` | Show API cost summary for the current session |\n| `/compact` | Summarize and compress conversation history |\n| `/exit`, `/quit`, `/q` | Exit the session |\n| `!\u003ccmd\u003e` | Run a shell command directly |\n\nTab key at the empty prompt cycles through available full agents.\nType `@path/to/file` to expand file or directory contents inline.\n\nThe TUI features a splash screen with centered logo and command reference,\na fixed prompt bar at the bottom showing agent/model/provider and context usage,\nmouse scrollback through session history, and streaming tool call visualization\nwith syntax-colored diffs. Long splash input is automatically truncated with `…`\nso it never overflows the input box border. Thought blocks are rendered in the\nactive theme's accent and muted colors.\n\n### Single-shot\n\n```bash\nio \"summarize the changes in src/\"\n```\n\nRuns one turn and prints the response, then exits.\n\n### Flags\n\n```bash\nio --new              # Start a fresh session (ignore history)\nio --continue         # Resume the last session\nio --model anthropic  # Override the default provider\n```\n\n## Supported Providers\n\n| Provider | Config key | Default Model |\n|---|---|---|\n| **Anthropic** | `anthropic` | `claude-sonnet-4-20250514` |\n| **OpenAI** | `openai` | `gpt-4o` |\n| **Google Gemini** | `gemini` | `gemini-2.5-pro` |\n| **Groq** | `groq` | `llama-3.3-70b-versatile` |\n| **Ollama** | `ollama` | `llama3.2` |\n| **Azure OpenAI** | `azure` | `gpt-4o` |\n| **AWS Bedrock** | `bedrock` | `anthropic.claude-3-5-sonnet-20241022-v2:0` |\n| **Mistral AI** | `mistral` | `mistral-large-latest` |\n| **DeepSeek** | `deepseek` | `deepseek-chat` |\n| **OpenRouter** | `openrouter` | `anthropic/claude-sonnet-4` |\n| **xAI (Grok)** | `xai` | `grok-3-beta` |\n| **OpenCode Go** | `opencode_go` | `deepseek-v3` |\n| **OpenCode Zen** | `opencode_zen` | `opencode/claude-sonnet-4` |\n\n## Configuration\n\nConfiguration is stored in `~/.io/config.toml` (global) and optionally `.io/config.toml` (per-project).\n\n```toml\n[provider]\ndefault = \"anthropic\"\n\n[provider.anthropic]\nmodel = \"claude-sonnet-4-20250514\"\nbase_url = \"https://api.anthropic.com/v1\"\napi_key_env = \"ANTHROPIC_API_KEY\"\n\n[session]\nauto_compact = true\nmemory_enabled = true\nmax_turns = 100\n\n[permissions]\ndefault = \"prompt\"       # \"allow\" | \"deny\" | \"prompt\"\nallowed_commands = []\ndenied_commands = [\"rm\", \"sudo\"]\n\n# Optional: theme = \"ocean\"  (default, ocean, rose, forest, sunset, mono, breeze, ink, dawn, sand, mint, dusk)\n```\n\n### API Keys\n\nKeys are stored in `~/.io/keys.toml` (with `chmod 600` on Unix). You can also use environment variables:\n\n```toml\n# ~/.io/keys.toml\nanthropic = \"sk-ant-...\"\nopenai = \"sk-proj-...\"\n```\n\nOr set `api_key_env` in `config.toml` to reference an environment variable.\n\n### Commands\n\n```bash\n# View current config\nio config show\n\n# Modify config\nio config set provider.default anthropic\nio config set session.auto_compact true\nio config set permissions.default allow\n\n# Initialize io in the current project\nio init\n```\n\n### Session Management\n\n```bash\n# List sessions\nio session list\n\n# Show session details\nio session show \u003cid\u003e\n\n# Delete a session\nio session delete \u003cid\u003e\n```\n\n## Architecture\n\n```\nio/\n├── io/                          # CLI frontend (binary crate)\n│   ├── Cargo.toml\n│   └── src/\n│       ├── main.rs              # Entry point, CLI parsing, subcommand dispatch\n│       ├── tui.rs               # REPL orchestration: agent construction, slash command dispatch\n│       ├── input.rs             # Readline loops (REPL + splash), popup helpers, @file resolution\n│       ├── stream.rs            # Streaming event processing: ThinkParser, blink_and_print\n│       ├── cost.rs              # /cost report\n│       ├── config_cmd.rs        # `io config …` and `io init` handlers\n│       ├── agent.rs             # Agent switching (/agent command)\n│       ├── connect.rs           # Interactive provider setup wizard (13 providers)\n│       └── model.rs             # Provider switching (/model command)\n│\n├── io-tui/                      # Terminal UI components (library crate)\n│   ├── Cargo.toml\n│   └── src/\n│       ├── lib.rs               # Re-exports: picker, readline, render, theme\n│       ├── render.rs            # Terminal rendering: markdown, diffs, splash, prompt bar, scrollback\n│       ├── picker.rs            # Terminal interactive picker (arrow keys, viewport)\n│       ├── readline.rs          # Custom readline with slash commands\n│       └── theme.rs             # Interactive theme picker\n│\n├── io-runtime/                  # Core engine (library crate)\n│   ├── Cargo.toml\n│   ├── tests/\n│   │   └── agent_loop.rs        # 11 integration tests against a scripted mock provider\n│   └── src/\n│       ├── lib.rs               # Crate root — re-exports public API + load_project_context()\n│       ├── agent.rs             # Agent loop: LLM completion + tool execution (sync \u0026 streaming)\n│       ├── compact.rs           # /compact + auto-compact summarization\n│       ├── config.rs            # Config/schema (TOML), KeyStore, provider config structs\n│       ├── types.rs             # Core data types — Session, Turn, ToolCallRecord, TurnUsage\n│       ├── memory.rs            # SQLite-backed session persistence (CRUD)\n│       ├── sandbox.rs           # Permission checker (allow/deny/prompt modes)\n│       ├── command_safety.rs    # Semantic command classifier (Safe/Caution/Destructive)\n│       ├── pricing.rs           # Per-token cost calculation for supported providers\n│       ├── tools/               # Built-in tools (7 tools, each with unit tests)\n│       │   ├── mod.rs           # Tool trait, ToolRegistry, default_registry()\n│       │   ├── read.rs          # Read files with offset/limit\n│       │   ├── write.rs         # Write/create files, returns unified diff\n│       │   ├── edit.rs          # Replace first occurrence of text, returns unified diff\n│       │   ├── bash.rs          # Execute shell commands with timeout \u0026 workdir\n│       │   ├── glob.rs          # Find files by glob pattern (sorted by mtime)\n│       │   ├── grep.rs          # Search file contents with regex\n│       │   └── spawn.rs         # spawn_agent — delegate to a restricted sub-agent\n│       │\n│       └── provider/            # LLM provider implementations\n│           ├── mod.rs           # ProviderKind enum, CompletionModel trait, create_provider()\n│           ├── anthropic.rs     # Anthropic Claude\n│           ├── openai.rs        # OpenAI + 8 compat providers via OpenAICompatProvider\n│           ├── gemini.rs        # Google Gemini\n│           ├── azure.rs         # Azure OpenAI\n│           └── bedrock.rs       # AWS Bedrock\n│\n├── io-agents/                   # Built-in agent definitions (library crate)\n│   └── src/\n│       ├── agent_config.rs      # AgentConfig + ToolAccess + auto_allow_writes\n│       └── builtin/             # build, plan, debug, explore, review, test,\n│                                #   security, docs, git, refactor, general\n│\n├── .github/\n│   └── workflows/\n│       └── ci.yml               # CI: fmt, clippy, build, test on push/PR\n├── assets/\n│   └── io.png                   # Logo\n├── Cargo.toml                   # Workspace root (resolver = \"3\")\n└── README.md\n```\n\n### How It Works\n\n1. **Input** — User types a prompt (interactive or single-shot)\n2. **Project context** — On startup, `load_project_context()` reads `AGENTS.md` / `CLAUDE.md` from the project root and passes the content to the agent; it is injected as a synthetic user/assistant message pair so the model always has project conventions in context\n3. **Agent loop** — The agent iterates up to 20 turns: sends conversation history + system prompt + project context + tool specs to the LLM\n4. **Tool execution** — If the LLM requests a tool call, the agent executes it via `ToolRegistry`, checks permissions via `PermissionChecker`, and feeds results back to the model\n5. **Streaming** — In interactive mode, text deltas stream to the terminal as they arrive; tool starts and completions are rendered inline (with syntax-colored diffs for `write`/`edit`)\n6. **Persistence** — Each turn (with tool call records and token usage) is saved to SQLite for session resumption\n\n### Message Flow\n\n```\nUser Input\n    │\n    ▼\nAgent.run_turn() / run_turn_streaming()\n    │\n    ├── Build Messages (system prompt + history + new input)\n    │\n    ├── CompletionModel.complete() / complete_stream()\n    │       │\n    │       ├── Text blocks → stream to user / accumulate\n    │       └── ToolUse blocks → execute tools\n    │               │\n    │               ├── PermissionChecker.check_tool()\n    │               ├── ToolRegistry.get().execute()\n    │               └── Feed ToolResult back to model\n    │\n    └── Save Turn to SQLite (SessionStore)\n```\n\n## Built-in Tools\n\n| Tool | Description |\n|---|---|\n| **`read`** | Read files with optional `offset` (line number) and `limit` for partial reading |\n| **`write`** | Write or create a file. Returns a unified diff of what changed |\n| **`edit`** | Replace the first occurrence of `old_string` with `new_string` in a file. Returns a unified diff |\n| **`bash`** | Execute shell commands with configurable `timeout` (ms) and `workdir` |\n| **`glob`** | Find files by glob pattern, sorted by modification time (newest first) |\n| **`grep`** | Search file contents with regex, optional file type filtering via `include` glob |\n\nAll tools implement the `Tool` trait with a JSON input schema exposed to the LLM, allowing autonomous discovery and use of parameters.\n\n## Development\n\n```bash\n# Build\ncargo build\n\n# Run in development\ncargo run -- \"your prompt\"\ncargo run --\n\n# Run tests (149 unit tests + 9 integration tests)\ncargo test\n\n# Add a new provider\n# 1. Add a config struct in io-runtime/src/config.rs\n# 2. Create a provider module in io-runtime/src/provider/\n# 3. Add it to ProviderKind enum and create_provider() in provider/mod.rs\n# 4. Add it to PROVIDERS array and match block in connect.rs\n```\n\n### Adding a New Tool\n\n1. Create `io-runtime/src/tools/\u003cname\u003e.rs` implementing the `Tool` trait\n2. Register it in `tools/mod.rs` (add module + register in `default_registry()`)\n3. The LLM will discover it automatically via tool specs\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoder11125%2Fio","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcoder11125%2Fio","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcoder11125%2Fio/lists"}