Find a file
易良 010941d202
fix(standalone): pin @lydell/node-pty-linux-arm64 and fail release on missing prebuilds (#12649)
* fix(standalone): pin @lydell/node-pty-linux-arm64 and make missing prebuilds fatal at release

The wrapper publishes a linux-arm64 prebuild at the same 1.2.0-beta.10 pin,
but the root and core manifests never declared it, so the linux-arm64
standalone archive and the linux-arm64 Desktop runtime both degraded to
"PTY not available" while every other target shipped a working web
terminal.

With the pin in place every shipped target resolves a prebuild package, so
the release archive build can stop degrading silently: release.yml now
exports QWEN_STANDALONE_REQUIRE_NODE_PTY_PREBUILD=1 next to the existing
audio-capture gate, turning a missing prebuild into a hard failure instead
of another #11872.

Fixes #11872

* fix(standalone): update pnpm lockfile for the linux-arm64 node-pty pin

The two package.json manifests gained @lydell/node-pty-linux-arm64 but
pnpm-lock.yaml was not regenerated, so every CI job failed at the
frozen-lockfile install with ERR_PNPM_OUTDATED_LOCKFILE.

* docs(standalone): align the linux-arm64 PTY guide and tripwire with the pin

Pinning @lydell/node-pty-linux-arm64 makes linux-arm64 a supported PTY target,
but INSTALLATION_GUIDE.md still told users that archive ships without PTY and
reports "PTY not available". CI could not catch the drift because
install-script.test.js pinned that exact sentence as its tripwire, so the guide
and the assertion have to move together.

List all five shipped targets in the guide, retarget the tripwire at the new
sentence, and refresh the matching stale comment in desktop-shell's
test-release.js degrade fixture - that arm now only fires for a target the map
does not know.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* fix(standalone): complete the node-pty linux-arm64 pin in esbuild externals

`create-standalone-package.js` documents that "esbuild.config.js keeps every
node-pty specifier external" so the bundled CLI resolves the platform prebuild
from `lib/node_modules` at runtime. The external list carried five of the six
pinned platform packages and omitted `@lydell/node-pty-linux-arm64` — the exact
platform this PR pins. Nothing imports that specifier statically today, so the
bundle is unaffected; the gap is that the invariant the archive's PTY support
rests on was one entry short of complete.

Probe (esbuild, `--platform=node --format=esm`, entry importing both
specifiers):

- without the entry: `Could not resolve "@lydell/node-pty-linux-arm64"`
- with the entry: builds clean and emits the import left external, matching
  the other five platforms

Also corrects two comments this PR rewrote in the previous round. Both claimed
the desktop degrade arm "fires only for a target the map does not know (a
future platform)". That trigger is unreachable: `desktopTarget()` throws
`Unsupported desktop target` for anything outside its five-entry allowlist and
`NODE_PTY_PREBUILD_PACKAGE` maps exactly those five, so `prebuildPackage` is
always a real name. Verified by running the script:

    $ QWEN_DESKTOP_SKIP_BUILD=1 QWEN_DESKTOP_TARGET=freebsd-x64 \
        node packages/desktop-shell/scripts/prepare-runtime.js
    Error: Unsupported desktop target: freebsd-x64
        at desktopTarget (prepare-runtime.js:351:11)

The reachable trigger is the one the warn string already names and the one
`test-release.js` reproduces four lines below its own comment: a known target
whose prebuild package is unpinned in the source root manifest.

Comment-only apart from the single external entry. prettier --check and
eslint --max-warnings 0 clean on all three files; node --check passes.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>

* test(standalone): pin the node-pty release gate and its target map

Closes out three review findings on the node-pty pin. Test- and
comment-only apart from one new export; no production behavior changes.

R1-1 prepare-runtime.js: the nodePtyPackageSpecs() docstring still claimed
its null return "is how an unsupported target degrades". desktopTarget()
throws for anything outside its five-entry allowlist, and
test-release.js:testRuntimeNodePtyTargetMapping() asserts
NODE_PTY_PREBUILD_PACKAGE's keys equal exactly that allowlist, so an
unknown target can never reach it. A null here is a dropped pin. Verified
by re-running that tripwire's extraction against the edited file: both
literals still match and keys == allowlist == the same five targets.

R1-2 create-standalone-package.js: export TARGET_PREBUILD_DIR and assert
every release target maps to a package the manifests actually pin. The
guide sentence this PR adds states that invariant while release.yml:707
makes violating it abort the whole archive step, yet the map had zero test
references. The expectation is derived from readNodePtyPackageSpecs() so
the version list stays single-sourced, and is one-directional because
@lydell/node-pty-win32-arm64 is pinned while no target maps to it.

