* 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> |
||
|---|---|---|
| .. | ||
| .agents/skills | ||
| .github | ||
| apps | ||
| docs/plans | ||
| packages | ||
| scripts | ||
| .dockerignore | ||
| .gitignore | ||
| .nvmrc | ||
| bun.lock | ||
| CODE_OF_CONDUCT.md | ||
| CONTRIBUTING.md | ||
| LICENSE | ||
| NOTICE | ||
| package.json | ||
| README.md | ||
| SECURITY.md | ||
| TRADEMARK.md | ||
| tsconfig.base.json | ||
| tsconfig.json | ||
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-versionfor 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:
electron:vendor:qwen— vendors a Qwen Code CLI runtime intovendor/qwen-code/. SetQWEN_CODE_VERSIONto download a published npm version, orQWEN_CODE_TARBALLto use a localnpm packtarball. If neither is set in this monorepo, it builds from the local checkout.electron:build— compiles the app via esbuild (main + preload), Vite (renderer), and copies resources/assets.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.