Skip to content

fix(core): Align MCP OAuth guidance and docs#5589

Merged
wenshao merged 22 commits into
QwenLM:mainfrom
doudouOUC:docs/audit-documentation-consistency
Jun 23, 2026
Merged

fix(core): Align MCP OAuth guidance and docs#5589
wenshao merged 22 commits into
QwenLM:mainfrom
doudouOUC:docs/audit-documentation-consistency

Conversation

@doudouOUC

@doudouOUC doudouOUC commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

What this PR does

This PR updates Qwen Code documentation and the related runtime behavior so user-facing MCP, SDK, sandbox, extension, theme, channel plugin, and Qwen OAuth guidance matches the current CLI. It removes stale MCP OAuth command references, points users to the /mcp dialog for authentication and recovery, clarifies SDK permission semantics, fixes broken local documentation links, and refreshes outdated setup guidance.

It also includes the code and test fixes needed to keep that guidance true in practice. MCP OAuth error paths now surface actionable /mcp recovery instructions when automatic authentication, discovery, token validation, or stored-token reuse fails; stored credentials that cannot produce a valid token now emit a warning instead of silently falling through; web-shell and CLI completions no longer advertise removed auth subcommands; and the shared text input was migrated from Ink internal subpaths to the public Ink hooks so this runtime cleanup does not continue relying on internal module paths.

Why it's needed

The documentation had drifted from the code in several places, including stale command names, broken local links, outdated SDK permission field descriptions, and older Qwen OAuth wording. Those mismatches can send users toward commands that no longer exist or configuration keys with different semantics.

The code changes are included because some stale documentation pointed at behavior that the CLI no longer implemented cleanly, while some runtime errors still failed to give users the recovery path now documented. Without the runtime fixes, the updated docs would be accurate only on the happy path, and users with expired or unusable MCP OAuth credentials could still receive generic failures with no clear next step. The Ink cleanup is a small maintainability refactor that moves the text input off internal Ink subpath imports and onto public hooks; it is included with tests, but it is not required to fix the repository's current pinned Ink build.

Reviewer Test Plan

How to verify

Review the updated MCP and SDK documentation and confirm that MCP OAuth authentication points users to the /mcp dialog, SDK coreTools is described as the legacy --core-tools allowlist rather than ordinary permissions.allow, and local documentation links resolve. Exercise the MCP OAuth failure paths in the focused tests and confirm that automatic OAuth failures, discovery failures, token validation failures, and stored-token fallback cases all produce actionable recovery guidance. Run the focused MCP, CLI input/status, and web-shell completion tests, then run the workspace build and typecheck; the expected result is that all commands exit successfully with only the existing vscode companion lint warnings.

Evidence (Before & After)

Before: MCP OAuth docs and status tips referenced /mcp auth <server-name>, SDK docs described coreTools as equivalent to permission allow rules, completion hints included removed auth arguments, several MCP OAuth failures surfaced generic errors or silently fell back when stored credentials were unusable, and the shared text input depended on Ink internal subpaths. After: OAuth guidance uses the /mcp dialog path, MCP recovery errors include the documented next step, stored-token fallback emits a warning, MCP completion hints no longer include removed auth arguments, SDK docs distinguish coreTools registry allowlist semantics from permissions.allow auto-approval, and the shared text input uses public Ink hooks. Build evidence: npm run build && npm run typecheck exits 0 locally; the vscode companion build still reports 15 pre-existing lint warnings and 0 errors.

Tested on

OS Status
🍏 macOS ✅ tested
🪟 Windows ⚠️ not tested locally; covered by PR CI
🐧 Linux ⚠️ not tested locally; covered by PR CI

Environment (optional)

Node.js v22.22.3, npm 10.9.8.

Risk & Scope

  • Main risk or tradeoff: The broad documentation sweep touches many cross-links and command references, and the MCP OAuth changes touch error handling around authentication recovery, so the main risk is inaccurate wording or an unintended change in failure messaging.
  • Not validated / out of scope: Windows and Linux were not tested locally; no visual TUI screenshot was captured for the changed MCP status tip.
  • Breaking changes / migration notes: No intentional breaking changes or migrations.

Linked Issues

N/A

中文说明

What this PR does

这个 PR 更新了 Qwen Code 的文档以及相关运行时行为,使面向用户的 MCP、SDK、沙箱、扩展、主题、通道插件和 Qwen OAuth 指引与当前 CLI 保持一致。它移除了过期的 MCP OAuth 命令引用,指引用户通过 /mcp 对话框完成认证和恢复,澄清了 SDK 权限语义,修复了失效的本地文档链接,并刷新了过时的设置说明。

它还包含了让这些指引在实际运行中成立所需的代码和测试修复。当自动认证、发现、token 校验或已保存 token 复用失败时,MCP OAuth 错误路径现在会给出可执行的 /mcp 恢复指引;已保存凭据无法产出有效 token 时会输出 warning,而不是静默降级;web-shell 和 CLI 补全不再展示已经移除的 auth 子命令;共享文本输入也从 Ink 内部子路径迁移到了公开 Ink hooks,使这次运行时清理不再继续依赖内部模块路径。

Why it's needed

文档中有多处已经与代码行为不一致,包括过期命令名、失效的本地链接、过时的 SDK 权限字段描述,以及旧的 Qwen OAuth 表述。这些不一致会让用户尝试不存在的命令,或误解配置键的真实语义。

代码变更之所以一起包含在这个 PR 中,是因为部分过期文档指向了 CLI 已经不能干净支持的行为,而部分运行时错误也仍然没有给出文档中承诺的恢复路径。如果没有这些运行时修复,更新后的文档只会在正常路径上准确;当用户遇到过期或不可用的 MCP OAuth 凭据时,仍可能收到没有明确下一步的通用失败信息。Ink 清理是一个小的可维护性重构,把文本输入从 Ink 内部子路径迁移到公开 hooks;它包含测试,但并不是为了解决仓库当前锁定 Ink 版本下的构建问题。

