* feat(triage): add confidence score, sequence diagram, files overview, and review footer to PR comments Enrich the /triage bot's PR comments with four presentation elements, all conditional and kept in the existing human-maintainer voice: - Stage 3 opens with a one-line `Confidence: N/5` score mapped to the approve / defer / request-changes verdict (fork-refactor guardrail caps at 3/5). - Stage 2 may add a light/dark mermaid sequence diagram — only for PRs that introduce or reshape a multi-step runtime flow. - Stage 2 may add a collapsed changed-files overview table — only when many source files are touched. - Every staged comment ends with a footer recording the reviewed commit SHA, so a maintainer can tell on re-run whether new commits landed since. Heavy elements (diagram, table) trigger only on complex PRs; a small, focused PR still gets the plain findings + tmux testing comment. Fetch now captures headRefOid for the footer. * fix(triage): use a single auto-themed sequence diagram, not the light/dark anchor trick The `#gh-light-mode-only` / `#gh-dark-mode-only` fragment only theme-scopes images on GitHub, not anchor-wrapped mermaid — verified on a real comment's body_html, where both `<pre lang="mermaid">` blocks survive with no theme-hiding class, so the two copies render stacked. Switch the skill template to a single plain mermaid block with no theme directive; GitHub auto-themes unthemed mermaid to the reader's own light/dark mode. * docs(triage): warn against ; and em-dash inside mermaid message text A `;` or `—` inside a sequence-diagram message breaks GitHub's mermaid parser (`;` is read as a statement separator), so the diagram fails to render. Tell the skill to keep message text to plain words plus commas and parentheses. * fix(triage): address #6789 review findings on the enrichment additions Review of the triage-enrichment PR flagged 3 Critical plus several Suggestion items on the new skill text; this addresses them: - Escape attacker-controlled fork PR paths before they enter the changed-files table (|, backticks, <>&, @, CR/LF), and pull the list via paginated REST so files past the first 100 are not silently dropped. - Pin the full headRefOid in the reviewed-commit footer (a 7-char prefix is spoofable via force-push) and reuse it from the initial fetch instead of a second gh call; drop the footer when HEAD_SHA is empty rather than emitting empty backticks that overwrite a valid SHA on re-run. - Correct the mermaid punctuation rule: em dashes render fine (the prohibition was false), while `;` breaks the parser and `#` clips the label (both verified against the bundled Mermaid). - Add `files` to the initial fetch; qualify the SHA footer as skipped for terminal-gate reviews; fold Stage-0 escalation into the confidence-cap rule; give Stage 2 a concrete footer template and Chinese-block placement; unify "enrichments" terminology and point SKILL.md at pr-workflow.md as the single source of truth. * fix(triage): address #6789 re-review of the enrichment fixes The first review-fix commit introduced a few inconsistencies the re-review caught; this resolves them: - Drop the undefined `$PR_JSON` reference and the "reuse, do not call twice" framing: capture HEAD_SHA with a fresh per-stage `gh pr view --json headRefOid` so the footer actually reflects the head each stage reviewed (reuse cannot detect a mid-run force-push). - Remove `files` from the initial fetch — the changed-files table uses the paginated REST endpoint, so the fetched `files` was unused. - Replace the prose path-escaping with a deterministic `sanitize_path()` that escapes `&` first (no double-encoding) and renders inside `<code>` (so a backtick in a filename is escapable). - Confidence rubric: 3/5 is "defer (comment)", never `--request-changes`; spell out defer-vs-escalate and how to word a guardrail-capped 3/5. - Unify the signature to underscore italics. * fix(triage): address #6789 round-3 review of the enrichment fixes Round-3 re-review caught a rendering bug I introduced plus three hardening gaps: - Fix a broken code fence: the sanitize_path recipe opened with 4 backticks and "closed" with 3, swallowing the following prose and the files-table template into one giant bash block. - Footer empty-guard now fails closed. Dropping the footer on a re-run PATCHes the whole body and erases the prior valid SHA just like empty backticks would, so keep the existing comment and its footer until a full OID is available. - Extend the mermaid punctuation guard to participant aliases and labels (a `;` there also forges a second actor), and require labels from a safe char set. - Budget the changed-files table (cap ~30 rows, trim cells to 200 chars, append an "and N more" row) so the mandatory Stage 2 post cannot exceed GitHub's comment limit; render example paths with <code> to match the sanitizer. * fix(triage): address #6789 round-4 review of the enrichment fixes - Footer pins the SHA actually inspected (captured once at review start), and before every post and before --approve the workflow re-reads the head and bails on a mismatch — closes the force-push TOCTOU that a post-time capture or a pre-approve gap left open. - Reconcile the footer rules: Stage 2 and Stage 3 now both defer to the fail-closed rule on empty HEAD_SHA instead of "omit the footer" (which would blank a prior valid footer on re-run). - Mermaid participant safety: generate aliases (P1, P2) and keep sanitized names only in `as` labels, since reserved words (loop/end/activate) can't be aliases. - Files table: <code> does not stop GFM from parsing Markdown, so also encode link/emphasis syntax; sanitize the "What changed" column; cap tmux output so the whole Stage 2 comment stays under the size limit. - 3/5 wording: make the defer path unambiguous (not request-changes). * fix(triage): bind approval to reviewed commit and normalize mermaid labels (#6789 P1s) - Approve via the reviews API pinned to $HEAD_SHA (commit_id) instead of `gh pr review --approve`, closing the check-then-act force-push window before approval — a review recorded against the reviewed commit is not counted for a moved head under "require approval of latest push". - Define a deterministic `as`-label normalizer for diagram participants (keep [A-Za-z0-9 _.()-], drop CR/LF and Mermaid control chars, cap length) so a newline in a fork-supplied component name cannot inject a second actor. * fix(triage): use the SHA-pinned approval form in Stage 3 too (#6789 critical) The Approval note switched to the commit_id-pinned reviews API, but the actual Stage 3 Step 2 approve block still used gh pr review --approve (no SHA binding). Update the step-proximate code so an agent following Stage 3 uses the pinned form. * fix(triage): actually encode markdown metachars in sanitize_path + guard empty HEAD_SHA (#6789) - The prose said to encode [](){}* but the sed never did it, so a fork filename like src/[x](https://attacker).ts still rendered as a link inside the <code> cell. Add the five sed clauses (after the & pass, so no double-encoding). - HEAD_SHA capture now fails on gh error and on an empty OID, and the stale check requires a non-empty current head, closing the empty-vs-empty pass. |
||
|---|---|---|
| .github | ||
| .husky | ||
| .qwen | ||
| .vscode | ||
| docs | ||
| docs-site | ||
| eslint-rules | ||
| integration-tests | ||
| 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.