R1-3 install-script.test.js: the release.yml assertion matched only the
variable name, which also appears in the packager's usage text, so nothing
connected producer to consumer and no test executed the fail() branch at
create-standalone-package.js:578. Tightened to the full wiring line and
added the behavioral twin of the audio-capture pair: gate on with the
addon removed must throw, gate off must still build a PTY-less archive.
packageFakeStandalone() gained an env option for this; spreading
process.env leaves its 15 existing callers unchanged.

Mutation-checked, each mutant applied alone then restored and md5
verified: win-x64 mapped to an unpinned name, gate reader renamed to '2',
gate polarity flipped to !==, and release.yml no longer evaluating to '1'
are each caught by a new or tightened assertion. The polarity flip was
previously undetectable on the PR lane, where the linux-x64 prebuild is
present so the gate is never reached.

Focused: install-script.test.js 130 passed / 11 skipped (141).
prettier --check and eslint --max-warnings 0 clean on all three files.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-closeout/jmufv3et42h

* docs(standalone): state the real node-pty degrade conditions in comments

prepare-runtime.js said the degrade arm fires only "where the repo pins
nothing", but nodePtyPackageSpecs returns null at the first unpinned name of
the pair, so it also fires when the wrapper pin is the one that went missing
while the warning names the prebuild package. Say "either name in the pair"
and note which package the warning names.

create-standalone-package.js justified the non-fatal default with "a developer
archive stays usable on an unmapped future target", which cannot happen:
main() calls copyNativeAddon first and it reads the same TARGET_PREBUILD_DIR
in an unconditional path.join(), so an unmapped target dies with a TypeError
in the audio step before copyNodePtyAddon runs. Replace the rationale with the
case that does reach the warn arm (a target whose prebuild the host install
does not have).

Comment-only; no behaviour change.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-closeout/jmug1iw422v

* test(standalone): make the node-pty gate assertions discriminate

Pin the `Required ` prefix on the fatal-gate regex. copyNodePtyAddon builds
one message and emits it on both paths, so the prefix-less regex was also
satisfied by the degrade warning folded into the child's stderr — the suite
would have reported the gate as covered after the prefix was dropped from
fail(). The sibling clipboard gate assertion already spells the prefix.

Assert QWEN_STANDALONE_REQUIRE_NODE_PTY_PREBUILD structurally on the `Build
Standalone Archives` step env instead of as a whole-file substring, so
commenting the line out or moving it into a neighbouring step's env goes red.
build-standalone-release.js spawns the packager with no env override, so that
step's env is the only route to the gate. The comment defending the substring
pin named a collision with create-standalone-package.js's usage text, which
cannot occur: the searched string is release.yml alone.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-closeout/jmug1iw422v

* test(standalone): cover the node-pty target map and the win-x64 dir name

Two coverage gaps left by the previous round of gate tests:

- The map test looped over TARGET_PREBUILD_DIR itself, so a release target
  with no map entry was never visited, deleting a whole entry merely removed
  an iteration, and an emptied map passed vacuously. Drive the loop from
  TARGETS and assert the lookup before the pin. Still one-directional:
  @lydell/node-pty-win32-arm64 is pinned while no target maps to it.

- Both gate tests reached the packager through packageFakeStandalone, which
  hardcoded --target linux-x64, the one dialect where the prebuild dir name
  equals the target name. Add a win-x64 arm so the 'win-x64' -> 'win32-x64'
  translation in copyNodePtyAddon is covered on every lane rather than only
  on test_windows. Parameterise the staged-modules fixture and the packaging
  helper to make that reachable without a Windows host.

Test-only change; no production code is modified.

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Patrol-Run: qwen-pr-closeout/jmug5t7mp33