Reviewer Test Plan

How to verify

检查更新后的 MCP 和 SDK 文档,确认 MCP OAuth 认证指向 /mcp 对话框,SDK coreTools 被描述为 legacy --core-tools allowlist,而不是普通的 permissions.allow,并确认本地文档链接可解析。通过聚焦测试覆盖 MCP OAuth 失败路径,确认自动 OAuth 失败、发现失败、token 校验失败和已保存 token 降级场景都会产出可执行的恢复指引。运行 MCP、CLI 输入/状态以及 web-shell 补全的聚焦测试,再运行工作区 build 和 typecheck;预期所有命令成功退出,且只保留既有的 vscode companion lint warnings。

Evidence (Before & After)

Before:MCP OAuth 文档和状态提示引用 /mcp auth <server-name>,SDK 文档把 coreTools 描述为等价于 permission allow 规则,补全提示包含已移除的 auth 参数,部分 MCP OAuth 失败只给出通用错误,或者在已保存凭据不可用时静默降级,共享文本输入也依赖 Ink 内部子路径。After:OAuth 指引改为 /mcp 对话框路径,MCP 恢复错误包含文档化的下一步,已保存 token 降级会输出 warning,MCP 补全提示不再包含已移除的 auth 参数,SDK 文档区分了 coreTools 的注册级 allowlist 语义和 permissions.allow 的自动批准语义,并且共享文本输入使用公开 Ink hooks。构建证据:npm run build && npm run typecheck 在本地以 0 退出;vscode companion build 仍报告 15 个既有 lint warnings,0 个 errors。

Tested on

OS Status
🍏 macOS ✅ tested
🪟 Windows ⚠️ not tested locally; covered by PR CI
🐧 Linux ⚠️ not tested locally; covered by PR CI

Environment (optional)

Node.js v22.22.3,npm 10.9.8。

Risk & Scope

  • Main risk or tradeoff: 这次文档梳理覆盖较多交叉链接和命令引用,MCP OAuth 变更也触及认证恢复相关的错误处理,因此主要风险是存在措辞不准确或失败消息出现非预期变化。
  • Not validated / out of scope: 本地未测试 Windows 和 Linux;没有为变更后的 MCP 状态提示截取可视化 TUI 截图。
  • Breaking changes / migration notes: 没有有意引入破坏性变更或迁移要求。

Linked Issues

N/A

Update stale documentation and user-facing MCP OAuth guidance to match the current dialog-based flows, SDK permission semantics, current links, and Qwen OAuth status.

Also replace Ink internal imports with public Ink APIs for the shared text input so the workspace builds against Ink 7.

Co-authored-by: Qwen-Coder <[email protected]>
@doudouOUC
doudouOUC marked this pull request as ready for review June 22, 2026 03:06
Copilot AI review requested due to automatic review settings June 22, 2026 03:06

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@qwen-code-ci-bot

qwen-code-ci-bot commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Thanks for the PR, @doudouOUC!

Template looks good ✓

On direction: aligning docs with the current CLI behavior and improving MCP OAuth error messages is squarely within scope. Documentation drift — stale command names, broken links, wrong config keys — directly hurts users. The Ink internal-import cleanup is a real build fix (Ink no longer exports those subpaths). CHANGELOG has prior entries for MCP OAuth and docs consistency work, confirming this area is actively maintained.

On approach: the scope is large (43 files, +1412/-381), but the code changes are tightly coupled to the docs they support. The /mcp auth deprecation path, plaintext-token warning, and 401 error-message improvements all exist because the docs now point users at the /mcp dialog — without them the docs would lie. The BaseTextInput Ink cleanup is a standalone build fix that arguably belongs in its own PR, but it's small and self-contained. No scope creep beyond the stated goal.

Moving on to code review. 🔍

中文说明

感谢贡献!

模板完整 ✓

方向:文档对齐和 MCP OAuth 错误消息改进完全在项目范围内。文档漂移(过期命令名、失效链接、错误配置键)直接影响用户体验。Ink 内部导入清理是实际的构建修复(Ink 不再导出那些子路径)。CHANGELOG 中有 MCP OAuth 和文档一致性的历史记录,确认该领域在积极维护中。

方案:范围较大(43 个文件,+1412/-381),但代码变更与它们支撑的文档紧密耦合。/mcp auth 弃用路径、明文 token 警告和 401 错误消息改进都是因为文档现在指向 /mcp 对话框——没有它们文档就是错的。BaseTextInput Ink 清理是独立的构建修复,理论上可以单独提 PR,但代码量小且自包含。没有超出目标的范围蔓延。

进入代码审查 🔍

Qwen Code · qwen3.7-max

@qwen-code-ci-bot

qwen-code-ci-bot commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Code Review

Reviewed all 43 changed files. The code changes are well-structured and focused:

  • mcpCommand.ts: The legacy auth/noauth subcommand handler is clean — returns a warning message pointing users to the /mcp dialog, with the server name interpolated safely via i18n t(). The argumentHint is correctly narrowed to desc|nodesc|schema.
  • oauth-token-storage.ts: The plaintext storage warning uses a module-level didWarnPlaintextTokenStorage flag to fire exactly once per process. The try/catch around process.stderr.write is correct — stderr is best-effort, token persistence has already succeeded.
  • mcp-client.ts: The getMcpOAuthDialogInstruction helper centralizes recovery messaging. The connectToMcpServer 401 handler is substantially improved — it snapshots credentials before createTransport (whose internal getValidToken may purge them), then uses a three-state discriminator (accepted-token-rejected, unusable, missing) for accurate post-401 messaging. The duplicated SSE-OAuth-handling blocks from the old code are properly consolidated.
  • BaseTextInput.tsx: Replaces ink/dom addLayoutListener and CursorContext (both internal APIs) with public useBoxMetrics/useCursor hooks and useInsertionEffect. The extracted getAbsolutePosition and getPhysicalCursorPosition helpers are well-tested and exported for reuse.

