The Qwen Code extension lives in qwen/ (the output directory declared in src/platforms/qwen/runtime-config.js). The manifest (qwen-extension.json) and context file (QWEN.md) remain at the repo root so Qwen Code can discover the extension; generated artifacts (qwen/agents/, qwen/hooks.json) live in the subdirectory. It mirrors the Gemini CLI extension structure with Qwen-specific manifest, context, and tool mappings.
Manifest: qwen-extension.json
Version: generated from package.json
Context File: QWEN.md
{
"command": "node",
"args": ["${extensionPath}/mcp/maestro-server.js"],
"cwd": "${extensionPath}",
"env": {
"MAESTRO_RUNTIME": "qwen",
"MAESTRO_WORKSPACE_PATH": "${workspacePath}"
}
}Qwen reuses the repo-root public server at mcp/maestro-server.js. The Qwen manifest launches that shared adapter with MAESTRO_RUNTIME=qwen; without that env var the adapter defaults to Gemini. The adapter requires canonical src/mcp/maestro-server.js directly and runs the Qwen runtime against shared source in src/. Qwen declares primary: filesystem and fallback: none.
Qwen uses snake_case for agent names (matching Gemini's convention): code_reviewer, api_designer, accessibility_specialist.
Agent files are generated at qwen/agents/*.md with snake_case filenames (Qwen's own subdirectory, separate from Gemini's repo-root agents/).
Direct function call syntax:
coder(query: "Implement the user service...")
architect(query: "Design the auth system...")
The Qwen runtime does not emit its own TOML command files. src/generator/entry-point-expander.js sets qwen: null in both ENTRY_POINT_CONFIG and CORE_COMMAND_CONFIG, so expandEntryPoints('qwen') and expandCoreCommands('qwen') return empty arrays. This is intentional: Qwen Code is Gemini-CLI-compatible and consumes the 12 TOML commands generated for Gemini at repo-root commands/maestro/ when both extensions coexist. See docs/runtime-gemini.md for the full command list.
4 hook events in qwen/hooks.json:
| Event | Script | Purpose |
|---|---|---|
SessionStart |
hooks/hook-runner.js qwen session-start |
Initialize hook state, prune stale sessions |
SubagentStart |
hooks/hook-runner.js qwen before-agent |
Detect agent, inject session context |
SubagentStop |
hooks/hook-runner.js qwen after-agent |
Validate Task Report + Downstream Context |
SessionEnd |
hooks/hook-runner.js qwen session-end |
Clean up hook state |
Qwen uses the same post-delegation validation as Gemini:
- Checks for
## Task Report(or# Task Report) and## Downstream Contextheadings - First failure: blocks and requests retry
- Second failure (
stopHookActive=true): allows through with warning
Qwen reuses the shared Gemini-style adapter at hooks/adapters/qwen-adapter.js (or the shared Gemini adapter when the CLI JSON shape matches). Output format: { continue: boolean, systemMessage?: string }.
policies/maestro.toml — TOML-based shell guardrails evaluated by Qwen's policy engine (same rules as Gemini):
Deny (priority 950):
rm -rf,rm -fr,sudo rm -rf,sudo rm -frgit reset --hard,git checkout --git clean -fd,git clean -df,git clean -xfd,git clean -xdf- Heredocs (
<<)
Ask User (priority 850):
teecommands- Output redirection (
>,>>)
Qwen tools use canonical names with Qwen-specific overrides declared in src/platforms/qwen/runtime-config.js:
| Canonical | Qwen |
|---|---|
read_file |
read_file |
read_many_files |
read_many_files |
list_directory |
list_directory |
glob |
glob |
grep_search |
grep_search |
google_web_search |
web_search |
web_fetch |
web_fetch |
write_file |
write_file |
replace |
edit |
run_shell_command |
run_shell_command |
ask_user |
ask_user_question |
write_todos |
todo_write |
activate_skill |
skill |
enter_plan_mode |
enter_plan_mode |
exit_plan_mode |
exit_plan_mode |
codebase_investigator |
codebase_investigator |
The canonical feature set (same 4 flags across all runtimes, values per runtime):
exampleBlocks: false
claudeStateContract: false
scriptBasedStateContract: true
codexStateContract: false
See src/platforms/qwen/runtime-config.js for the authoritative values.
Qwen agent stubs share the Gemini shape:
---
name: coder
kind: local
description: "..."
tools: [read_file, write_file, ...]
temperature: 0.2
max_turns: 25
timeout_mins: 10
---Fields: kind (always "local"), temperature, max_turns, timeout_mins.
qwen/
├── agents/ 39 agent stubs (snake_case, Qwen tool names)
└── hooks.json hook registration (SubagentStart, SubagentStop, …)
The Qwen extension reuses Gemini's repo-root commands/maestro/, hooks/, mcp/, and policies/ artifacts when both runtimes coexist; no duplicates are written under qwen/.
- Qwen writes its own agent stubs and hook config to
qwen/agents/andqwen/hooks.json(separate from Gemini's repo-root outputs). For the/maestro:*command surface, Qwen reuses Gemini's repo-rootcommands/maestro/TOML files — the Qwen generator does not duplicate these. node scripts/generate.jsderivesqwen-extension.jsonfrompackage.jsonwith the other runtime manifests so release metadata stays aligned.