qwen-code/packages/desktop
zjgzx1988 07405e669c
fix(artifacts): expand recorded directories into per-file artifacts (#9395)
* fix(artifacts): expand recorded directories into per-file artifacts

A generated folder was stored as one file artifact, so Open and Download hit file APIs on a directory and returned 400. Record each file instead, and treat office documents as downloadable artifacts.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(artifacts): address review on directory expansion

Report depth truncation, keep later files on their own turn, and stop one bad filename or a full-content hash from breaking directory ingest.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(artifacts): tighten directory expansion after review

Use the locator's realpath workspace root, map unlistable directories to validation errors, skip junk roots, and keep walk caps/warnings aligned with what was actually recorded.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(artifacts): drop unused recorded counter

Directory expansion warnings are always surfaced, so the counter tripped no-unused-vars in CI.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(artifacts): close remaining directory-expansion review gaps

Reject non-object metadata and overlong titles before fan-out, wrap symlink-target lstat as validation, skip junk-only over-deep peeks, and stop offering Download for missing files.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(artifacts): follow up on the latest directory-expansion suggestions

Trim derived child titles, hash expanded files like direct records, only flag over-deep trees that actually contain recordable files, and show missing status on download-only cards.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(artifacts): reject worktree-root expansion and close remaining review gaps

Directory expansion treated a worktree cwd as a normal subdirectory, silently dropped unrecordable names, and could overflow the metadata budget when stamping expandedFromDirectory. Align the walker, tool, and store so those cases fail or disclose cleanly, and keep the pathless download test covering the collapsed 3-card cap.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(artifacts): close junk-path, coalesce, and depth-disclosure review gaps

Reject directory expansion when any path component is skip-listed, including symlink aliases into those trees. Treat unreadable over-depth directories as depth-limited, reject trim-unstable child names, and strip expandedFromDirectory when a curated same-batch record wins coalescing.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(artifacts): use bracket access for expandedFromDirectory metadata

acp-bridge tsc fails under noPropertyAccessFromIndexSignature when the test reads the marker via dot access.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(artifacts): keep worktree directory expansion and close round-7 gaps

Strip the bound-root worktree prefix before the skip-directory gate so ordinary subdirectories still expand in worktree sessions. Realpath every directory walk root to catch intermediate symlink aliases into skipped trees, validate parent title/description before fan-out, and make the new fixtures Windows-safe.

Co-authored-by: Cursor <cursoragent@cursor.com>

* fix(ci): refresh desktop bun.lock for Live Host frozen install

Qwen Live Host CI runs `bun install --frozen-lockfile` with Bun 1.3.9; the checked-in lockfile drifted and fails on main and any PR that touches Live Host path filters. Regenerate with the CI Bun version so install stays reproducible.

Co-authored-by: Cursor <cursoragent@cursor.com>

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-08-21 07:46:18 +00:00
..
.agents/skills feat(desktop): compile macOS 26+ Liquid Glass Assets.car in brand-create (#5284) 2026-06-19 03:57:02 +08:00
.github feat(desktop): Add desktop app package with Qwen ACP SDK integration (#3778) 2026-06-11 21:57:20 +08:00
apps fix(desktop): reserve scrollbar gutter so sidebar rows don't jitter (#9073) 2026-08-13 10:00:25 +00:00
docs/plans fix(desktop): isolate update feed from CLI releases (#5139) 2026-06-15 15:32:39 +08:00
packages fix(cli): improve slash command history feedback (#8365) 2026-08-12 17:15:01 +00:00
scripts feat(web-shell): add native Live Voice (#7859) 2026-08-05 08:33:22 +00:00
.dockerignore feat(desktop): Add desktop app package with Qwen ACP SDK integration (#3778) 2026-06-11 21:57:20 +08:00
.gitignore feat(desktop): Add desktop app package with Qwen ACP SDK integration (#3778) 2026-06-11 21:57:20 +08:00
.nvmrc feat(desktop): Add desktop app package with Qwen ACP SDK integration (#3778) 2026-06-11 21:57:20 +08:00
bun.lock fix(artifacts): expand recorded directories into per-file artifacts (#9395) 2026-08-21 07:46:18 +00:00
CODE_OF_CONDUCT.md feat(desktop): Add desktop app package with Qwen ACP SDK integration (#3778) 2026-06-11 21:57:20 +08:00
CONTRIBUTING.md feat(desktop): Add desktop app package with Qwen ACP SDK integration (#3778) 2026-06-11 21:57:20 +08:00
LICENSE feat(desktop): Add desktop app package with Qwen ACP SDK integration (#3778) 2026-06-11 21:57:20 +08:00
NOTICE feat(desktop): Add desktop app package with Qwen ACP SDK integration (#3778) 2026-06-11 21:57:20 +08:00
package.json feat(web-shell): add native Live Voice (#7859) 2026-08-05 08:33:22 +00:00
README.md feat(desktop): Add desktop app package with Qwen ACP SDK integration (#3778) 2026-06-11 21:57:20 +08:00
SECURITY.md feat(desktop): Add desktop app package with Qwen ACP SDK integration (#3778) 2026-06-11 21:57:20 +08:00
TRADEMARK.md feat(desktop): Add desktop app package with Qwen ACP SDK integration (#3778) 2026-06-11 21:57:20 +08:00
tsconfig.base.json feat(desktop): Add desktop app package with Qwen ACP SDK integration (#3778) 2026-06-11 21:57:20 +08:00
tsconfig.json feat(desktop): Add desktop app package with Qwen ACP SDK integration (#3778) 2026-06-11 21:57:20 +08:00

Qwen Code

Qwen Code is a desktop and headless agent workspace. It provides multi-session chat, source connections, skills, file previews, automations, and permission modes in a local-first application.

Backend

This fork is Qwen-only:

  • Agent sessions run through Qwen Code over ACP.
  • The app does not store third-party LLM API keys.
  • The built-in LLM connection is qwen-code.
  • Legacy multi-provider backends and package/runtime wiring have been removed.

Qwen Code CLI Runtime

The desktop app talks to the Qwen Code CLI over ACP. Treat the CLI as a runtime artifact, not as desktop source code. A packaged app must bundle a known CLI build so users can launch it without installing qwen separately.

Use one of these workflows depending on what you are developing:

Workflow Use it when Commands
Default desktop development You are developing desktop only. bun run dev
Published npm package You want a specific published CLI version for dev, CI, or release builds. QWEN_CODE_VERSION=0.15.12-acp.0 bun run dev
Local npm tarball You need to verify the exact package contents before publishing. QWEN_CODE_TARBALL=/path/to/qwen-code-0.15.12-acp.0.tgz bun run dev
Local qwen-code checkout You are changing ACP or other CLI behavior while testing desktop. QWEN_CODE_ROOT=/path/to/qwen-code bun run dev
Explicit CLI entry You need to point at a specific CLI file. QWEN_CODE_CLI=/path/to/qwen-code/scripts/dev.js bun run dev

electron:dev uses local overrides first. If no override is set and this repository is not inside the qwen-code monorepo, it vendors the default version from qwenCodeRuntime.version in package.json and points Electron at the vendored CLI automatically.

If you are preparing a package without publishing it, create the tarball from the Qwen Code repository and point desktop at it:

cd /path/to/qwen-code
npm run build
npm run bundle
npm run prepare:package
npm pack

cd /path/to/desktop
QWEN_CODE_TARBALL=/path/to/qwen-code/qwen-code-0.15.12-acp.0.tgz bun run dist:mac

Distribution builds run electron:vendor:qwen automatically. Set QWEN_CODE_VERSION or QWEN_CODE_TARBALL when you want the packaged app to use a published or packed CLI artifact. If neither is set, this monorepo builds from the local checkout; a standalone desktop checkout uses qwenCodeRuntime.version from package.json.

Development runtime resolution checks sources in this order:

QWEN_CODE_CLI / QWEN_CODE_ROOT / QWEN_CODE_PATH
QWEN_CODE_TARBALL
QWEN_CODE_VERSION
local monorepo checkout
existing vendored CLI
qwenCodeRuntime.version from package.json

Distribution vendoring checks sources in this order:

QWEN_CODE_TARBALL
QWEN_CODE_VERSION
QWEN_CODE_ROOT / QWEN_CODE_PATH
local monorepo checkout
qwenCodeRuntime.version from package.json

Installation

bun install
bun run dev

Common Commands

bun run typecheck:all
bun run test:shared
bun run dev
bun run server:start

Building for Distribution

All build commands run from packages/desktop/.

Prerequisites

  • Bun (see .bun-version for exact version)
  • bun install — install all workspace dependencies

Developer Build (no code signing)

Use this for local testing. Produces an ad-hoc signed app.

# macOS (arm64 + x64)
bun run electron:dist:dev:mac

# Windows
bun run electron:dist:dev:win

# Linux
bun run electron:dist:dev:linux

Release Build (with code signing)

bun run electron:dist:mac
bun run electron:dist:win
bun run electron:dist:linux

Release builds require signing credentials via environment variables:

Variable Purpose
CSC_LINK Path to signing certificate
APPLE_ID Apple ID for notarization
APPLE_APP_SPECIFIC_PASSWORD App-specific password
APPLE_TEAM_ID Team ID for notarization

Build Output

All artifacts are written to apps/electron/release/:

Platform Artifact
macOS Qwen-Code-Desktop-{arm64,x64}.dmg, Qwen-Code-Desktop-{arm64,x64}.zip
Windows Qwen-Code-Desktop-x64.exe
Linux Qwen-Code-Desktop-x64.AppImage

What the Build Does

Each electron:dist:* command runs three stages:

  1. electron:vendor:qwen — vendors a Qwen Code CLI runtime into vendor/qwen-code/. Set QWEN_CODE_VERSION to download a published npm version, or QWEN_CODE_TARBALL to use a local npm pack tarball. If neither is set in this monorepo, it builds from the local checkout.
  2. electron:build — compiles the app via esbuild (main + preload), Vite (renderer), and copies resources/assets.
  3. electron-builder — downloads the Electron runtime, packages the app, signs it, and produces distributable installers (DMG, NSIS, AppImage).

CLI

bun run apps/cli/src/index.ts run "Hello from Qwen"
bun run apps/cli/src/index.ts run --workspace-dir ./project "Summarize this repo"

The run command spawns a headless server, creates a temporary session, streams the response, and exits. Provider flags are accepted only for compatibility; the backend remains Qwen Code.

Repository Layout

apps/
  electron/     Desktop app
  cli/          Terminal client
  webui/        Web adapter
packages/
  shared/       Agent, config, prompts, sessions, sources
  server-core/  RPC handlers and session manager
  core/         Shared types
  ui/           Shared UI components
  session-tools-core/
  session-mcp-server/
scripts/        Build and packaging helpers

Capabilities

  • Multi-session inbox with streaming responses and tool visualization
  • Qwen Code model discovery through ACP
  • MCP, REST API, and local filesystem sources
  • Skills stored per workspace
  • Permission modes for planning, asking before edits, and autonomous execution
  • File attachments and in-app previews for images, PDFs, Office files, and diffs
  • Event-driven automations and messaging integrations

License

Apache 2.0. Third-party dependencies are listed in package manifests and are subject to their respective licenses.