No correctness bugs, security issues, or convention violations found. The reuse-before-new-code check passes — getMcpOAuthDialogInstruction replaces three copy-pasted error strings, and the token-state discriminator replaces duplicated 401-handling blocks.

Build & Typecheck

npm run build         → exit 0 (15 pre-existing vscode companion warnings, 0 errors)
npm run typecheck     → exit 0

Tests

packages/core:  oauth-token-storage (31), oauth-provider (27), mcp-client (89) → 147 passed
packages/cli:   mcpCommand (10), BaseTextInput (12), McpStatus (12)            → 34 passed
packages/web-shell: slashCompletion (14)                                        → 14 passed
Total: 195 tests, all passing

Real-Scenario Test

$ npm run dev -- -p 'say hello'
> @qwen-code/[email protected] dev
> node scripts/dev.js -p say hello

DEV is set to true, but the React DevTools server is not running. Start it with:
$ npx react-devtools

Hello! How can I help you today?

Dev build starts cleanly and responds normally. The /mcp auth deprecation path is interactive-only (slash command), so it's covered by the unit tests above rather than headless -p mode.

中文说明

代码审查

审查了全部 43 个变更文件。代码变更结构清晰且聚焦:

  • mcpCommand.ts:遗留 auth/noauth 子命令处理干净——返回警告消息引导用户使用 /mcp 对话框,服务器名通过 i18n t() 安全插值。argumentHint 正确收窄为 desc|nodesc|schema
  • oauth-token-storage.ts:明文存储警告使用模块级 didWarnPlaintextTokenStorage 标志,每进程仅触发一次。process.stderr.writetry/catch 正确——stderr 是尽力而为,token 持久化已成功。
  • mcp-client.tsgetMcpOAuthDialogInstruction 集中化恢复指引。connectToMcpServer 的 401 处理大幅改进——在 createTransport 前快照凭据(其内部 getValidToken 可能清除它们),然后使用三态判别器给出准确的 401 后消息。旧代码中重复的 SSE-OAuth 处理块被正确合并。
  • BaseTextInput.tsx:用公开的 useBoxMetrics/useCursor hooks 和 useInsertionEffect 替代了 ink/domaddLayoutListenerCursorContext(均为内部 API)。提取的辅助函数经过测试并导出供复用。

未发现正确性 bug、安全问题或规范违反。

构建与类型检查

构建退出 0(15 个既有 vscode companion 警告,0 个错误),类型检查退出 0。

测试

195 个测试全部通过。

真实场景测试

开发构建正常启动并响应。/mcp auth 弃用路径仅限交互模式,由上述单元测试覆盖。

Qwen Code · qwen3.7-max

@qwen-code-ci-bot

qwen-code-ci-bot commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

Stepping back to look at the whole picture: this PR solves a real problem — docs had drifted from the code, pointing users at removed commands (/mcp auth <server-name>) and wrong config keys ("theme" vs "ui.theme"). The code changes exist to make the docs true in practice, not just on paper.

My independent proposal for this problem would have been: (1) fix the docs, (2) add the /mcp auth deprecation warning, (3) improve the 401 error messages, (4) add the plaintext-token warning. That's essentially what this PR does, and it does it well. The getMcpOAuthDialogInstruction helper avoids string duplication across four error paths, and the three-state token discriminator in connectToMcpServer replaces copy-pasted 401 blocks with something maintainable.

The BaseTextInput Ink cleanup is the one piece that's tangentially related — it fixes a build break from Ink no longer exporting internal subpaths, but it's not strictly required by the docs changes. It's small (removes ~60 lines of internal-API gymnastics, replaces with ~15 lines using public hooks) and well-tested, so it's fine to ship together.

Build passes, typecheck passes, 195 tests pass, dev build runs cleanly. The PR already has CHANGES_REQUESTED from a prior round — the author has addressed the feedback and the current state looks solid.

No reservations. This is a thorough, well-motivated docs-and-consistency PR that ships the code changes needed to keep the docs honest.

中文说明

退后一步看整体:这个 PR 解决了一个真实问题——文档已经与代码脱节,指向已移除的命令(/mcp auth <server-name>)和错误的配置键("theme" vs "ui.theme")。代码变更的存在是为了让文档在实践中成立,而不仅仅是纸面上。

我对这个问题的独立方案是:(1) 修复文档,(2) 添加 /mcp auth 弃用警告,(3) 改进 401 错误消息,(4) 添加明文 token 警告。这基本上就是这个 PR 所做的,而且做得很好。getMcpOAuthDialogInstruction 避免了四个错误路径中的字符串重复,connectToMcpServer 中的三态 token 判别器用可维护的代码替代了复制粘贴的 401 块。

BaseTextInput Ink 清理是唯一与主题略有距离的部分——它修复了 Ink 不再导出内部子路径导致的构建中断,但文档变更并不严格需要它。代码量小(移除约 60 行内部 API 操作,用约 15 行公开 hooks 替代)且测试充分,一起发布没问题。

构建通过,类型检查通过,195 个测试通过,开发构建正常运行。PR 在之前的一轮中已有 CHANGES_REQUESTED——作者已处理反馈,当前状态看起来稳固。

没有顾虑。这是一个彻底的、动机明确的文档一致性 PR,发布了让文档保持准确所需的代码变更。

Qwen Code · qwen3.7-max

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, looks ready to ship. ✅

