* feat(review): statement-level mutation probes in test-efficacy
The revert probe is all-or-nothing: it reverts whole production files, so a
suite that gates six of a diff's behaviours goes red and the probe says
"gated" — even when the seventh behaviour, a one-line safety statement, has no
test at all. Dogfooded on a live PR: deleting a single `reminders.clear()`
inside the not-continued branch left the full 471-test suite green, and that
line carried the PR's headline safety property (an abandoned task's todos must
not bleed into an unrelated new prompt). A human reviewer found it with a
hand-rolled mutation probe; the command could not.
Add the probe kind the human ran, deterministically. Candidates are added
lines from the committed head (never the dirty worktree) whose trimmed
statement calls a safety verb — .clear(), .delete(), .reset(), .abort(),
.removeListener(), .unref() — or reassigns state to empty ([] / new
Map()/Set()), and that are removable as a whole: single complete expression
statements, brace-balanced via a string/comment-aware scanner, previous
significant line ending ;, { or } (which rejects fluent tails, continuations,
and the brace-less-if silent-rebind trap), outside template literals and block
comments. Selection is conservative by design: a false negative costs
nothing, a false positive burns a suite run.
Each mutant (capped at 8, files with collocated new tests first) deletes its
one line in the existing probe worktree and re-runs the affected suites
through the existing vitest-json classifier: red = killed (the line is
guarded), green = SURVIVED — the invariant it enforces ships unprotected —
filed as a finding in the unreachable/inert register so the Agent-7 pipeline
picks it up without any skill change. Compile/load failure = inconclusive,
never a finding. Mutants run only after a cleanly green baseline, inside the
command's existing deadline budget (each run must leave room for the revert
probe); candidates that no longer fit are counted, not silently dropped.
* fix(cli): harden test-efficacy mutant selection text checks (#8020)
Mutant selection ran its end-anchored checks on raw trimmed lines, so a
trailing comment hid a statement's real end (dropping genuine candidates
like `reminders.clear(); // why`) and a safety verb inside a string faked
one (a wasted suite run plus a misleading survivor). Route the
`SAFETY_VERB_RE`, `endsWith(';')`, and predecessor `/[;{}]$/` checks
through a shared `codeOnly()` that strips comments and blanks literal
contents first.
Also guard the template-state escape skip against a backslash-continued
line, mirroring the single/double-quote branch: swallowing that newline
dropped a per-line literal flag and shifted every later line's verdict.
Adds unit coverage for all three selection fixes and an integration test
for the baseline-not-green skip branch.
* fix(cli): gitignore fake vitest in test-efficacy integration fixture (#8020)
The fake vitest bin was committed by `git add -A` and checked out into
the probe worktree as the stale passing copy, so installFailingVitest's
overwrite in the main worktree was never seen by npx in the probe tree.
The baseline read green and the baseline-not-green skip test failed.
* fix(review): make mutation-probe reporting precise (#8020)
Address review feedback on the test-efficacy mutation probe:
- Count candidates the MAX_MUTANTS cap drops in `skippedForCap` instead of
silently losing them, so a capped `survived: 0` cannot read as "every
safety statement is covered" (mirrors the existing `skippedForBudget`).
- Gate the mutant phase per probe file: run each mutant against the files
that are green in the unmutated baseline, so one unrelated quarantined
(all-skip) suite — `inconclusive`, not red — no longer disables the whole
probe.
- Scope the `mutant-survived` finding to the diff's own tests ("confirm an
existing test covers it, or add one") rather than asserting the invariant
ships unprotected, which an untouched pre-existing test may still cover.
* test(review): cover the budget-skip path in mutation-probe integration tests (#8020)
* fix(review): harden mutation-probe selection and diff parsing (#8020)
* fix(review): handle multi-line class headers in mutation-probe selection (#8020)
* fix(review): stop class-body walk at braces before matching class keyword (#8020)
* fix(review): whole-file literal scan for mutant selection; pin the untested guard paths
The per-line scanner pair (codeOnly + lineStartsInsideLiteral) shared a blind
spot: a backtick inside a `${…}` interpolation read as the outer template's
closing backtick. That flipped the literal state for every following line and,
in the single-line skip, exposed nested-template content as code — so a safety
verb inside a string could be selected as a mutant (a false-finding vector) and
a class field below a brace-bearing template could slip the class-body
rejection. Replace the pair with one whole-file pass that tracks interpolation
brace depth: per-line code text with comments stripped and literal contents
blanked, plus the same `${}`-aware skip for delimiter scanning. Differential
audit over every core+cli source file: zero selection differences on real code;
the pathological shapes are pinned by three new tests.
Also pin the remaining untested paths from review: the selection-failure catch
(discloses and still runs the revert probe), the runOneMutant line-mismatch
guard (now exported; inconclusive, file untouched), and the budget-skip stdout
disclosure.
* fix(review): clamp probe deadlines to the whole-command budget (#8020)
* fix(review): harden mutant selection guards and disclosure accounting (#8020)
* fix(review): close silent-zero paths in mutant disclosure and harden diff parsing (#8020)
* fix(review): drop interpolation quote-skip that mis-parsed regex literals (#8020)
* fix(review): track template nesting with a stack; disclose derailed files; harden and pin the remaining probe paths
The nested-template fix that landed as a counter cannot represent a nested
template INSIDE a nested interpolation: at two levels the deep template's text
`}` is charged against the wrong frame, the scan desyncs, and the file either
admits template text as a mutant or derail-drops its real candidates. Replace
the counter with a stack — one frame per open template, `}` closes only the
top interpolation, a backtick closes only the innermost template — and derive
the end state from the stack. The two-level trigger is pinned by a test
written red-first against the counter.
Derailed files are now disclosed, not silently dropped: selectMutants returns
them, and the note composer stacks the derail note with the red-baseline note
instead of clobbering. The hostile-git-config path gets its missing test (repo
diff.srcPrefix/dstPrefix, diff.external, core.quotePath with a non-ASCII
path — fails with the pinned flags removed). The budget test drops its
Date.now call-count coupling for an injected clock threaded through
runTestEfficacy/runProbeSuite. The mutation-phase catch gets an end-to-end
test (ENOBUFS mid-phase → all candidates inconclusive, revert probe still
runs, report still written).
---------
Co-authored-by: verify <verify@local>
Co-authored-by: qwen-code-dev-bot <qwen-code-dev@service.alibaba.com>
Co-authored-by: Qwen Code Bot <qwen-code-bot@users.noreply.github.com>
Co-authored-by: Qwen Code <qwen-code@users.noreply.github.com>
Co-authored-by: Qwen Code Autofix <qwen-code-autofix@users.noreply.github.com>
|
||
|---|---|---|
| .github | ||
| .husky | ||
| .qwen | ||
| .vscode | ||
| docs | ||
| docs-site | ||
| eslint-rules | ||
| integration-tests | ||
| integrations/external-context | ||
| packages | ||
| patches | ||
| scripts | ||
| .dockerignore | ||
| .editorconfig | ||
| .gitattributes | ||
| .gitignore | ||
| .npmrc | ||
| .nvmrc | ||
| .prettierignore | ||
| .prettierrc.json | ||
| .yamllint.yml | ||
| AGENTS.md | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| CONTRIBUTING.md | ||
| Dockerfile | ||
| esbuild.config.js | ||
| eslint.config.js | ||
| eslint.legacy-filenames.mjs | ||
| LICENSE | ||
| Makefile | ||
| package-lock.json | ||
| package.json | ||
| README.md | ||
| SECURITY.md | ||
| tsconfig.json | ||
| vitest.config.ts | ||
The open-source AI coding agent that lives in your terminal.
中文 | 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, daemon mode, SDKs, and IM bots (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
qwen # Launch interactive terminal UI
# Inside the session:
/auth # Configure your provider and API key
See the Authentication Guide and Settings Reference for detailed setup.
How to Use Qwen Code
| Mode | Command | Use Case |
|---|---|---|
| Interactive | qwen |
Terminal UI with rich rendering, @file references, slash commands |
| Headless | qwen -p "..." |
Scripts, CI/CD, batch processing — no UI |
| IDE | — | VS Code, Zed, JetBrains |
| Desktop | — | Qwen Code Desktop — GUI for macOS, Windows, Linux |
| Daemon | qwen serve |
Shared agent session over HTTP+SSE (ACP). Multiple clients, one agent. (experimental) Docs |
| SDK | — | TypeScript, Python, Java |
| IM Bot | qwen channel |
Connect to Telegram, DingTalk, WeChat, or Feishu |
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) | ✓ | — |
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.
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.
