feat(serve): add workspace MCP management - #6954
Conversation
fcab051 to
eb228d1
Compare
|
Please do not rebase or force-push to an active PR as it invalidates existing review comments. Note for future reference, the bots always squash all changes into a single commit automatically as part of the integration. 中文请勿对活跃的 PR 执行 rebase 或 force-push,因为这会使已有的评审评论失效。另外,供日后参考:作为集成流程的一部分,机器人始终会自动将所有改动压缩(squash)为单个提交。 |
🖼️ web-shell visual previewAuto-rendered from this PR head Screenshots · light / dark
Full-resolution recordings (.webm) are attached to the workflow run. — Qwen Code · web-shell visuals |
|
Thanks for the PR @ytahdn! Template looks good — all required sections present, bilingual body included, test plan concrete. ✓ Problem (observed, not theoretical): the PR addresses a real lifecycle-coupling issue — MCP management previously depended on a live chat session, which could lose discovery state and fail operations when no session existed. The PR body explains the failure modes clearly and the reviewer test plan covers the before/after scenarios. No before/after reproduction is attached, but the failure mode is an architectural property of the previous session-scoped design rather than a specific bug path, so the framing is reasonable. Direction: aligned. Workspace-level MCP management continues the multi-workspace daemon direction that the recent PRs in this area (runtime workspace removal #6745, persisted workspace registrations #6716, channel workers grouped by workspace #6635, workspace-qualified ACP transport #6621) have been building toward. Decoupling MCP administration from session lifecycle is the natural next step. CHANGELOG has no direct prior MCP-management entry, but the workspace/daemon cluster of recent work makes the area clearly relevant. Size:
Approach:
Re-run note (a78cd5e): two follow-up commits since the previous review at Moving on to code review and real-scenario testing. 🔍 中文说明感谢 @ytahdn 的贡献! 模板完整 ✓ —— 所有章节齐全,含双语正文,测试计划具体。 问题(已观察到,非理论性): PR 解决一个真实的生命周期耦合问题——此前 MCP 管理依赖存活聊天 session,可能在无 session 时丢失发现状态、操作失败。正文对失败模式的描述清楚,reviewer 测试计划覆盖 before/after 场景。未附复现,但该失败模式是此前 session-scoped 设计的架构属性,而非具体 bug 路径,所以 framing 合理。 方向: 对齐。工作区级 MCP 管理延续了近期多工作区 daemon 方向(运行时工作区移除 #6745、持久化工作区注册 #6716、按工作区分组的 channel worker #6635、工作区限定的 ACP 传输 #6621)。把 MCP 管理从 session 生命周期中解耦是自然的下一步。CHANGELOG 中没有直接对应的 MCP 管理条目,但该领域与近期的 workspace/daemon 集群明显相关。 规模:
方案:
Re-run 说明(a78cd5e6b): 自上次 review( 接下来进入代码审查与真实场景测试。🔍 — Qwen Code · qwen3.7-max Reviewed at |
Code review (re-run on a78cd5e)Two follow-up commits landed since the previous review at
All three fixes are minimal, targeted, and directly address findings from the previous review. No scope creep or drive-by changes. Previous Stage 2 concerns — status:
Core path review: unchanged — Real-scenario testingAll affected test suites pass on the current HEAD ( I did not run a before/after tmux drive of the live web-shell MCP management UI — that requires a running daemon with OAuth-configured MCP servers, which is outside what's feasible in this CI environment. The unit-test evidence covers the correctness surface (the previous failure was a unit-level assertion mismatch, now resolved), and the PR body already flags that Web Shell UI manual testing was not run on Linux/Windows. 中文说明代码审查(在 a78cd5e 上 re-run)自上次 review(
三个修复都是最小化、有针对性的,直接对应上次 review 的发现。没有范围蔓延或顺手改动。 上次 Stage 2 关注——状态:
核心路径审查: 不变—— 真实场景测试所有受影响的测试套件在当前 HEAD( 我没有在 tmux 中做 Web Shell MCP 管理 UI 的 before/after 实操驱动——那需要带 OAuth 配置的 MCP 服务器运行中的 daemon,超出 CI 环境能力。单元测试证据覆盖了正确性面(此前的失败是单元级断言不匹配,现已修复),PR 正文已标记 Linux/Windows 上未进行 Web Shell UI 手动测试。 — Qwen Code · qwen3.7-max Reviewed at |
|
Confidence: 4/5 — solid across every stage; the one correctness blocker from the previous review is fixed, all 1,838 tests pass, and three non-blocking hygiene items remain for future cleanup. Stepping back from the stages, my honest read on this re-run:
Approving. The architecture earns its lines, the tests pass, the follow-up commits are clean, and the remaining concerns are cleanup items for future iterations. 中文说明置信度:4/5 —— 各阶段扎实;上次 review 的唯一正确性阻断已修复,1,838 个测试全部通过,三个不阻断的代码卫生项留待后续清理。 从所有阶段退一步看,这次 re-run 的真实判断:
Approve。架构赚到了它的行数,测试通过,跟进提交干净,剩余关注是未来迭代的清理项。 — Qwen Code · qwen3.7-max Reviewed at |
Code review —
|
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Not reviewed: reverse audit — worktree was cleaned up during review, reverse audit could not run.
Not reviewed: build-and-test — npm ci timed out in worktree; build and test results unavailable.
Not reviewed: coverage — could not read the agents' transcripts (no subagent transcripts at /home/github-runner/actions-runner-15/_work/_temp/qwen-home/projects/-home-github-runner-actions-runner-15--work-qwen-code-qwen-code/subagents/80673a63-3250-4061-b1d3-097ec754954b (ENOENT: no such file or directory, scandir '/home/github-runner/actions-runner-15/_work/_temp/qwen-home/projects/-home-github-runner-actions-runner-15--work-qwen-code-qwen-code/subagents/80673a63-3250-4061-b1d3-097ec754954b'). The harness writes one per agent; if there are none, either no agents ran or the harness could not write them.), so this run cannot show that any of the diff was read.
— qwen3.7-max via Qwen Code /review
364a308 to
ed9ea7f
Compare
|
Qwen Code review did not complete successfully. Qwen review exited with status 1. See workflow logs. |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
Reviewed — no blockers. Suggestions are inline. 1 Suggestion-level finding(s) could not be anchored to the diff; see the terminal output.
— qwen3.7-max via Qwen Code /review
|
Review triage for head a78cd5e: The latest automated review reports no blockers. This PR has already gone through well over five review rounds, so per the repository review-round policy this round only landed correctness-blocking fixes and records remaining Suggestions for follow-up instead of widening the PR again. Fixed in a78cd5e:
Rejected as inconsistent with the agreed product behavior:
Deferred to follow-up work:
All required CI checks are green. The remaining merge gate is maintainer review/decision. |
|
@qwen-code /triage |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
|
@qwen-code /resolve |
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
Qwen Code resolved the merge conflicts and pushed the branch update. Merge Conflict Resolution Summary — PR #6954Base branch
Conflicted file
Conflict analysisBoth sides added independent private fields to the HEAD (PR branch — feat/web-shell-mcp-page): Added three workspace MCP discovery fields plus two origin/main: Added one ResolutionKept both sets of fields. They are orthogonal features on the same class with no semantic interaction. Ordering: PR's MCP fields first, then main's Verified all field names are referenced beyond their declarations (10, 19, and 5 occurrences respectively), confirming neither side is dead code. Commit
|
✅ Local verification report — workspace MCP managementMaintainer-run local build + real test verification of this PR, done in an isolated git worktree at the current PR head
Test results (all green at
|
| Package · suite | Result |
|---|---|
core · mcp-client-manager.test.ts (incl. new getServerStatus) |
113 passed |
cli · acp-integration/acpAgent.test.ts (workspace-MCP ops) |
249 passed |
cli · serve/routes/workspace-settings.test.ts + workspace-service/facade.test.ts |
95 passed |
cli · serve/server.test.ts (incl. new /workspace/mcp/* routes ×56) |
683 passed, 51 pre-existing¹ |
acp-bridge · bridge.test.ts + status |
403 passed |
sdk-typescript · DaemonClient + acpRouteTable + daemonEvents + DaemonSessionClient |
524 passed |
webui · workspace/actions.test.ts + DaemonWorkspaceProvider.test.tsx |
24 passed |
web-shell · App.test.tsx + ExtensionsManagerPage.test.tsx |
123 passed |
≈ 2,214 tests passing across the changed surface.
¹ The 51 server.test.ts failures are pre-existing and environmental, not caused by this PR. Controlled experiment (same machine, same node_modules): the failing set is byte-identical between the PR and current origin/main.
| passed | failed | total | |
|---|---|---|---|
PR fdfcbf45a |
683 | 51 | 734 |
origin/main ad65ba3bd |
688 | 51 | 739 |
diff of the two failing-name sets ⇒ identical. They are all unrelated routes (POST /session returns 500 on this box, etc.) that fail on a clean main checkout too. The PR adds new passing tests and regresses nothing.
Typecheck (all tsc --noEmit clean at fdfcbf45a, deps built in dependency order)
sdk-typescript ✅ · acp-bridge ✅ · webui ✅ · web-shell ✅ · core build ✅
Note on the cli package typecheck (environmental, not a PR defect)
Raw cli tsc --noEmit inside the symlinked verification worktree emits false cross-package "property does not exist" errors because tsc resolves some @qwen-code/acp-bridge / @qwen-code/sdk subpath types against composite .d.ts declarations rather than the source paths map. This is not PR-specific:
- current
origin/mainemits 52 such errors in the identical setup; the PR emits 72 (31 shared). - the 13-error PR delta all references symbols this PR adds and that are present in source — verified directly:
AcpSessionBridge.initializeWorkspaceMcp/reloadWorkspaceMcp(bridgeTypes.ts:861,864),manageMcpServer(action: 'approve' | …)(bridgeTypes.ts:1171), andServeWorkspaceMcpServerStatus.{configOrigin,approvalState,authenticationState,removable,…}(status.ts:220). - the packages that define those symbols (
acp-bridge,sdk-typescript) typecheck clean.
CI's dependency-ordered build resolves these; the PR's own CI typechecks pass.
UI — real render of the new McpManagerPage
The PR flagged Web Shell UI as not automation-tested. I rendered the real McpManagerPage component in a standalone Vite harness (real globals.css Tailwind v4 + shadcn tokens, real i18n; only the useMcp/useSettings daemon hooks mocked) and drove it with Playwright over representative multi-state fixtures (connected · needs-approval · OAuth-authenticating · disabled · extension-provided · disconnected-with-error). Zero console/page errors across all interactions.
Server list — light & dark
| Light | Dark |
|---|---|
![]() |
![]() |
Source filter → Extension (narrows to the extension-provided server; extension servers are visible but not individually removable — matches Test Plan #3)
Server detail — Basic Information & Tools browser (drill-down loads tools/resources on demand; invalid tool flagged Blocked)
| Overview | Tools |
|---|---|
![]() |
![]() |
Add MCP Server dialog (name / description / scope select / JSON config — light & dark, via Radix portal)
| Light | Dark |
|---|---|
![]() |
![]() |
Method
- Isolated
git worktreedetached atfdfcbf45a;node_modulessymlinked from a built checkout; workspace deps resolve to source via each package'svitest/tsconfigpathsaliases. server.test.tsbaseline via a second worktree pinned toorigin/mainad65ba3bd, same environment.- Screenshots: real
McpManagerPagein a Vite dev harness + Playwright (deviceScaleFactor: 2), light & dark.
Verdict
LGTM from a local-verification standpoint. Backend routes, secret redaction/restore, workspace-scoped MCP lifecycle, SDK typing, and the new Web Shell UI all behave correctly and are covered by green suites; no regression against current main. The only caveat is the environmental cli raw-tsc noise documented above, which CI does not hit.
🇨🇳 中文版本(点击展开)
✅ 本地验证报告 —— 工作区 MCP 管理
以维护者身份对本 PR 做了本地构建 + 真实测试验证:在隔离的 git worktree 中检出当前 PR HEAD fdfcbf45a,并与当前 origin/main(ad65ba3bd)做对照基线。PR 涉及的所有包测试套件全部通过,未引入任何回归;同时对新增的 McpManagerPage 做了端到端真实渲染(真实 Tailwind/shadcn + i18n,仅 mock daemon hooks),截图见下。
验证过程中 HEAD 从
a78cd5e6b前进到fdfcbf45a(一次main合并)。我已在fdfcbf45a重跑了全部验证。PR 自身的 MCP 文件(workspace-mcp-control.ts、mcp-server-secrets.ts、workspace-settings.ts、mcp-client-manager.ts、McpManagerPage.tsx、PluginManagerPage.tsx、actions.ts、useDaemonMcp.ts)在两个 HEAD 下逐字节相同,合并仅带入了无关的main内容。
测试结果(fdfcbf45a 全绿)
| 包 · 套件 | 结果 |
|---|---|
core · mcp-client-manager.test.ts(含新增 getServerStatus) |
113 通过 |
cli · acp-integration/acpAgent.test.ts(工作区 MCP 操作) |
249 通过 |
cli · serve/routes/workspace-settings.test.ts + workspace-service/facade.test.ts |
95 通过 |
cli · serve/server.test.ts(含新增 /workspace/mcp/* 路由 ×56) |
683 通过,51 为既有失败¹ |
acp-bridge · bridge.test.ts + status |
403 通过 |
sdk-typescript · DaemonClient + acpRouteTable + daemonEvents + DaemonSessionClient |
524 通过 |
webui · workspace/actions.test.ts + DaemonWorkspaceProvider.test.tsx |
24 通过 |
web-shell · App.test.tsx + ExtensionsManagerPage.test.tsx |
123 通过 |
改动面上 约 2,214 条测试通过。
¹ server.test.ts 的 51 条失败是既有的、环境相关的,与本 PR 无关。 对照实验(同机器、同 node_modules):PR 与当前 origin/main 的失败用例集合逐字节相同。
| 通过 | 失败 | 总计 | |
|---|---|---|---|
PR fdfcbf45a |
683 | 51 | 734 |
origin/main ad65ba3bd |
688 | 51 | 739 |
两份失败用例名单 diff 结果完全一致,均为无关路由(如本机 POST /session 返回 500),在干净的 main 上同样失败。本 PR 只新增了通过的测试,未造成任何回归。
类型检查(fdfcbf45a 下各包 tsc --noEmit 干净,依赖按序构建)
sdk-typescript ✅ · acp-bridge ✅ · webui ✅ · web-shell ✅ · core 构建 ✅
关于 cli 包类型检查的说明(环境问题,非 PR 缺陷)
在使用符号链接 node_modules 的验证 worktree 中,cli 的原始 tsc --noEmit 会报出跨包 “property does not exist” 的假错误——因为 tsc 对部分 @qwen-code/acp-bridge / @qwen-code/sdk 子路径类型走了 composite .d.ts 声明,而非源码 paths 映射。这并非本 PR 特有:
- 当前
origin/main在完全相同的环境下报 52 条同类错误;PR 报 72 条(31 条共有)。 - PR 多出的 13 条全部指向本 PR 新增且源码中确实存在 的符号,已逐一核对:
AcpSessionBridge.initializeWorkspaceMcp/reloadWorkspaceMcp(bridgeTypes.ts:861,864)、manageMcpServer(action: 'approve' | …)(bridgeTypes.ts:1171)、ServeWorkspaceMcpServerStatus.{configOrigin,approvalState,authenticationState,removable,…}(status.ts:220)。 - 定义这些符号的包(
acp-bridge、sdk-typescript)类型检查干净。
CI 的按依赖顺序构建可正确解析这些;PR 自身的 CI 类型检查通过。
UI —— 新增 McpManagerPage 真实渲染
PR 明确指出 Web Shell UI 未做自动化测试。我在独立 Vite harness 中渲染了真实的 McpManagerPage 组件(真实 globals.css Tailwind v4 + shadcn tokens、真实 i18n,仅 mock useMcp/useSettings),并用 Playwright 以覆盖多种状态的样例数据驱动(已连接 · 待审批 · OAuth 认证中 · 已禁用 · 扩展提供 · 断开并报错)。所有交互零 console/page 报错。
服务器列表 —— 浅色与深色
| 浅色 | 深色 |
|---|---|
![]() |
![]() |
来源筛选 → Extension(仅保留扩展提供的服务器;扩展服务器可见但不能单独删除 —— 对应测试计划 #3)
服务器详情 —— 基本信息与工具浏览(进入详情按需加载 tools/resources;非法工具标记为 Blocked)
| 概览 | 工具 |
|---|---|
![]() |
![]() |
新增 MCP Server 对话框(名称 / 描述 / 范围选择 / JSON 配置 —— 浅色与深色,经 Radix portal)
| 浅色 | 深色 |
|---|---|
![]() |
![]() |
方法
- 隔离
git worktree,detached 于fdfcbf45a;node_modules从已构建的 checkout 符号链接;工作区依赖通过各包vitest/tsconfig的pathsalias 解析到源码。 server.test.ts基线来自第二个固定在origin/mainad65ba3bd的 worktree,环境一致。- 截图:真实
McpManagerPage跑在 Vite dev harness + Playwright(deviceScaleFactor: 2),浅色与深色。
结论
从本地验证角度 LGTM。 后端路由、密钥遮罩/还原、工作区级 MCP 生命周期、SDK 类型、以及新增 Web Shell UI 行为均正确,且被全绿套件覆盖;相对当前 main 无回归。唯一需要说明的是上文所述的 cli 原始 tsc 环境噪声,CI 不会触发该问题。
chiga0
left a comment
There was a problem hiding this comment.
Code Review Overview (AI Generated)
PR: #6954 — feat(serve): add workspace MCP management
Type: New Feature
Change size: +6150/-1516 across 54 files
HEAD: fdfcbf45
Findings Summary
- Critical: 0
- Major: 3 (architecture/UX quality, not correctness blockers)
- Minor: 5
- Nit: 3
Cross-Validation
| Finding | Other Reviewer | My Assessment |
|---|---|---|
| Latest review: LGTM | qwen-code-ci-bot | Confirmed — no blocking correctness issues |
| Earlier CHANGES_REQUESTED (dismissed) | qwen-code-ci-bot | Resolved in subsequent fix commits |
Review
Comprehensive feature adding workspace-scoped MCP management across daemon, bridge, SDK, and Web Shell. The design is sound: management operations go through ensureChannel() with proper withWorkspaceControl accounting, configuration changes persist first then reconcile across live runtimes, and secret redaction is correctly extracted into a shared module (mcp-server-secrets.ts).
Key strengths verified:
- Secret handling: Backend
redactMcpServersSettingcorrectly redacts before sending to frontend.restoreRedactedMcpSecretspreserves originals when__redacted__is unchanged. Broadcasts use redacted values. - OAuth flow: Handles server removal during polling, auth failure detection, daemon errors, URL validation (
isHttpUrl), and finite iteration limits (400 × 1.5s = 10min max). - Navigation state: Session preserved between chat ↔ MCP management.
/mcpcommand opens management page directly. - Mutation serialization:
mcpServerMutationQueuescorrectly chains operations per workspace/scope, preventing concurrent config mutations. - Status caching:
mergeManagedWorkspaceMcpStatuspreserves cached state across child process restarts, with proper handling of fresh children.
Major Findings (non-blocking)
M1. Monolithic 1777-line McpManagerPage component
Single function component with 20+ useState calls, all business logic, and all rendering. Not a correctness issue but makes the component hard to test, review, and maintain. Recommend extracting useMcpDiscovery, useMcpServerActions, useMcpServerForm hooks and ServerList, ServerDetail, ToolDetailView sub-components in a follow-up.
M2. __redacted__ placeholders visible in edit form textarea
Users see __redacted__ magic strings in the JSON config editor with no visual indication these are protected fields. If accidentally modified, the backend treats it as a new secret value. Backend behavior is correct (secrets never leak to frontend), but UX could surprise users. Recommend either stripping env/headers/oauth.clientSecret from the editable JSON and providing separate masked inputs, or adding a visible warning banner.
M3. OAuth authentication runs as detached async task with no shutdown cancellation
The authenticate action spawns a detached IIFE that continues executing against a partially-torn-down agent if shutdown occurs mid-authentication. Common pattern in long-running daemons but reconcileMcpServerAcrossLiveConfigs could iterate configs whose tool registries are already stopped. An AbortController would be cleaner.
Minor Findings
busyServerblocks ALL server actions during OAuth poll — overly conservative; should be per-server.disableaction has no confirmation dialog — unlikeremove, executes immediately. Disabling interrupts all active connections.originatorClientIddefaults to'daemon'sentinel — audit trails become ambiguous. Should be a documented constant orundefined.workspaceMcpDiscoveryConfiglacks explicit teardown — pool drain handles connections but Config's tool registry/event listeners aren't explicitly disposed.reconcileMcpServerAcrossLiveConfigsis not atomic — sequential operations leave partial state on failure. By design (per-runtime independence) but can cause cross-session inconsistency.
Final Verdict
APPROVE. The feature is well-designed with correct secret handling, proper OAuth flow management, and solid status caching. The Major findings are architecture/UX quality issues, not correctness blockers. The test coverage (249 CLI MCP tests, 106 SDK tests, bridge tests for channel lifecycle and status merging) is thorough.
This review was generated by QoderWork AI

















What this PR does
This PR adds workspace-scoped MCP management to Web Shell and the daemon. It introduces a plugin management entry with extension and MCP tabs, persisted user/workspace MCP discovery that can run without a chat session, typed SDK status and control operations, and management flows for approval, reconnect, OAuth authentication, enablement, add, edit, and delete. Changes are reconciled into live sessions while project .mcp.json servers and non-persisted runtime servers remain outside the management list.
The MCP UI now provides aligned cards and empty states, source filtering, server/tool/resource details, polling for OAuth completion, safe destructive confirmations, atomic settings mutations, redacted-secret preservation, and compatible source metadata through the additive configOrigin field.
Why it's needed
MCP administration was previously tied too closely to session lifecycle, so the management page could lose discovery state, fail operations when no session existed, or require repeated initialization. Users also lacked a consistent place to inspect and manage persisted MCP servers. A workspace-level control path allows administration after daemon restart, works with or without connected sessions, and propagates configuration changes to every active runtime.
Reviewer Test Plan
How to verify
Evidence (Before & After)
Before: MCP management depended on a live session and could reinitialize repeatedly, lose status across navigation, or expose operations that the backend could not perform.
After: MCP management has a workspace-level lifecycle, works with zero or multiple live sessions, propagates changes to those sessions, and provides consistent management UI and status behavior.
Tested on
Environment (optional)
Targeted validation completed: CLI MCP tests (249 passed), workspace settings tests (14 passed), SDK daemon event tests (106 passed), package-level typechecks for CLI, ACP bridge, SDK, and Web Shell, targeted builds for ACP bridge, SDK, and WebUI, and git diff validation. Per request, no Web Shell UI test or repository-wide build was run.
Risk & Scope
Linked Issues
N/A
中文说明
本 PR 的改动
本 PR 为 Web Shell 和 daemon 增加工作区级 MCP 管理能力。新增带有“扩展”和“MCP”Tab 的插件管理入口;持久化的用户级、工作区级 MCP 可在没有聊天 session 时完成发现;SDK 增加类型化的状态与控制操作;管理页支持审批、重新连接、OAuth 认证、启用、新增、编辑和删除。配置变更会同步到所有存活 session,同时项目 .mcp.json 和未落盘的运行时 MCP 不进入管理列表。
MCP 页面同时补齐统一的卡片与空状态、来源筛选、服务器/工具/资源详情、OAuth 完成轮询、安全的删除二次确认、原子设置修改、敏感字段遮罩保留,以及通过新增 configOrigin 字段提供兼容且精确的来源信息。
为什么需要
此前 MCP 管理与 session 生命周期耦合过深,管理页面可能丢失发现状态、在没有 session 时无法操作,或者重复初始化。用户也缺少统一查看和管理持久化 MCP 服务器的入口。工作区级控制链路可以在 daemon 重启后直接管理,在没有或存在多个 session 时都能工作,并把配置变更传播到所有活跃运行实例。
Reviewer 测试计划
验证方式
前后对比证据
修改前:MCP 管理依赖存活 session,可能重复初始化、导航后丢失状态,或展示后端不支持的操作。
修改后:MCP 管理具有工作区级生命周期,可在零个或多个存活 session 下工作,操作结果同步到 session,并提供一致的管理 UI 与状态行为。
测试平台
环境
已完成定向验证:CLI MCP 测试 249 个通过、工作区设置测试 14 个通过、SDK daemon 事件测试 106 个通过、CLI/ACP bridge/SDK/Web Shell 包级类型检查、ACP bridge/SDK/WebUI 定向构建以及 git diff 检查。按要求未运行 Web Shell UI 测试或仓库全量 build。
风险与范围
关联 Issue
无