Comment thread packages/core/src/tools/mcp-client.ts Outdated
Comment thread docs/developers/daemon/00-index.md Outdated
Comment thread docs/developers/tools/mcp-server.md Outdated
Comment thread docs/users/features/mcp.md Outdated

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review Summary

Scope: 38 files, +210/-215 — documentation alignment with current CLI behavior and BaseTextInput refactor from Ink internal APIs to public APIs.

Automated checks: tsc ✅, eslint ✅, targeted tests (oauth-provider 27/27, McpStatus 12/12, slashCompletion 14/14) ✅

Overall assessment: Solid documentation audit. The docs changes accurately reflect current CLI behavior (MCP management commands, extension settings, theme system, SDK permissions, Qwen OAuth deprecation). The BaseTextInput refactor from addLayoutListener/CursorContext to useBoxMetrics/useCursor is a good move to public APIs.

Below are a few suggestions for improvement. Two are about code hygiene in a newly extracted helper, and two are about test coverage gaps introduced by the refactor.

Comment thread packages/core/src/tools/mcp-client.ts Outdated
Comment thread packages/cli/src/ui/components/BaseTextInput.tsx Outdated
Comment thread packages/sdk-typescript/src/types/types.ts Outdated
Comment thread packages/cli/src/ui/commands/mcpCommand.ts
Comment thread packages/core/src/tools/mcp-client.ts Outdated
Comment thread packages/core/src/tools/mcp-client.ts Outdated
Comment thread packages/cli/src/ui/commands/mcpCommand.test.ts
Comment thread packages/cli/src/ui/commands/mcpCommand.ts Outdated
yiliang114
yiliang114 previously approved these changes Jun 22, 2026
Comment thread packages/core/src/tools/mcp-client.ts Outdated

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review Summary

3 findings across this PR. The docs alignment and OAuth messaging refactor are solid — these comments focus on a behavioral regression in cursor cleanup, a test-coverage gap, and a docs security callout.

Comment thread packages/cli/src/ui/components/BaseTextInput.tsx Outdated
Comment thread packages/core/src/tools/mcp-client.test.ts
Comment thread docs/users/features/mcp.md
wenshao
wenshao previously approved these changes Jun 22, 2026
@wenshao

wenshao commented Jun 22, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /triage

Comment thread packages/sdk-typescript/README.md Outdated
Comment thread packages/core/src/tools/mcp-client.ts
Comment thread docs/users/extension/extension-releasing.md Outdated
@wenshao

wenshao commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /triage

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, looks ready to ship. ✅

Fix SSE OAuth credential pre-check failures by reporting token storage read errors before connecting.

Update SDK coreTools docs and extension release link text from the follow-up review.

Co-authored-by: Qwen-Coder <[email protected]>
@doudouOUC
doudouOUC dismissed stale reviews from qwen-code-ci-bot and wenshao via 5e7c3b0 June 23, 2026 03:11
Resolve BaseTextInput conflicts by keeping the public Ink cursor implementation while preserving the latest software-cursor tests from main.

Co-authored-by: Qwen-Coder <[email protected]>

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Downgraded from Approve to Comment: CI still running. Reviewing code statically; CI results not yet available.

Reviewed 43 changed files across documentation alignment, BaseTextInput Ink API migration, and MCP OAuth error messaging improvements. Build passes, all 168 targeted tests pass. Found 2 Critical issues and 1 Suggestion in new code.

Comment thread packages/core/src/tools/mcp-client.ts Outdated
Comment thread packages/core/src/mcp/oauth-token-storage.ts Outdated
Comment thread packages/core/src/tools/mcp-client.ts Outdated
Handle stderr warning failures as best-effort and keep SSE 401 OAuth guidance when credential re-read fails.

Co-authored-by: Qwen-Coder <[email protected]>
Comment thread packages/core/src/tools/mcp-client.ts Outdated
Comment thread packages/cli/src/ui/components/BaseTextInput.test.tsx
Avoid blocking SSE MCP connections when the diagnostic credential pre-read fails, and cover BaseTextInput absolute-position edge cases.

Co-authored-by: Qwen-Coder <[email protected]>
Comment thread packages/core/src/tools/mcp-client.ts Outdated

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] handleAutomaticOAuth return-false path (line ~1531) throws "Failed to handle automatic OAuth for server '<name>'" — a generic, unactionable message. Inside handleAutomaticOAuth, the /mcp dialog instruction is correctly logged via debugLogger.error, but that log is invisible without debug mode enabled. The thrown error should also include getMcpOAuthDialogInstruction(...) so callers and error-monitoring pipelines get actionable guidance.

— qwen3.7-max via Qwen Code /review

Comment thread packages/core/src/tools/mcp-client.ts
Comment thread packages/core/src/tools/mcp-client.ts

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Downgraded from Approve to Comment: CI still running.

[Suggestion] In the no-www-authenticate 401 handler's else-branch (when hasNetworkTransport(mcpServerConfig) is false, mcp-client.ts:1669), the error message uses "Please configure OAuth or check server settings" without getMcpOAuthDialogInstruction(). Every other 401 error path updated by this PR includes the /mcp dialog instruction. This branch is old unchanged code, so it was missed during the sweep. Consider adding the dialog instruction for consistency.

— qwen3.7-max via Qwen Code /review

Comment thread packages/core/src/tools/mcp-client.test.ts
Comment thread packages/cli/src/ui/components/BaseTextInput.tsx Outdated
@doudouOUC doudouOUC changed the title docs: Align docs with current CLI behavior fix(core): Align MCP OAuth guidance and docs Jun 23, 2026
@wenshao

wenshao commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

✅ Maintainer local verification — real build, typecheck, 190 unit tests, mutation test

