* fix(cli): window the OpenTUI transcript so a long resume cannot blank the screen @opentui allocates one native TextBuffer per mounted text element, and the OpenTUI transcript mounted every history item at once. Resuming a session of a few thousand records exhausted the process, and the resulting throw was silent: it lands inside a React host-instance creation, @opentui/react's own boundary catches it, its red-text fallback calls a jsxDEV the bundle does not provide and throws too, and React unmounts the whole root, leaving an empty alternate screen with a live process still accepting input. Mount only the items near the viewport, budgeted in rows rather than items, with spacers standing in for the rest so the scroll geometry still spans the whole session. Estimates mirror the values the ink transcript already uses, real heights are measured per item id and survive unmount, and the scroll position is sampled on the renderer's frame event so an idle terminal costs nothing. Also wrap each mounted item in an error boundary whose fallback renders nothing. A failed item now costs one row instead of the whole UI, and the error reaches the OPEN_TUI_TRANSCRIPT debug log. The session picker's preview pane is clipped and does not scroll, so the view takes an initial anchor and the preview passes 'top'. * fix(cli): stop the transcript window moving the reading position Three defects in the windowing's scroll handling: The height table was cleared on a width change, which renumbered every row offset underneath a scroll position that is itself counted in rows, so a resize moved the visible turn by more than a hundred. The entries a resize actually invalidates are the mounted ones, and the next frame re-measures those. A height correction was written back through the sticky-aware scrollTop setter. No correction is owed: an item the measuring loop can see is already painted at the height just read from it, and both spacers derive from offsets a change inside the window leaves alone. Writing one moved the reading position and, at the tail, took the shell's bottom pin off for the rest of the session. The position was sampled only on the renderer's frame event, which fires after the paint, so an absolute jump — a scrollbar track click or a thumb drag, which can land anywhere in the transcript — painted one spacer-only gap first. The scroll bar emits a public change event synchronously before that paint; subscribing to it covers every scroll path. Also: the host-less session preview now follows the height prop across a resize instead of seeding its viewport rows once at mount; the item failure log carries the component stack and the error stack, matching ink; the two windowing options no caller ever set are gone, so the cap and the overscan are pinned by the tests that exercise them; and the cap's binding condition is stated correctly in the code and in both design docs. Adds a scroll-host harness so the frame-driven half is reachable from jsdom at all, and five tests over it, each mutation-proved against the defect it pins. * docs(cli): record the two windowing follow-ups the review named The bundle-level jsxDEV escalation Decision 8 compensates for at the item is still live for every other subtree, and a window-only move re-executes every mounted item's render path. Both are named in the design rather than left to be rediscovered. * fix(cli): measure transcript items by identity and settle pulled-in rows Each mounted item now registers its own node under `(kind, id)` instead of being recovered from its position among the transcript root's children, so the tool and task cards one subagent call mints no longer overwrite a single height slot, and the item key no longer collides as a React key either. The rows recorded are Yoga's computed height rather than the reported one, which is clamped to a row and would permanently charge a row to an item that paints nothing. An upward window move pulls in items whose spacer rows were charged at the estimate, so the frame that first measures them now subtracts what they turned out to cost from the scroll position — guarded to fire only strictly above the tail, where the reader's own scrolling has already released the shell's bottom pin. Measuring an item that was already mounted still owes nothing. Measuring also runs when no scroll host is found, so the session picker's preview records real heights too. * docs(cli): state the measured mutant victims in the windowing design doc * fix(cli): settle a transcript row whose recorded height went stale off-window The settlement for a row the window pulls in above the viewport only fired for an identity the height table had never seen. A row measured earlier, evicted, and then re-measured at a different height moved the offsets under a scroll position nothing re-anchored, so the page lurched on every wheel tick after a terminal resize or ctrl+O. Settle on the charge rather than on first-ever measurement, spend the charge on the measurement that answers it, and never charge an identity the previous commit already had mounted — which is what a `task-end` splice above the window would otherwise do, since it shifts the index space the charging loop walks while the identities on screen stay put. * docs(cli): keep the windowing design doc true about the stale-height settlement Decision 5 said the frame that *first* measures a pulled-in item settles it, and that the charge is always the estimate; the settlement now spends a charge on the measurement that answers it and never charges an already-mounted identity. The mutation ledger named ten tests on the scroll-host harness and a suite total that both moved. --------- Co-authored-by: Shaojin Wen <[email protected]>
The open-source AI coding agent for your terminal, editor, desktop, browser, and chat.
中文 | Deutsch | français | 日本語 | Русский | Português (Brasil) | 한국어
Why Qwen Code?
- Agentic out of the box — Auto-Memory, Auto-Skills, SubAgents, Agent Teams, and MCP. Dynamic workflows, zero setup.
- Open-source, inside and out — The framework and the Qwen models are open-source. They evolve together. No vendor lock-in.
- Multi-protocol — Supports OpenAI, Anthropic, Gemini, and Qwen APIs. Any third-party provider or local model (Ollama / vLLM). Switch at runtime.
- Beyond the terminal — IDE plugins, Desktop app, Web UI, SDKs, and chat integrations (Telegram / DingTalk / WeChat / Feishu).
Tip
Qwen Code is actively iterating on itself — using its own agent and models to file issues, submit PRs, review code, and run tests. Powered by the community, driven by AI.
Installation
Linux / macOS:
curl -fsSL https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install-qwen-standalone.sh | bash
Windows:
irm https://qwen-code-assets.oss-cn-hangzhou.aliyuncs.com/installation/install-qwen-standalone.ps1 | iex
Restart your terminal after installation to ensure environment variables take effect.
NPM / Homebrew
NPM (requires Node.js 22+):
npm install -g @qwen-code/qwen-code@latest
Homebrew (macOS / Linux):
brew install qwen-code
Quick Start
Open a terminal in your project and start Qwen Code:
cd /path/to/your-project
qwen
Inside the session, run /auth to configure your provider and API key. Then try:
Explain this repository and show me where to start.
See the Authentication Guide and Settings Reference for detailed setup.
How to Use Qwen Code
Choose the interface that fits your workflow:
| Interface | Get started |
|---|---|
| Terminal | Run qwen in your project — see Quick Start. |
| Desktop | Download Qwen Code Desktop for macOS, Windows, and Linux. |
| Web | Run qwen serve --open to open the Web UI in your browser. (experimental) |
| Editor | Set up VS Code, Zed, or JetBrains. |
| Chat | Connect Telegram, DingTalk, WeChat, or Feishu, then run qwen channel start. |
For automation and custom integrations:
- Headless — Run
qwen -p "..."in scripts, CI/CD, or batch jobs. - SDKs — Build with TypeScript, Python, or Java.
- Daemon — Run
qwen serveto connect clients over HTTP + SSE (ACP). (experimental) Daemon guide.
SDK example (Python)
import asyncio
from qwen_code_sdk import is_sdk_result_message, query
async def main() -> None:
result = query(
"Summarize the repository layout.",
{
"cwd": "/path/to/project",
"path_to_qwen_executable": "qwen",
},
)
async for message in result:
if is_sdk_result_message(message):
print(message["result"])
asyncio.run(main())
Capabilities
If you know Claude Code, you already know Qwen Code — and then some. We've put significant effort into bringing Qwen Code to feature parity with Claude Code, improving both breadth and reliability across the board.
| Feature | Qwen Code | Claude Code |
|---|---|---|
| SubAgents, Agent Teams, Dynamic Workflows | ✓ | ✓ |
| Auto-Memory, Auto-Skills, Hooks | ✓ | ✓ |
| Built-in Skills (/review, /batch, /loop, /bugfix…) | ✓ | ✓ |
| MCP, Plan Mode, LSP Integration | ✓ | ✓ |
| Auto Mode, Sandbox, Git Worktrees | ✓ | ✓ |
| Computer Use (desktop automation) | ✓ | ✓ |
| IDE Plugins (VS Code / JetBrains / Zed) | ✓ | ✓ |
| SDK | ✓ | ✓ |
| Headless Mode, Session Management | ✓ | ✓ |
| Open-source — model and framework | ✓ | — |
| Multi-protocol (OpenAI / Anthropic / Gemini / Qwen + any provider) | ✓ | — |
| Agent Arena (multi-model head-to-head on same task) | ✓ | — |
Daemon Mode — qwen serve (multi-client shared agent) |
✓ | — |
| IM Channels (Telegram / DingTalk / WeChat / Feishu) | ✓ | — |
Qwen Code Evaluation
Evaluation Configuration
| Configuration | Value |
|---|---|
| Dataset | princeton-nlp/SWE-bench_Verified, 500 cases |
| Runs | 3 trials per version, 1,500 jobs per version; 7 Qwen Code versions |
| Model | Qwen 3.7 Max |
| Sampling | temperature=1, top_p=0.95 |
| Thinking / Reasoning | interleaved_thinking=true, thinking_type=adaptive, reasoning_effort=high |
| Context / Output Limits | context_1m=true, model_context_length=1,000,000, max_tokens=64,000, model_max_tokens=65,535 |
| Harness Limits | max_iterations=500, runtime_timeout_sec=7,200, agent_timeout_multiplier=3.0 |
Scores by Qwen Code Version
| Version | Avg Score | Pass Rate | pass@3 | pass^3 |
|---|---|---|---|---|
| 0.0.14 | 77.80% | 84.6% | 84.6% | 69.2% |
| 0.1.0 | 76.73% | 84.6% | 84.6% | 68.0% |
| 0.5.0 | 76.60% | 83.0% | 83.0% | 68.4% |
| 0.10.0 | 76.47% | 84.4% | 84.4% | 67.4% |
| 0.15.0 | 77.67% | 84.6% | 84.6% | 68.6% |
| 0.19.0 | 76.40% | 85.0% | 85.0% | 65.8% |
| 0.22.0 | 77.33% | 84.4% | 84.4% | 68.0% |
Avg Score Trend
Ecosystem
-
Qwen Code Desktop — Official desktop app for macOS, Windows, and Linux
-
AionUi — A modern GUI for command-line AI tools including Qwen Code
-
Gemini CLI Desktop — A cross-platform desktop/web/mobile UI for Qwen Code
-
🦞 Qwen Code Claw — Let other agents (Claude, Codex, etc.) delegate coding tasks to Qwen Code via ACP. Paste this prompt into your agent:
Use Qwen Code as a coding agent. First, fetch and read this skill reference:
https://raw.githubusercontent.com/QwenLM/qwen-code/refs/heads/main/.qwen/skills/qwen-code-claw/SKILL.md
Then follow the instructions inside to install, authenticate, and use Qwen Code via acpx for all coding tasks.
- Aliyun Model Studio CLI — Official CLI for Aliyun's AI platform (
bailian-cli). Extends Qwen Code with image/video generation, knowledge retrieval, app orchestration, and model deployment
Privacy
See the Terms of Service and Privacy Notice, including Chrome extension and Browser Use data handling.
Contributing
Contributions are welcome! See CONTRIBUTING.md for guidelines.
Acknowledgments
This project was originally based on Google Gemini CLI v0.8.2. We gratefully acknowledge the Gemini CLI team's excellent work. Starting from Qwen Code v0.1, we stopped syncing with upstream and began independent development as a multi-protocol, multi-platform agent framework with deep integrations for Qwen models and beyond.

