Set up
Runs on your computer. Pick your agent and operating system.
Before you start
- uv (`curl -LsSf https://astral.sh/uv/install.sh | sh`)
{
"mcpServers": {
"codewright": {
"command": "uvx",
"args": [
"codewright"
]
}
}
}same format Cursor, GitHub Copilot CLI, Junie, JetBrains AI Assistant, Augment (Auggie CLI), Factory Droid, Kiro, Devin CLI +12
Values in angle brackets are placeholders. Restart Claude Desktop after editing its config.Claude Desktop docs
README
synced Oct 26, 2026Codewright
A powerful and concise coding agent for the command line, written in Python.
Codewright : a streaming LLM loop, a polymorphic tool runtime, multi-agent orchestration, session persistence, MCP tool servers, and an interactive TUI.
Features
- Interactive TUI with streaming output, a status bar, and modal approvals.
- Non-interactive mode for one-shot prompts and scripting.
- Semantic file tools (
read_file,list_dir,find_files,search_text) plus a statefulshelltool family (bash-anchored, with background jobs and output paging) and transactionalapply_patchedits. - Task planning: the agent maintains a live, step-by-step plan
(
update_plan) that streams to the TUI so you can watch progress. - Permission profiles that gate destructive shell commands and out-of-workspace access.
- Multi-agent: spawn child agents that each run in their own isolated
session under a built-in role —
explorer(read-only investigation),worker(scoped execution), ordefault— and report back to the parent. The primary agent's role is set by[agent] default_role/CODEWRIGHT_DEFAULT_ROLE. - Project instructions: an
AGENTS.md(or.agents.md) found in the workspace — searched from the working directory up to the workspace root — is injected into every turn as guidance for the agent. - Skills: project-scoped instructions and workflows under
<workspace>/skills/(agentskills.io format). Author them by hand, and/or let the agent auto-distill reusable, test-verified knowledge into new skills; it pulls the relevant ones back in on later tasks via theskilltool. - MCP tool servers over stdio and streamable-http.
- Automatic context compaction: as history approaches the model's context window it is summarized down in place, so long sessions keep running.
- Session persistence + resume via append-only JSONL rollouts.
- Pluggable providers: OpenAI Chat Completions or Responses API, and any OpenAI-compatible endpoint (DeepSeek, Qwen/DashScope, Ollama, local gateways).
Requirements
- Python 3.12 (
>=3.12,<3.13) uv- An API key for an LLM provider (see Configuration)
Installation
As a global command (recommended)
Install Codewright as a standalone tool so codewright is available in any directory:
uv tool install --editable . # run once from the repo root
uv tool update-shell # if the uv tools bin dir is not on your PATH (then reopen the terminal)
--editable installs from source, so later code changes take effect without
reinstalling. Omit it for a pinned snapshot (re-run with --reinstall to update).
pipx install --editable . works too.
From source (development)
uv sync # install deps incl. the dev group
uv run codewright --help # run without a global install (inside the repo)
Quick start
# Interactive TUI in the current directory (bare command == `codewright tui`):
codewright
# Interactive TUI in a specific workspace:
codewright --workspace path/to/project
# One non-interactive turn, prints the final message:
codewright run "explain what this project does" --workspace .
# List and resume saved sessions:
codewright list-sessions
codewright resume <session_id> # reopen in the TUI
codewright resume <session_id> --message "now add tests" # one turn, then exit
Configuration
Settings are read from ~/.codewright/config.toml. Effective-value precedence
(highest wins): CLI flags > environment variables > config file > built-in defaults.
A model API key is the only thing you must supply — everything else has a default. Provide a key via any one of:
| Source | How |
|---|---|
OPENAI_API_KEY | export it in your shell (simplest) |
CODEWRIGHT_API_KEY | export it in your shell |
[llm] api_key_env | name of an env var holding the key (keeps the secret out of the file) |
[llm] api_key | the key inline (discouraged; plaintext) |
A minimal ~/.codewright/config.toml:
[llm]
model = "gpt-4o"
api_key_env = "OPENAI_API_KEY"
# base_url = "https://api.deepseek.com/v1" # for OpenAI-compatible providers
See examples/config.example.toml for every
option (model/provider, context window, permission profile, shell path, skills
test runners, and MCP servers) with its default and explanation.
Useful environment overrides: CODEWRIGHT_MODEL, CODEWRIGHT_API_KEY,
CODEWRIGHT_API_KEY_ENV, CODEWRIGHT_BASE_URL (or OPENAI_BASE_URL),
CODEWRIGHT_PERMISSION_PROFILE, CODEWRIGHT_DEFAULT_ROLE, CODEWRIGHT_SHELL_PATH,
CODEWRIGHT_MAX_CONTEXT_TOKENS, CODEWRIGHT_COMPACT_THRESHOLD.
Commands
| Command | Description |
|---|---|
codewright | Launch the interactive TUI in the current directory (alias for tui). |
codewright tui | Launch the interactive TUI. |
codewright run <prompt> | Run a single non-interactive turn and print the final message. |
codewright resume <session_id> | Resume a saved session (TUI, or --message for one turn). |
codewright list-sessions | List saved sessions in the workspace. |
Common flags: --workspace <dir> (default: current dir), --model,
--provider-base-url, --api-style {chat_completions,responses},
--permission-profile {read_only,workspace_write,dangerous}. run also accepts
--max-context-tokens, --print-session-id, and --no-persist. Run
codewright <command> --help for the full list.
TUI keys
| Key | Action |
|---|---|
Ctrl-C | Interrupt the current turn |
Ctrl-D | Quit |
PageUp / PageDown | Scroll history |
Ctrl-Home / Ctrl-End | Jump to top / bottom |
F1 or ? | Toggle status details |
y / s / n / a | On an approval prompt: approve / approve for session / deny / abort |
Permissions
The active permission profile decides which shell commands run without asking:
read_only— no shell exec at all; only the read/search file tools.workspace_write(default) — exec is auto-allowed inside the workspace; destructive commands (rm -rf,git reset --hard, network access, …) and any cwd outside the workspace still prompt for approval.dangerous— nothing is auto-allowed; every exec prompts.
The workspace root is a hard boundary: reads and writes outside it require approval.
Sessions
Each session is recorded as an append-only JSONL rollout under
<workspace>/.codewright/sessions/<session_id>.jsonl. run persists by default
(disable with --no-persist); the TUI always persists. Use list-sessions and
resume to pick up where you left off.
Architecture
The engine sits behind two asyncio.Queues: front ends submit Op instances
and consume Event instances, and never touch Session internals. A single
submission_loop drives run_turn, which streams the model, dispatches tool
calls through the executor, compacts history, and emits events.
Development
uv run pytest # full test suite
uv run pytest tests/test_run_turn.py # a single file
uv run ruff check src tests # lint
uv run ruff check --fix src tests # lint + autofix
uv run lint-imports # enforce the layering contracts (.importlinter)