Verified PR #5589 at head 8732cd720 in an isolated worktree with a fresh npm ci (Node 22.22.2). This is a real build of the whole workspace, not a diff read. My earlier Ink-import blocker is now fixed. Summary first, evidence below.

Verdict: safe to merge. Build + typecheck exit 0, all touched suites pass (190 tests), and a mutation test proves the substantive code changes are well-guarded. The open CHANGES_REQUESTED items are AI-reviewer [Suggestion]s, not correctness blockers (assessed individually below). CI is already green on macOS/Ubuntu/Windows; this is an independent local cross-check.

1. My prior blocker (the ink/dom import) — RESOLVED ✅

Earlier I requested changes because BaseTextInput.tsx imported Ink internal subpaths not exported by the current Ink package (a build/runtime break). Current head migrates to the public Ink 7 API:

- import { addLayoutListener, type DOMElement } from 'ink/dom';
- import CursorContext from 'ink/components/CursorContext';
+ import { Box, Text, type DOMElement, useBoxMetrics, useCursor } from 'ink';

Confirmed [email protected] exports all three from its main entry (build/index.d.ts: useCursor, useBoxMetrics, export type { DOMElement }). No ink/ subpath imports remain anywhere in the file. The whole-workspace typecheck passes, and — as a bonus — the mutation test below shows the base BaseTextInput.tsx no longer even loads against the installed Ink 7, confirming the migration was necessary, not cosmetic.

