feat(host): add Qwen Code host adapter - #6
Conversation
|
ok |
There was a problem hiding this comment.
Pull request overview
该 PR 将 Qwen Code 作为第五个受支持的 Host 平台接入 Better Harness(与 Qoder / Codex / Claude Code / Cursor 并列),补齐会话证据(session-analysis)、资产盘点(agent-customize)、插件壳(plugin shell)、打包校验与文档/测试覆盖。
Changes:
- 新增 Qwen 会话分析适配器:读取
~/.qwen/projects/<slug>/chats/**/*.jsonl,归一化message.parts的 functionCall/functionResponse 与toolCallResult。 - 新增 Qwen 资产盘点适配器:盘点
~/.qwen/{skills,agents,rules,commands,hooks,extensions}、工作区.qwen/、QWEN.md以及~/.mcp.json。 - 增加
.qwen-plugin/plugin.json并更新 npm 打包/校验、CLI help、参考文档与测试用例以纳入qwen平台。
Reviewed changes
Copilot reviewed 45 out of 45 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| test/session-analysis-providers.test.mjs | 增加 Qwen provider 的 session 事件展开与 workspace slug 覆盖测试。 |
| test/scripts-refactor-contract.test.mjs | 更新 CLI 输出契约哈希以反映新增平台。 |
| test/plugin-manifests.test.mjs | 将 .qwen-plugin/plugin.json 纳入宿主插件清单一致性与打包包含性断言。 |
| test/fixtures/scripts-refactor-contract/session-help.txt | session-analysis 帮助文本加入 qwen。 |
| test/fixtures/scripts-refactor-contract/root-help.txt | 根命令 help 文本更新以包含 Qwen。 |
| test/coding-agent-platform-notes.test.mjs | sessions-diagnostics 平台说明加入 Qwen 并断言排序/内容。 |
| test/better-harness-evidence-bundle.test.mjs | evidence-bundle 的 agentCustomize lane 覆盖 Qwen 路由。 |
| test/agent-customize.test.mjs | 增加 Qwen fixture 与 inventory 断言(插件、MCP、skills/hooks/rules/commands/agents)。 |
| test/agent-customize-architecture.test.mjs | 架构/社区/术语文档断言从“四个平台壳”更新到“五个平台壳”。 |
| test/agent-asset-integrity.test.mjs | asset-integrity CLI 增加 Qwen 路径与隐私不泄漏断言。 |
| test/agent-asset-baseline.test.mjs | asset-baseline 增加 Qwen provider 的基线收集测试。 |
| scripts/session-analysis/usage-summary.mjs | --platform 参数说明加入 qwen。 |
| scripts/session-analysis/selection-profile.mjs | --platform 参数说明加入 qwen。 |
| scripts/session-analysis/platforms/qwen.mjs | 新增 Qwen 会话分析器实现。 |
| scripts/session-analysis/lifecycle-demand-signals.mjs | 平台白名单加入 qwen。 |
| scripts/session-analysis/analyzer.mjs | loader/帮助与错误信息加入 qwen + 动态 import。 |
| scripts/session-analysis.mjs | 顶层 shim loader/usage 加入 qwen + 动态 import。 |
| scripts/npm-package/verify-pack.mjs | pack 校验:版本对齐、必需文件、runtime bundle 禁止项加入 .qwen-plugin/。 |
| scripts/harness-analysis/task-loop-source.mjs | task-loop source 支持 qwen(平台列表、asset review 支持、qwenHome 透传、inventory 路由)。 |
| scripts/harness-analysis/task-loop-report.mjs | 报告平台白名单加入 qwen。 |
| scripts/harness-analysis/report-run.mjs | report-run 平台白名单与 CLI 允许参数加入 qwen-home。 |
| scripts/harness-analysis/report-quality.mjs | 会话范围识别正则加入 .qwen / qwen。 |
| scripts/harness-analysis/evidence-bundle/contract.mjs | evidence-bundle provider 集合加入 qwen。 |
| scripts/harness-analysis/evidence-bundle/cli.mjs | evidence-bundle CLI 平台说明与允许参数加入 qwen。 |
| scripts/harness-analysis/evidence-bundle/agent-customize.mjs | agentCustomize lane provider 白名单加入 qwen。 |
| scripts/coding-agent-practices/inventory.mjs | inventory CLI/平台白名单加入 qwen。 |
| scripts/coding-agent-practices/asset-integrity.mjs | asset-integrity CLI provider 白名单与 usage 加入 qwen。 |
| scripts/coding-agent-practices/asset-baseline.mjs | asset-baseline provider 白名单、usage、错误信息加入 qwen。 |
| scripts/better-harness-cli/registry.mjs | CLI registry 描述更新以包含 Qwen。 |
| scripts/agent-lint/cli.mjs | agent-lint provider usage 加入 qwen。 |
| scripts/agent-customize/providers/qwen.mjs | 新增 Qwen agent-customize provider 实现。 |
| scripts/agent-customize/providers/index.mjs | provider collectors map 注册 qwen。 |
| scripts/agent-customize/cli.mjs | summary 透出 qwenHome。 |
| references/session-evidence/sessions-diagnostics.md | sessions diagnostics 文档加入 Qwen 平台说明与命令示例。 |
| references/loop-engineering/loop-discovery.md | loop-discovery 文案更新以包含 Qwen 会话证据。 |
| references/agent-customize/routing.md | agent-customize routing 增加 Qwen Asset Route。 |
| references/agent-customize/platforms/qwen.md | 新增 Qwen Code best practices 参考文档。 |
| package.json | npm files 列表加入 .qwen-plugin/。 |
| docs/glossary.md | glossary 补充 Qwen 平台与 host shell 列表/描述更新。 |
| docs/concepts.md | concepts 中 session evidence 描述加入 Qwen。 |
| docs/community.md | community 中 host shell/packaging 条目加入 Qwen。 |
| docs/ARCHITECTURE.md | 架构说明从 4 个插件壳更新为 5 个。 |
| docs/adrs/directory-structure.md | 目录结构 ADR 更新 host adapter 列表与插件壳数量。 |
| docs/adapters/README.md | Host Adapter Matrix 新增 Qwen Code 行与说明;输出模式描述更新。 |
| .qwen-plugin/plugin.json | 新增 Qwen 插件壳清单。 |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
When toolCallResult.resultDisplay is absent (8.9% of real tool_result rows), fall back to functionResponse.response.output for resultFacts extraction. Also use functionResponse.id as a fallback for callId correlation. Addresses Copilot review comment on PR QoderAI#6.
|
@copilot thanks for the catch — this is a real gap, not hypothetical. Validated against real Qwen Code session data (24,207 Fixed in 593d1b2: All 10 |
Review result: request changesI reviewed this PR in an isolated worktree and cross-checked the adapter against the local Qwen Code 0.21.0 source at Blocking findings
Review readiness
Suggested repair sequence
The logged-in Qwen review independently flagged the same seven implementation gaps. One wording correction from that model output: lowercasing is Windows-only; replacing all non-alphanumeric characters applies on every platform. |
When toolCallResult.resultDisplay is absent (8.9% of real tool_result rows), fall back to functionResponse.response.output for resultFacts extraction. Also use functionResponse.id as a fallback for callId correlation. Addresses Copilot review comment on PR QoderAI#6.
|
@phodal thanks for the thorough review — all 7 findings confirmed against Qwen Code 0.21.0 source and fixed in 59541aa (rebased onto current main, conflict resolved). What changed
Verification
Still open
|
|
CI fix in b464d06: macOS and Windows both failed test 584 ("Qwen provider expands function calls and tool results from parts") with Root cause: on case-insensitive filesystems (HFS+, NTFS), the two slug variants from Fix: dedupe resolved root paths via |
|
@phodal could you approve the pending workflow run for the latest push (b464d06)? It is currently in This push fixes the macOS/Windows CI failure (case-insensitive filesystem slug dedup) on top of the review fixes. |
Follow-up review of
|
Add Qwen Code as a fifth supported host alongside Qoder, Codex, Claude Code,
and Cursor.
Session analyzer (scripts/session-analysis/platforms/qwen.mjs) parses
~/.qwen/projects/<slug>/chats/*.jsonl transcripts using the message.parts
functionCall/functionResponse format and top-level toolCallResult, mapping
usageMetadata to standard usage fields.
Asset collector (scripts/agent-customize/providers/qwen.mjs) inventories
~/.qwen/{skills,agents,rules,commands,hooks,extensions} plus workspace .qwen,
QWEN.md, AGENTS.md, and ~/.mcp.json.
New files: .qwen-plugin/plugin.json, session-analysis/platforms/qwen.mjs,
agent-customize/providers/qwen.mjs, references/agent-customize/platforms/qwen.md.
Updated: registration points, platform whitelists, help/USAGE text, docs
(sessions-diagnostics, adapters/README matrix, routing, ARCHITECTURE,
community, glossary), and 7 test files.
832 tests pass; pack:verify passes.
When toolCallResult.resultDisplay is absent (8.9% of real tool_result rows), fall back to functionResponse.response.output for resultFacts extraction. Also use functionResponse.id as a fallback for callId correlation. Addresses Copilot review comment on PR QoderAI#6.
…ug, enablement, settings.json Address all 7 findings from phodal's review: P1: Replace .qwen-plugin/plugin.json with native qwen-extension.json at repo root, matching Qwen's EXTENSIONS_CONFIG_FILENAME contract. P1: Separate QWEN_HOME (config) from QWEN_RUNTIME_DIR (session data) in resolveScope; discoverSourceRoots now reads from runtimeDir. P1: Match native sanitizeCwd exactly — replace every non-alphanumeric character with '-', lowercase variant for Windows compatibility. P1: Read qwen-extension.json for extension metadata; compute enablement from extension-enablement.json overrides path rules instead of a nonexistent disabled boolean. P1: Read mcpServers and hooks from user/workspace settings.json in addition to .mcp.json and hooks.json. P2: Treat cancelled tool_result status as non-success. P2: Thread qwenHome through providerScope, collectProviderInventory, and userBase fallback in inventory.mjs. Also: rebase onto current main, resolve test/agent-customize.test.mjs conflict. 840 tests pass; pack:verify passes.
…tems On macOS (case-insensitive HFS+), two slug variants differing only in case resolve to the same projects directory, causing session files to be read twice and inflating responseCount. Use realpathSync.native to dedupe resolved root paths before walking.
…P paths, canonical enablement 1. [P1] Read process.env.QWEN_HOME as fallback in both session analyzer resolveScope and customize provider defaultQwenHome. 2. [P1] Parse settings.json hooks in native Qwen shape: object keyed by event name → array of definitions → nested hooks array. Supports both command and http hook types. 3. [P1] User MCP now reads from <QWEN_HOME>/settings.json mcpServers (not ~/.mcp.json). Project MCP reads from <workspace>/.mcp.json (not <workspace>/.qwen/.mcp.json). Preserve url/httpUrl transport metadata. 4. [P2] Extension enablement now evaluates overrides against both lexical and canonical (realpathSync.native) workspace paths, matching native Qwen behavior for symlinked workspaces. Also: agent-customize --help adds qwen/--qwen-home; reference doc updated for native MCP paths and sanitizeCwd slug algorithm; rebased onto current main. 866 tests pass; pack:verify passes.
|
@phodal follow-up fixes pushed in 5af2afb (rebased onto 305ee58). All 4 items addressed and locally verified: 1. [P1] QWEN_HOME env fallbackBoth adapters now read
Verified: 2. [P1] Native hooks shapeReplaced Verified: fixture with 3. [P1] MCP paths + transport metadata
Verified: settings-based 4. [P2] Canonical path enablement
Verified: symlink Smaller items
866/866 tests pass; pack:verify passes (npm 308, runtime 334). The spec doc ( |
|
@phodal we have started using the adapter on a real internal project (a Python/Django service with ~6 months of Qwen Code session history). Sharing sanitized findings: Smoke test:
|
Resolve the docs/adapters/README.md matrix conflict introduced by the Qwen Code host adapter (QoderAI#6): keep this branch's reviewed Cursor row (Default Output pending U-03, runtime smoke pending U-04) and keep the new Qwen Code row, updating its Smoke cell from the nonexistent `harness prepare --platform qwen` -> `html-report` chain to the current `harness analyze --platform qwen` -> `harness render --mode html --validate` chain, matching A-05 AC-1 (no stale `harness prepare` / standalone `html-report` strings in the matrix; `--platform qwen` is accepted by scripts/harness-analysis/report-run.mjs). Test: node --test better-harness-skill agent-customize-architecture doc-link-graph legacy-product-names (21/21) AI: Assisted
Summary
Add Qwen Code as a fifth supported host, alongside Qoder, Codex, Claude Code, and Cursor.
What's new
scripts/session-analysis/platforms/qwen.mjs): parses~/.qwen/projects/<slug>/chats/*.jsonltranscripts using themessage.partsfunctionCall/functionResponse format and top-leveltoolCallResult, mappingusageMetadatato standard usage fields.scripts/agent-customize/providers/qwen.mjs): inventories~/.qwen/{skills,agents,rules,commands,hooks,extensions}+ workspace.qwen+QWEN.md+~/.mcp.json..qwen-plugin/plugin.json)references/agent-customize/platforms/qwen.md)Changes
pack:verifypassesVerification
Validated against real Qwen Code session data:
session-analysis sources --platform qwendiscovers real sessionssession-analysis facts --platform qwenoutputssession-core-facts(schemaVersion 3)harness evidence-bundle --platform qwen— all 3 lanes (sessionEvidence + projectHarness + agentCustomize) available