* feat(autofix): direct takeover of maintainer-fork PRs Maintainer-approved v2: many maintainers work from personal forks, and adoption-snapshotting breaks their local workflow. A fork PR is now directly manageable when three live conditions hold — the takeover label, 'Allow edits from maintainers' (org-owned forks cannot enable it; adoption remains their path), and a fork author who holds write+ RIGHT NOW (the same live-privilege rule as the comment command, so an ex-member's fork can never summon secret-bearing runs). Plumbing: - Scan: fork takeover candidates are admitted per candidate (allow- edits + no-skip filtered in jq; the author's live write+ gate is one permission call each — a rare set); every matrix target now carries its head repo. - Address: prepare fetches the fork branch (origin has no copy) and checks out FETCH_HEAD with hooks already severed; the eligibility gate re-verifies takeover + allow-edits + author write+ live; the report step pushes back to the fork via the allow-edits grant. - Triggers: fork pull_request label events carry NO secrets, so the route notes them and the next scheduled scan engages (≤10m); the comment command now toggles fork PRs too (write+ senders only — fork authors stay silently dropped) and refuses only when allow-edits is missing, with the actionable ask. The scan posts a first-pickup engage ack (identity-verified, deduped on any existing ack, ic.json re-fetched so the same scan counts under the fresh window key) — closing the fork/manual-label ack gap and anchoring the round window. Behavioral coverage: fork-candidate admission jq (allow-edits, skip, in-repo exclusion, tsv rows), eligibility across fork+takeover+allow-edits+write / no-allow-edits / read-author, the toggle's fork split (refusal vs managed), plus plumbing pins (fork fetch/push forms, head_repo threading, first-pickup ack dedup). 60/60 + 12/12. * fix(autofix): strip stray patch-artifact quotes after two fi keywords Two inserted blocks ended 'fi"' — the quotes balanced against each other inside the same script, so bash -n stayed green while runtime would have lexed 'fi' as a command word and swallowed the span between them (the fork head-repo resolution tail and the engage-ack block) into one string. Removed both, and pinned the artifact class in the suite: a lone fi/done/esac followed by a quote now fails the tests. 61/61 + 12/12. * fix(autofix): author-filtered, re-armable first-pickup engage ack Reverse-audit findings on the scan-side ack: - Dedup was a raw grep over ic.json — a forged human comment carrying the engaged marker would have suppressed the real ack (and with it the window anchor). Dedup now selects bot-authored engaged acks via jq, same author rule as the window key itself. - Fork PRs get NO ack job (label events carry no secrets), so the documented re-arm gesture — remove and re-add the label to reset the round window — silently kept the old window: any historical ack blocked a fresh one. When a bot ack already exists, the scan now compares it against the takeover label's latest application time (issue events, fetched only in that rare case); a newer application posts a fresh ack, resetting window and cap as documented. Coverage: verbatim jq replays for both selections (forged-marker and released-marker exclusion, label-name filter, sort|last) plus the lexicographic re-arm gate pin. 61/61 + 12/12. * fix(autofix): review round 1 — ack ordering, dry-run, ghost-engage gate Addresses the maintainer review on #7213 (all findings confirmed): - Critical: the first-pickup ack read ic.json BEFORE the per-PR fetch — the first takeover candidate killed the whole scan step (missing file under -eo pipefail; every in-repo label-forced scan regressed), and later candidates dedup'd against the PREVIOUS PR's comments (bot PR ahead → fresh ack every 10min → window reset → cap never binds). The block now sits directly AFTER the fetch; its post-ack re-fetch keeps the downstream MARKERS/window-key reads fresh. A contract pin asserts the fetch precedes the first ack-timestamp read. - Medium: the ack now honors DRY_RUN (log only, window key untouched). - Medium: the command refused forks only for missing allow-edits — a below-write fork author was a silent ghost engagement (label sticks, no ack, nothing ever manages it). The command now mirrors the scan's author write+ gate with an actionable bilingual refusal. Found while fixing it: PR_INFO never fetched maintainerCanModify (or author), so EVERY fork toggle refused regardless of allow-edits — the test stub carried the field and masked the gap. Both engage-side fork gates are now also scoped to 'add': release is never blocked. - Low: the two new paginated jq reads are slurped (add-merged) so >100 comments/events cannot scramble the timestamp comparisons; replays now feed two concatenated page-documents. Fork fetch pins refs/heads/ (tag shadowing); HEAD_REPO_FULL guards each component (deleted fork = owner XOR name empty); fork-rotation caveat documented; forced-path refusal mentions the scheduled fork path. - Security caveat adopted: prepare proves fork push access with a --dry-run push right after checkout (allow-edits rides the classic-PAT grant only) and discards gracefully instead of 403ing after a full agent round. 61/61 + 12/12; YAML parses; every run block passes bash -n. * fix(autofix): fork targets keep base/branch invariants + 3 hardening follow-ups Blocking (yiliang114): the last fork elif ends the eligibility ladder for every eligible fork, so the LIVE_BASE/LIVE_BRANCH re-checks were unreachable for exactly the PR class the loop fetches and pushes — a labeled fork retargeted off main (or head-renamed) between scan and address would have had conflicts resolved against the wrong base. The base/branch invariants now sit ABOVE the fork chain (comment explains why the order is load-bearing), with replay cases pinning a retargeted and a renamed fork to the discard path. Follow-ups from the same review, all adopted: - PR_LIVE re-reads headRepositoryOwner/headRepository; a fork renamed or transferred since the scan discards at the live re-check (moved or unresolved, fail-closed) instead of fetching and token-pushing a stale path. The replay's fork fixture now carries its head repo and the harness provides the matrix HEAD_REPO to compare against. - The fork fetch failure (force-push/rename race) discards through the standard no-action path instead of a red run. - The first-pickup engage ack defers to the in-repo label event's DEDICATED ack job within a 3-minute grace after the label lands, so a concurrent ack job is never double-posted (which would shift the round-window anchor); a failed ack job is still healed by the next scan, and forks (no ack job) keep immediate pickup. Events are read once, before the branch split. Both hooks-order regex windows widened to span the new fork-arm guards (the assertions are about order; one hooksPath site genuinely covers both checkout arms). 61/61 + 12/12. * test: raise timeout ceiling for I/O-bound tests flaky under CI contention The self-hosted CI runners are heavily oversubscribed (core runs maxThreads: 16), and a recurring class of tests blows vitest's 5s default timeout purely under that contention — not from any logic fault. Observed repeatedly across unrelated PRs (#7213, #7219, and noted in prior sessions): - packages/core/src/utils/shell-ast-parser-lazy.test.ts — fully mocked, but the dynamic import + async coordination exceeds 5s when 16 threads contend. - packages/cli/src/serve/workspace-registration-store.test.ts — tempdir round-trip. - packages/core/src/extension/github.test.ts > extractFile — its waitForFileData helper polled a FIXED 1_000 setImmediate turns, which elapse in <100ms while the tar extraction I/O is still catching up, throwing 'Timed out waiting for extracted data'. Fixes: - testTimeout: 15000 in the core and cli vitest configs — 3x the default. Assertions still fail instantly; only the timeout ceiling grows, so this masks no logic bug (a real hang still fails, just later, and the job timeout still bounds it). - waitForFileData now polls a real ~10s wall-clock budget (2_000 x 5ms) instead of a fixed iteration count, so a slow extraction is awaited rather than raced. Stays under the 15s ceiling. These are the deterministic root-cause fixes for the flake class the autofix loop and CI Failure Patrol were papering over with reruns. --------- Co-authored-by: wenshao <wenshao@example.com> |
||
|---|---|---|
| .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.