2. Build + typecheck — exit 0 (the PR's central claim)

step command result
build npm run build (all workspaces) BUILD_EXIT=0
typecheck npm run typecheck (all workspaces) TYPECHECK_EXIT=0

3. Unit tests — 190 passed across the 7 touched suites

package suites tests
core mcp-client, oauth-token-storage, oauth-provider ✅ 142
cli mcpCommand, BaseTextInput, McpStatus ✅ 34
web-shell slashCompletion ✅ 14

4. Mutation test — substantive changes are non-vacuous

Reverted the 6 production files to base (31dcb6e32), kept the PR's test files, re-ran the suites:

suite group result with base source what it guards
core (mcp-client + oauth-token-storage) 17 failed / 98 passed OAuth recovery messages, token-state branches, plaintext warning
cli (mcpCommand + BaseTextInput + McpStatus) 12 failed / 22 passed legacy auth/noauth deprecation, physical-cursor migration, status-tip snapshot
web-shell (slashCompletion) ⚠️ 0 failed see note

Restoring the PR source → all green again. 29 guard tests flip with the fix removed.

Honest note on web-shell: reverting localCommands.ts did not fail slashCompletion.test.ts, because that test builds its own mock command list and asserts the completion logic, not the argumentHint string in localCommands.ts. So the one-line 'desc|nodesc|schema|auth|noauth''desc|nodesc|schema' change is cosmetic and not independently asserted. Low risk; just flagging it accurately.

5. Code-change correctness highlights

  • OAuth 401 recovery (mcp-client.ts) snapshots hadStoredSseOAuthCredentials before createTransport, because getValidToken inside transport creation may refresh/purge tokens — so the later 401 handler can correctly distinguish "had credentials, now unusable" (unusable) from "never configured" (missing). All getCredentials calls are now try/caught. Solid handling of a real race.
  • Plaintext-token warning (oauth-token-storage.ts) fires in both setCredentials (L126) and deleteCredentials (L207, the rewrite path) — this addresses the earlier review note that deleteCredentials rewrote the plaintext file silently. One-shot per process, best-effort stderr.
  • Legacy /mcp auth is gracefully deprecated, not silently dropped: mcpCommand.ts returns a warning message redirecting to the /mcp dialog.
  • The new guidance is factually accurate — it points headless/SDK users to qwen mcp add --oauth-*, and those flags genuinely exist (--oauth-client-id/-secret/-redirect-uri/-authorization-url/-token-url/-scopes in commands/mcp/add.ts).

6. Documentation consistency

  • All 200 relative links across the 29 changed docs resolve (with .md/index/README resolution). No broken local links introduced.
  • /mcp auth is removed from every user-facing doc, status tip, completion hint, and error message. The only 2 remaining references live in docs/design/f2-mcp-transport-pool.md — an internal design doc not touched by this PR and out of scope.

7. Open CHANGES_REQUESTED threads — both non-blocking

  • BaseTextInput.tsx:129 PhysicalCursorState not exported — the bot labels it [Suggestion]; the function is an internal (test-only) helper and typecheck is clean, so this is a stylistic nit, not a TS error or blocker.
  • mcp-client.test.ts:412 coverage gaps[Suggestion] to add the OAuth discovery happy-path and the handleAutomaticOAuth fallback-branch tests. The PR already covers the error paths (its actual subject) with 12+ new tests; these are nice-to-have additions, not correctness blockers.

The active CHANGES_REQUESTED is from the AI qwen-code-ci-bot with [Suggestion]-level items; the one substantive blocker (Ink) is fixed and CI is green on all three platforms.

Risk notes (low)

  • Broad doc sweep + OAuth error-message rewrites; risk is wording, not behavior. Error paths are now actionable and test-covered.
  • Cosmetic web-shell hint string is untested (see §4 note).
中文版(完整对应)

✅ 维护者本地验证 —— 真实构建、typecheck、190 个单测、变异测试

在 head 8732cd720 的独立 worktree 内全新 npm ci(Node 22.22.2)验证 PR #5589。这是对整个工作区的真实构建,非看 diff。我之前的 Ink 导入 blocker 现已修复。 先结论,后证据。

结论:可以安全合并。 build + typecheck 均 exit 0,所有改动套件通过(190 测试),变异测试证明实质性代码改动有测试守护。当前 CHANGES_REQUESTED 的未决项是 AI reviewer 的 [Suggestion],非正确性 blocker(下文逐条评估)。CI 三平台已全绿,本报告为独立本地交叉核验。

1. 我之前的 blocker(ink/dom 导入)—— 已解决 ✅

我此前 request changes 是因为 BaseTextInput.tsx 导入了当前 Ink 包未导出的内部子路径(构建/运行时破坏)。当前 head 已迁移到 Ink 7 公开 API:

- import { addLayoutListener, type DOMElement } from 'ink/dom';
- import CursorContext from 'ink/components/CursorContext';
+ import { Box, Text, type DOMElement, useBoxMetrics, useCursor } from 'ink';

已确认 [email protected] 主入口导出全部三者(build/index.d.ts:useCursoruseBoxMetricsexport type { DOMElement })。文件中不再有任何 ink/ 子路径导入。整工作区 typecheck 通过;且作为旁证,下方变异测试显示 baseBaseTextInput.tsx 在已安装的 Ink 7 下甚至无法加载,证明该迁移是必需的、非装饰性。

2. 构建 + typecheck —— exit 0(PR 中心claim)

步骤 命令 结果
build npm run build(所有 workspace) BUILD_EXIT=0
typecheck npm run typecheck(所有 workspace) TYPECHECK_EXIT=0

3. 单元测试 —— 7 个改动套件 190 通过

套件 测试数
core mcp-client、oauth-token-storage、oauth-provider ✅ 142
cli mcpCommand、BaseTextInput、McpStatus ✅ 34
web-shell slashCompletion ✅ 14

4. 变异测试 —— 实质改动非空过

把 6 个生产文件回退到 base(31dcb6e32),保留 PR 测试文件,重跑套件:

套件组 base 源码下结果 守护内容
core(mcp-client + oauth-token-storage) 17 失败 / 98 通过 OAuth 恢复消息、token 状态分支、明文 warning
cli(mcpCommand + BaseTextInput + McpStatus) 12 失败 / 22 通过 legacy auth/noauth 弃用、物理光标迁移、状态提示快照
web-shell(slashCompletion) ⚠️ 0 失败 见下注

恢复 PR 源码 → 重新全绿。移除修复后共 29 个 guard 测试翻转。

关于 web-shell 的诚实说明: 回退 localCommands.ts 没有slashCompletion.test.ts 失败,因为该测试自建 mock 命令列表、断言的是补全逻辑而非 localCommands.ts 里的 argumentHint 串。所以那一行 'desc|nodesc|schema|auth|noauth''desc|nodesc|schema' 的改动是装饰性的、未被独立断言。风险低,如实标注。

5. 代码改动正确性要点

  • OAuth 401 恢复(mcp-client.ts)createTransport 之前快照 hadStoredSseOAuthCredentials,因为 transport 创建内部的 getValidToken 可能刷新/清除 token —— 这样后续 401 处理才能正确区分*"曾有凭据、现不可用"(unusable)与"从未配置"*(missing)。所有 getCredentials 调用现已 try/catch。对一个真实 race 的稳妥处理。
  • 明文 token warning(oauth-token-storage.ts)setCredentials(L126)与 deleteCredentials(L207,重写路径)两处都触发 —— 回应了早先 review 关于 deleteCredentials 静默重写明文文件的意见。进程内一次性,stderr 尽力而为。
  • legacy /mcp auth 是优雅弃用而非静默丢弃:mcpCommand.ts 返回 warning 消息引导到 /mcp 对话框。
  • 新指引事实准确 —— 它指引 headless/SDK 用户使用 qwen mcp add --oauth-*,而这些 flag 确实存在(commands/mcp/add.ts 中的 --oauth-client-id/-secret/-redirect-uri/-authorization-url/-token-url/-scopes)。

6. 文档一致性

  • 29 个改动文档中的全部 200 个相对链接均可解析(含 .md/index/README 解析)。未引入断链。
  • /mcp auth 已从所有面向用户的文档、状态提示、补全提示、错误消息中移除。仅存的 2 处引用在 docs/design/f2-mcp-transport-pool.md —— 一个本 PR 未改动、超出范围的内部设计文档。

7. 未决 CHANGES_REQUESTED 线程 —— 均非阻塞

  • BaseTextInput.tsx:129 PhysicalCursorState 未导出 —— bot 自标 [Suggestion];该函数是内部(仅测试用)helper,typecheck 干净,所以是风格 nit, TS 错误或 blocker。
  • mcp-client.test.ts:412 覆盖缺口 —— [Suggestion] 建议补 OAuth discovery happy 路径与 handleAutomaticOAuth 回退分支测试。PR 已用 12+ 新测试覆盖错误路径(其真正主题);这些是锦上添花,非正确性 blocker。

当前 CHANGES_REQUESTED 来自 AI qwen-code-ci-bot、均为 [Suggestion] 级;唯一实质 blocker(Ink)已修,CI 三平台全绿。

风险评估(低)

  • 大范围文档梳理 + OAuth 错误消息重写;风险在措辞而非行为。错误路径现已可执行且有测试覆盖。
  • web-shell 装饰性提示串未被测试(见 §4 注)。

Comment thread packages/cli/src/ui/components/BaseTextInput.tsx Outdated
Comment thread packages/core/src/tools/mcp-client.ts Outdated
Comment thread packages/core/src/tools/mcp-client.ts Outdated
Comment thread docs/developers/daemon/00-index.md

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Qwen Code Review — PR #5589

Verdict: COMMENT (downgraded from Approve due to CI failure: Test (macos-latest, Node 22.x))

Summary

This PR refactors MCP OAuth error handling with a tri-state token classification (SseOAuth401TokenState), centralizes OAuth recovery guidance via getMcpOAuthDialogInstruction(), removes legacy auth/noauth arguments from the /mcp command, and migrates BaseTextInput from Ink internal APIs (addLayoutListener, CursorContext, ink/dom) to public APIs (useBoxMetrics, useCursor, useInsertionEffect).

Deterministic Analysis

  • TypeScript (tsc): 17 findings — all verified as pre-existing on main (missing .js extensions in test imports). 0 new type errors.
  • ESLint: 0 findings.
  • Build: npm run build
  • Tests: 142 passed (22 CLI + 120 core). ✅

Findings

No new high-confidence Critical or Suggestion findings beyond the 43 existing inline comments (29 stale from prior commits, 14 on current HEAD). The existing comments already cover:

  • useInsertionEffect cleanup/setup ordering in BaseTextInput
  • warnPlaintextTokenStorage timing (called after atomicWriteFile succeeds)
  • getCredentials error handling in pre-transport OAuth check
  • PhysicalCursorState not exported but used in public API
  • Hardcoded English strings in mcpCommand bypassing i18n
  • hadStoredSseOAuthCredentials snapshot semantics
  • Test coverage gaps in OAuth error paths

Downgrade Reason

CI check Test (macos-latest, Node 22.x) is failing. Once that is resolved, this review would be an Approve.


Model: qwen3.7-max · Commit: 31b649ba

@wenshao

wenshao commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

@qwen-code /triage

@wenshao

wenshao commented Jun 23, 2026

Copy link
Copy Markdown
Collaborator

Maintainer local verification — real build + tests + docs link/consistency checks

I verified this PR locally on the latest head (31b649bae): a clean build/typecheck, the focused test suites, a real doc-link resolver over the changed docs, and doc↔code consistency checks. Verdict: mergeable — the docs sweep is accurate, the MCP OAuth error refactor is sound, and tests pass. One item is worth addressing before merge: the BaseTextInput.tsx change is justified as a build fix, but that justification does not hold at the pinned Ink version (details below).

Environment

  • Clean worktree at PR head 31b649bae, fresh npm ci + full build; tsc -p packages/cli/tsconfig.json and prettier/eslint on changed files; a doc-link resolver; a virtual git merge-tree against current origin/main.

Results

Check Result Detail
Build + CLI typecheck (PR head) tsc --noEmit exit 0, 0 errors
Focused tests 195 pass — core MCP 147 (mcp-client 89, oauth-token-storage 31, oauth-provider 27), cli 34 (mcpCommand/BaseTextInput/McpStatus), web-shell slashCompletion 14
Doc local links resolve 201/201 local links in the 29 changed docs resolve (with .md/index fallback) — no dangling links
/mcp auth removed from code 0 references in non-test src; new guidance points to the /mcp dialog
New guidance references real commands qwen mcp add --oauth-* flags exist (commands/mcp/add.ts); /mcp dialog exists
SDK coreTools doc accuracy ProcessTransport.ts:309 pushes --core-tools — the rewritten "legacy --core-tools allowlist" wording is correct
prettier / eslint (changed files) clean (matches green CI)
Virtual merge into current origin/main conflict-free and coherent — preserves main's recent BaseTextInput edits (#5772 background-fill removal), no stale imports

⚠️ The BaseTextInput.tsx change is a refactor, not a build fix — the stated rationale doesn't hold

The PR description says the Ink change is required because "the previous internal subpath imports are no longer exported by the current Ink package, which breaks workspace builds." Against the repo's pinned [email protected] (unchanged on both the merge-base and current main), that is not the case:

  • [email protected] still exports both old symbols at runtime and at the type level: ink/dom exports addLayoutListener (declared in build/dom.d.ts:60), and ink/components/CursorContext exports the default CursorContext context (build/components/CursorContext.d.ts). Both subpaths are in Ink's exports map.
  • origin/main's BaseTextInput.tsx still uses exactly these old imports and ships green (released as v0.19.1).
  • I restored origin/main's BaseTextInput.tsx into this worktree and typechecked it against the installed [email protected]: zero ink/dom / addLayoutListener / CursorContext errors (the only errors were the PR's new test referencing the new exports, which is expected when mixing old source with the new test).

