No description
Find a file
xmonader 7f8f981b59 feat(cli): qwen extensions <list|install|search|convert>
#18: the extensions install/marketplace/converter core was
unreachable from any binary. Add a `qwen extensions` subcommand:
- list: ExtensionManager over <cwd>/.qwen/extensions
- install <src> [--npm] [--marketplace]: parse_install_source +
  install_from_source / install_from_npm / Marketplace::resolve
- search <query>: Marketplace::fetch + search
- convert <file> --kind claude-agent|claude-plugin|gemini-config:
  the ported converters, pretty-printed to stdout

Verifying for real surfaced a latent defect that made the whole
subsystem inert: `Extension` had no serde defaults and required
id/enabled/path, so `from_str::<Extension>` failed on every
realistic hand-written extension.json — both the manager and the
post-install loader silently fell back to a stub, and `list` never
showed installed extensions. Fix: serde defaults + enabled
default-true + an `Extension::normalized(dir_name)` that fills
id-from-name / name-from-dir / version / description, applied at
both load sites.

Verified end-to-end: install local → reports real v2.1.0 (was
0.1.0) → list shows it (was "none") → convert works for all three
kinds. 212 qwen-core lib tests pass (2 new manifest tests); release
build clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-19 14:54:44 +02:00
crates feat(cli): qwen extensions <list|install|search|convert> 2026-05-19 14:54:44 +02:00
skills fix(skills): restore bundled skills + parse SKILL.md frontmatter 2026-05-19 12:04:44 +02:00
Cargo.lock feat(acp): ACP agent core + qwen acp stdio loop 2026-05-19 13:57:36 +02:00
Cargo.toml Round 4: close all subsystem gaps — tools, hooks, skills activation, sessions resume, followup 2026-05-18 13:00:56 +02:00
CONVERSION_PLAN.md Round 4: close all subsystem gaps — tools, hooks, skills activation, sessions resume, followup 2026-05-18 13:00:56 +02:00
PARITY.md Round 4: close all subsystem gaps — tools, hooks, skills activation, sessions resume, followup 2026-05-18 13:00:56 +02:00
qwen_adversarial_test.txt Fix path traversal check: block only '..', not absolute paths 2026-05-16 09:33:23 +02:00
qwen_final_verify.txt Fix path traversal check: block only '..', not absolute paths 2026-05-16 09:33:23 +02:00
README.md Round 4: close all subsystem gaps — tools, hooks, skills activation, sessions resume, followup 2026-05-18 13:00:56 +02:00

Qwen-Code (Rust)

AI coding agent ported from Qwen-Code TypeScript to Rust.

Quick Start

# Build
cargo build --release

# Interactive TUI (needs real terminal)
./target/release/qwen

# One-shot prompt
./target/release/qwen -p "explain rust traits"

# JSON output
./target/release/qwen -p "list 3 cli tips" --json

# HTTP server (with auth)
QWEN_API_KEY=mykey ./target/release/qwen serve --port 8080
curl -H "Authorization: Bearer mykey" -X POST http://localhost:8080/chat \
  -H "Content-Type: application/json" \
  -d '{"message":"write hello.py"}'

# Telegram bot
TELEGRAM_BOT_TOKEN=xxx ./target/release/qwen telegram

Modes

Command Description
qwen TUI (terminal UI)
qwen -p "text" One-shot prompt
qwen -p "text" --output-format json|stream-json|text Non-interactive output
qwen -p "/help" Slash command (handled locally)
qwen auth login|status|logout Qwen OAuth device flow
qwen serve HTTP API server (rate-limited)
qwen telegram Telegram bot

Features

  • LLM Providers: OpenAI-compatible (DashScope, Ollama, OpenRouter), Anthropic, Gemini (OpenAI-compat), and Qwen OAuth (device flow) with faithful auth-type resolution
  • System prompt: faithful port of qwen-code's full prompt (env-conditional sandbox/git sections, model-specific tool-call styles, deferred tools)
  • 18 tools: read_file, write_file, edit, run_shell_command, grep_search (ripgrep), glob, web_fetch, list_directory, todo_write, exit_plan_mode, ask_user_question, save_memory, structured_output, tool_search, task_stop, send_message, monitor, cron_create/list/delete, lsp
  • Turn model: full GeminiEventType parity (thought, tool calls, compaction, loop-detected, citations, retry, …)
  • Auto-compaction + loop detection (tool-call & content chanting)
  • LSP: stdio JSON-RPC client + per-language server manager
  • MCP: stdio client + OAuth (PKCE) + file token storage
  • Channels: Telegram, WeChat-Work, DingTalk
  • Telemetry: structured events, metrics registry, secret sanitizer, token-bucket rate limiting
  • Permissions: yolo/auto-edit/default/plan; shell read-only checker
  • Sessions / Memory / Skills / Hooks / SubAgents / Arena / Cron scheduler
  • 170 tests (126 core unit + 42 integration + 2 channel) — see CONVERSION_PLAN.md for the full TS→Rust milestone map

Security

  • HTTP server requires --api-key for authentication
  • Shell commands checked against dangerous pattern denylist
  • API keys masked in logs (first 4 + last 4 chars)
  • Path traversal blocked (".." in file paths)

Configuration

Create ~/.qwen/settings.json (Qwen-Code compatible):

{
  "modelProviders": {
    "openai": [{
      "id": "qwen3.5-plus",
      "name": "Qwen 3.5 Plus",
      "baseUrl": "https://coding-intl.dashscope.aliyuncs.com/v1",
      "envKey": "MY_API_KEY"
    }]
  },
  "model": { "name": "qwen3.5-plus" },
  "security": { "auth": { "selectedType": "openai" } },
  "env": { "MY_API_KEY": "sk-..." }
}

Architecture

qwen-core/     Core engine (LLM, tools, config, agent, memory, etc.)
qwen-tui/      Terminal UI (ratatui + crossterm)
qwen-telegram/ Telegram bot (teloxide)
qwen-cli/      CLI binary (clap + axum)