---------

Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
2026-09-25 04:38:07 +00:00
.github fix(standalone): pin @lydell/node-pty-linux-arm64 and fail release on missing prebuilds (#12649) 2026-09-25 04:38:07 +00:00
.husky Sync upstream Gemini-CLI v0.8.2 (#838) 2025-10-23 09:27:04 +08:00
.qwen docs(verify-pr): add persisted-state, steady-state and skip-coverage rules (#12456) 2026-09-23 01:09:13 +00:00
.vscode Merge branch 'main' into feat/sandbox-config-improvements 2026-03-06 14:38:39 +08:00
docs feat(sdk-java): Reconcile and adopt restored Runtime bindings (#12627) 2026-09-25 03:40:48 +00:00
docs-site Hide internal docs from docs site (#4357) 2026-06-01 15:55:14 +08:00
eslint-rules ci(lint): stop new cli imports from the core package root (#11798) 2026-09-14 04:49:03 +00:00
integration-tests feat(web-shell): manage the repository's worktrees from the git dialog (#12154) 2026-09-24 15:55:11 +00:00
integrations chore(release): v0.24.5 (#12661) 2026-09-24 17:19:31 +00:00
packages fix(standalone): pin @lydell/node-pty-linux-arm64 and fail release on missing prebuilds (#12649) 2026-09-25 04:38:07 +00:00
patches fix(cli): make the ink useBoxMetrics loop guard independent of machine speed (#11835) 2026-09-16 11:43:37 +00:00
scripts fix(standalone): pin @lydell/node-pty-linux-arm64 and fail release on missing prebuilds (#12649) 2026-09-25 04:38:07 +00:00
.dockerignore refactor(ci): extract release workflow scripts (#11165) 2026-09-08 07:09:09 +00:00
.editorconfig pre-release commit 2025-07-22 23:26:01 +08:00
.gitattributes feat: chat transcript mr2a html export (#10076) 2026-09-04 14:36:35 +00:00
.gitignore ci(pnpm): install with pnpm everywhere and retire package-lock.json (#11859) 2026-09-20 02:11:25 +00:00
.npmrc chore: remove google registry 2025-08-08 20:45:54 +08:00
.nvmrc chore(deps): upgrade ink 6.2.3 → 7.0.2 + bump Node engine to 22 (#3860) 2026-05-11 17:29:50 +08:00
.pnpmfile.mjs feat(browser-use): add Playwright-based Browser SDK (#11241) 2026-09-17 11:06:56 +00:00
.prettierignore feat(browser-use): add Chrome Native Messaging relay (#11242) 2026-09-18 05:50:24 +00:00
.prettierrc.json pre-release commit 2025-07-22 23:26:01 +08:00
.yamllint.yml perf(dev): add pnpm worktree bootstrap foundation (#10449) 2026-09-08 03:07:40 +00:00
AGENTS.md ci(pnpm): install with pnpm everywhere and retire package-lock.json (#11859) 2026-09-20 02:11:25 +00:00
CHANGELOG.md chore(release): v0.24.5 (#12661) 2026-09-24 17:19:31 +00:00
CLAUDE.md docs: rewrite CLAUDE.md to point to AGENTS.md as authoritative source (#5138) 2026-06-15 15:23:26 +08:00
CONTRIBUTING.md docs: fix /clear description, .qwen note, and outdated CLI name (#12555) 2026-09-24 12:54:19 +00:00
Dockerfile ci(pnpm): install with pnpm everywhere and retire package-lock.json (#11859) 2026-09-20 02:11:25 +00:00
esbuild.config.js fix(standalone): pin @lydell/node-pty-linux-arm64 and fail release on missing prebuilds (#12649) 2026-09-25 04:38:07 +00:00
eslint.config.js feat(browser-use): add Chrome Native Messaging relay (#11242) 2026-09-18 05:50:24 +00:00
eslint.legacy-core-barrel-imports.mjs feat(web-shell): manage git remotes from the workspace branch picker (#11163) 2026-09-17 13:40:47 +00:00
eslint.legacy-filenames.mjs refactor(goal): delete the first-generation Stop-hook Goal implementation (#11900) 2026-09-15 07:19:05 +00:00
LICENSE Sync upstream Gemini-CLI v0.8.2 (#838) 2025-10-23 09:27:04 +08:00
Makefile feat: update docs 2025-12-22 21:11:33 +08:00
package.json fix(standalone): pin @lydell/node-pty-linux-arm64 and fail release on missing prebuilds (#12649) 2026-09-25 04:38:07 +00:00
pnpm-lock.yaml fix(standalone): pin @lydell/node-pty-linux-arm64 and fail release on missing prebuilds (#12649) 2026-09-25 04:38:07 +00:00
pnpm-workspace.yaml ci(pnpm): install with pnpm everywhere and retire package-lock.json (#11859) 2026-09-20 02:11:25 +00:00
README.md docs: update README hero image (#12474) 2026-09-22 13:17:13 +00:00
SECURITY.md fix: update security vulnerability reporting channel 2026-02-24 14:22:47 +08:00
tsconfig.json # 🚀 Sync Gemini CLI v0.2.1 - Major Feature Update (#483) 2025-09-01 14:48:55 +08:00
vitest.config.ts feat(qwen-live): standalone voice daemon package — M1 + M2 (#10367) 2026-09-01 06:37:23 +00:00

npm version License Node.js Version Downloads

QwenLM%2Fqwen-code | Trendshift

The open-source AI coding agent for your terminal, editor, desktop, browser, and chat.

中文 | Deutsch | français | 日本語 | Русский | Português (Brasil) | 한국어

Qwen Code in the terminal, desktop app, browser, editor, and chat, with VS Code, Zed, JetBrains, Telegram, DingTalk, WeChat, and Feishu integrations

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.

See the terminal interface

Qwen Code terminal interface

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 serve to 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

Qwen Code version 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.