So migrating off the internal subpaths to the public useBoxMetrics / useCursor API is a reasonable maintainability improvement in its own right (internal subpaths can break on a future Ink bump), but it is not needed to keep the build working today, and it's somewhat out of scope for a docs-alignment PR. It also rewrites the IME physical-cursor-positioning path (layout-listener → render-time compute + useInsertionEffect); the new pure helpers are unit-tested, but the render-cycle timing isn't exercised by the tests. The PR's own code typechecks and the merge stays coherent, so this isn't a correctness blocker — but I'd suggest either splitting it into its own change (with an accurate "move off internal Ink subpaths" rationale and a quick real-terminal IME cursor check) or correcting the justification here.

Minor / non-blocking

  • Two /mcp auth <name> references remain in docs/design/f2-mcp-transport-pool.md (a historical design doc, not user-facing). The user-doc sweep didn't touch it; optional follow-up for full consistency.
  • oauth-token-storage.ts writes the new plaintext-storage warning straight to process.stderr (once per process). Fine functionally, but raw stderr writes can interleave with the Ink TUI — routing it through the app's notice channel would be cleaner. Also slightly beyond the PR's stated scope.
  • The branch is 19 commits behind origin/main; the merge is verified clean and coherent, so this is hygiene only — a rebase keeps CI reflecting current main.

What's solid

The MCP OAuth error refactor is well done: a single getMcpOAuthDialogInstruction() helper replaces every stale /mcp auth string with /mcp-dialog + qwen mcp add --oauth-* guidance (both verified to exist); a 3-state token machine (accepted-token-rejected / unusable / missing) gives accurate failure messaging; a pre-createTransport credential snapshot correctly distinguishes "had credentials, now unusable" from "never configured"; and credential/discovery reads are hardened with try/catch. Docs and SDK wording now match the code, links resolve, and all focused tests pass.

Verdict

Mergeable. The substance (docs accuracy, MCP OAuth recovery guidance, completions) is correct and verified. Recommend addressing the one item — split or re-justify the BaseTextInput.tsx Ink change (it's a refactor, not the build fix the description claims) — and rebasing onto current main.

中文版(点击展开)

维护者本地验证 —— 真实构建 + 测试 + 文档链接/一致性检查

我在最新 head(31b649bae)上做了本地验证:干净的 build/typecheck、聚焦测试套件、对改动文档跑真实链接解析器,以及文档↔代码一致性检查。结论:可以合并 —— 文档梳理准确,MCP OAuth 错误重构扎实,测试通过。合并前有一项值得处理:BaseTextInput.tsx 的改动被说成是构建修复,但在锁定的 Ink 版本下这个理由不成立(详见下文)。

环境

  • PR head 31b649bae 的干净 worktree,全新 npm ci + 完整构建;对改动文件跑 tsc -p packages/cli/tsconfig.jsonprettier/eslint;一个文档链接解析器;用 git merge-tree 对当前 origin/main 做虚拟合并。

结果

检查项 结果 说明
构建 + CLI typecheck(PR head) tsc --noEmit 退出 0,0 错误
聚焦测试 195 通过 —— core MCP 147(mcp-client 89、oauth-token-storage 31、oauth-provider 27),cli 34(mcpCommand/BaseTextInput/McpStatus),web-shell slashCompletion 14
文档本地链接可解析 29 个改动文档里 201/201 本地链接均可解析(带 .md/index 回退)—— 无悬空链接
代码中 /mcp auth 已移除 非测试 src 中 0 处引用;新指引指向 /mcp 对话框
新指引引用的命令真实存在 qwen mcp add --oauth-* 选项存在(commands/mcp/add.ts);/mcp 对话框存在
SDK coreTools 文档准确性 ProcessTransport.ts:309 推送 --core-tools —— 改写后的"legacy --core-tools allowlist"措辞正确
改动文件 prettier / eslint 干净(与绿色 CI 一致)
虚拟合并进当前 origin/main 无冲突且自洽 —— 保留了 main 近期对 BaseTextInput 的改动(#5772 移除背景填充),无残留 import

⚠️ BaseTextInput.tsx 是重构,不是构建修复 —— 所述理由不成立

PR 描述称 Ink 改动是必须的,因为"之前的内部子路径导入已不再被当前 Ink 包导出,会破坏工作区构建"。但对仓库锁定的 [email protected](merge-base 与当前 main 都是这个版本,未变)来说并非如此:

  • [email protected] 仍然在运行时和类型层面导出这两个旧符号:ink/dom 导出 addLayoutListener(声明在 build/dom.d.ts:60),ink/components/CursorContext 导出默认 CursorContextbuild/components/CursorContext.d.ts)。两个子路径都在 Ink 的 exports map 里。
  • origin/mainBaseTextInput.tsx 至今仍在用这些旧 import,且正常发布(v0.19.1)。
  • 我把 origin/mainBaseTextInput.tsx 还原进本 worktree,对安装的 [email protected] 做 typecheck: ink/dom / addLayoutListener / CursorContext 报错(仅有的报错是 PR 的新测试引用了新导出,这在"旧源码 + 新测试"混搭时是预期的)。

所以迁移到公共的 useBoxMetrics / useCursor API 本身是合理的可维护性改进(内部子路径在未来 Ink 升级时可能失效),但它并非今天维持构建所必需,且对一个文档对齐 PR 来说略微超范围。它还重写了 IME 物理光标定位路径(layout-listener → 渲染期计算 + useInsertionEffect);新的纯函数有单测,但渲染周期时序没有被测试覆盖。PR 自身代码能 typecheck、合并也自洽,所以这不是正确性阻断 —— 但我建议要么把它拆成独立改动(配上准确的"迁移出 Ink 内部子路径"理由 + 真实终端里快速验证 IME 光标),要么在此处修正理由。

次要 / 非阻断

  • docs/design/f2-mcp-transport-pool.md(历史设计文档,非面向用户)里还剩 2 处 /mcp auth <name> 引用。用户文档梳理没碰它;可作为完整一致性的可选后续。
  • oauth-token-storage.ts 把新的明文存储 warning 直接写到 process.stderr(每进程一次)。功能上没问题,但裸写 stderr 可能与 Ink TUI 交错 —— 走应用的通知通道更干净。这点也略超 PR 所述范围。
  • 分支落后 origin/main 19 个提交;合并已验证干净自洽,所以纯属卫生 —— rebase 可让 CI 反映当前 main

扎实的部分

MCP OAuth 错误重构做得不错:单个 getMcpOAuthDialogInstruction() 帮助函数把每一处过期的 /mcp auth 字符串替换为 /mcp 对话框 + qwen mcp add --oauth-* 指引(两者均已验证存在);3 态 token 状态机(accepted-token-rejected / unusable / missing)给出准确的失败消息;createTransport 前的凭据快照正确区分"曾有凭据、现已不可用"与"从未配置";凭据/发现读取用 try/catch 加固。文档与 SDK 措辞现在与代码一致,链接可解析,全部聚焦测试通过。

结论

可以合并。 实质内容(文档准确性、MCP OAuth 恢复指引、补全)正确且已验证。建议处理这一项 —— 把 BaseTextInput.tsx 的 Ink 改动拆出或修正理由(它是重构,而非描述所称的构建修复)—— 并 rebase 到当前 main

@qwen-code-ci-bot qwen-code-ci-bot left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, looks ready to ship. ✅

@wenshao
wenshao merged commit a234860 into QwenLM:main Jun 23, 2026
34 of 35 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants