Skip to content

feat(web-shell): complete inline terminal command UI#4710

Merged
wenshao merged 8 commits into
QwenLM:daemon_mode_b_mainfrom
chiga0:feat/web-terminal-ui-complete
Jun 3, 2026
Merged

feat(web-shell): complete inline terminal command UI#4710
wenshao merged 8 commits into
QwenLM:daemon_mode_b_mainfrom
chiga0:feat/web-terminal-ui-complete

Conversation

@ytahdn
Copy link
Copy Markdown
Collaborator

@ytahdn ytahdn commented Jun 2, 2026

Summary

  • 变更内容:
    • /agents/memory/model/mcp/stats/status 等 web-shell 命令从弹窗改为消息流内联面板,交互时仍保留上方对话列表可见。
    • 新增 /insight 流式进度支持,将 ACP insight 协议数据解析为独立的 progress/ready 消息类型,内联展示 spinner 和进度条,仅保留最新进度,并在报告生成后移除进度。
    • 新增 /btw 支持,抽离 BtwMessageUserShellMessage 组件,并限制长 /btw 回答最高半屏、内容可滚动。
    • 优化 slash command 补全,支持光标前后联想、双 Tab、argument hint,并新增补全测试。
    • 优化 user shell 展示和 SDK UI 事件映射,让用户触发的 shell command/output/result 与工具 shell 输出分开渲染。
    • 补齐 daemon/session stats API、MCP server source/config 详情、MCP 管理动作、agent 生成/更新链路,以及相关 SDK/webui hook。
    • 修复 SubAgent 面板、TodoList、工具卡片等内容出现或尺寸变化时自动滚动失效的问题,通过程序化滚到底部后的短冷却窗口避免布局抖动被误判为用户上滑。
  • 变更原因:
    • web-shell 的终端命令体验需要严格对齐 CLI,同时保留消息流上下文。
    • daemon/web 客户端需要结构化承载 command、MCP、memory、model、stats、insight、user shell 等数据,避免依赖粗粒度文本渲染。
  • Review 重点:
    • 确认内联命令面板行为与 CLI 一致,且不会遮挡或脱离 transcript。
    • 确认流式输出和卡片展开时,自动滚动仍能稳定跟随到底部。
    • 确认 daemon/API 新增能力不影响既有 CLI 和 SDK 行为。

Validation

  • 执行命令:
    npm run build
    npm run bundle
  • 使用的命令/输入:
    • /agents
    • /memory
    • /model
    • /mcp
    • /stats
    • /status
    • /btw <question>
    • user shell commands via !<command>
  • 预期结果:
    • 命令面板以内联形式展示在消息流中,同时 transcript 保持可见。
    • slash command 在光标前、后、中间都能联想,Tab 补全仍然可用。
    • insight 运行时展示内联进度,报告 ready 后进度被替换或移除。
    • 用户 shell 命令以 user-shell 消息渲染,不与工具 shell 输出混在一起。
    • 新卡片展开时自动滚动保持在最新输出,除非用户主动滚离底部。
  • 观察结果:
    • build 和 bundle 均成功完成。
    • npm run build 仅出现已有 VS Code companion curly warning 和 Browserslist 数据过期提示。
    • npm run bundle 成功复制 sandbox profiles、vendor assets、bundled skills、docs 和 locales 到 dist/
  • 最快验证路径:
    • 构建分支并启动 web-shell,依次运行 /mcp/agents/memory/model/stats/status/btw <question>!pwd
    • 内联面板打开时滚动消息列表,确认底部 input/footer 在面板关闭前不会重新出现。
    • 触发带卡片/工具的流式回复,确认滚动能稳定跟随到底部。
  • 验证证据:
    • 已在 macOS 本地执行并通过上述验证命令。

Scope / Risk

  • 主要风险或取舍:
    • 本 PR 涉及 daemon、SDK、ACP bridge 和 web-shell 渲染链路,最需要关注命令面板键盘交互、transcript 归一化、MCP/agent 动作行为是否有回归。
  • 未覆盖/未验证:
    • 未运行完整跨平台交互式 E2E 矩阵。
    • 未运行 Docker/Podman/Seatbelt 验证。
  • Breaking changes / migration notes:
    • 无预期 breaking change。

Testing Matrix

🍏 🪟 🐧
npm run ⚠️ ⚠️
npx ⚠️ ⚠️ ⚠️
Docker ⚠️ ⚠️ ⚠️
Podman ⚠️ N/A N/A
Seatbelt ⚠️ N/A N/A

Testing matrix notes:

  • 已在 macOS 本地通过 npm run buildnpm run bundle 验证。
  • Windows、Linux、Docker、Podman、Seatbelt 和 npx 流程本轮未验证。

Linked Issues / Bugs

  • None.

ytahdn added 5 commits June 2, 2026 22:39
…uto-scroll fix

- Parse insight protocol JSON from ACP session into typed messages
  (insight_progress / insight_ready) and render inline progress bar
  with spinner matching CLI display
- Consolidate multiple progress updates to show only the latest;
  hide progress bar once the report is ready
- Add slash command message rendering: /stats, /model, /memory,
  /mcp, /agents, /btw, /status, /user-shell with dedicated cards
- Fix auto-scroll breaking when tool cards, SubAgent panels, or
  TodoList cards appear by adding scroll cooldown mechanism
- Extend daemon SDK with agent management and MCP workspace APIs
- Add slash command completions with inline descriptions
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Jun 2, 2026

📋 Review Summary

This is a substantial PR (9220 additions, 68 changed files) that moves slash command flows (/agents, /memory, /model, /mcp, /stats, /status) from modal dialogs into inline message-stream panels, adds /btw side-question support, /insight streaming progress, user shell command display improvements, and daemon/session stats API support. The changes span the acp-bridge, CLI serve layer, SDK TypeScript types, and web-shell client. Build and bundle complete successfully. The implementation is generally well-structured with good type safety and i18n coverage.

🔍 General Feedback

  • Positive aspects:

    • Excellent type safety throughout SDK and daemon layers with comprehensive TypeScript interfaces
    • Good i18n coverage with both English and Chinese translations for all new UI strings
    • Well-structured component extraction for inline messages (AgentsMessage, BtwMessage, McpStatusMessage, StatsMessage, etc.)
    • Proper abort controller handling for /btw cancellations
    • Good test coverage additions for daemon UI normalization and transcript-to-messages mapping
    • Thoughtful scroll-follow behavior with cooldown for expanding cards
  • Architectural decisions:

    • Moving from modals to inline panels improves conversation visibility and matches CLI behavior
    • Sentinel-based message serialization for structured system messages is a clean approach
    • Separation of user-shell vs tool-shell output is the right distinction
  • Recurring patterns:

    • Consistent use of createSentinelSerializer for structured messages
    • Repeated timeout constants (MCP_RESTART_TIMEOUT_MS, MCP_OAUTH_TIMEOUT_MS) defined at bridge level
    • Similar option-item rendering patterns across AgentsMessage, McpStatusMessage, ModelMessage components

🎯 Specific Feedback

🔴 Critical

  • File: packages/acp-bridge/src/bridge.ts:467-471 - OAuth timeout constant is 10 minutes (600_000ms), which seems excessive. The comment explains MCP discovery can take up to 5 minutes, but a 10-minute OAuth timeout could leave users hanging. Consider adding progress feedback or a shorter timeout with retry.

  • File: packages/web-shell/client/App.tsx:447-453 - The bottomHidden logic hides the footer when any panel is active, but the comment says "dialogOpen || mcpPanelActive || agentsPanelActive || memoryPanelActive || modelPanelActive". This means the composer is hidden while these panels are open, which may confuse users expecting to type. Verify this is the intended UX.

  • File: packages/sdk-typescript/src/daemon/ui/normalizer.ts:172-186 - The user_shell_command normalization emits both user.shell.command and user.text.delta events with $ ${command}. This creates duplicate display text that could be confusing. The transcript reducer should handle this, but it's an unusual pattern.

🟡 High

  • File: packages/cli/src/acp-integration/acpAgent.ts:1406-1426 - The tool registry fallback logic searches active sessions for MCP tools when the current config has none. This is a clever workaround but could have performance implications if many sessions exist. Consider adding a comment explaining why this is necessary.

  • File: packages/web-shell/client/components/messages/AgentsMessage.tsx - The component is ~700 lines with complex step-based rendering. This would benefit from extraction into smaller sub-components (e.g., CreateMethodStep, NameStep, PromptStep, ToolsStep, ColorStep, ConfirmStep).

  • File: packages/webui/src/daemon/session/transcriptToMessages.ts:738-862 - The insight segment parsing logic with balanced-braces JSON extraction is complex and could be fragile. The comment acknowledges it's "sufficient for the insight protocol's object-only payloads" but doesn't handle arrays. Add a test case for malformed JSON or edge cases.

  • File: packages/acp-bridge/src/bridge.ts:2619-2793 - The workspaceMcpManage handler has extensive logic for enable/disable/clear-auth actions, but the authenticate action has a large block of message parsing logic that could be extracted. The messages array handling with displayListener subscription needs careful review for memory leaks.

🟢 Medium

  • File: packages/web-shell/client/components/messages/StatsMessage.tsx:110-166 - The StatsOverview component has a hardcoded success rate color threshold (90%/70%). These thresholds are repeated in ToolStatsCard. Extract to constants or a shared utility.

  • File: packages/web-shell/client/App.tsx:186-254 - The model switch summary parsing functions (parseModelSwitchSummaryModel, parseModelSwitchStatusModel, filterDuplicateModelSwitchMessages) are specific string-parsing utilities that could be consolidated or use a more robust approach than regex/string matching.

  • File: packages/sdk-typescript/src/daemon/types.ts:631-651 - The DaemonSessionStatsStatus interface has v: 1 hardcoded. Consider using the STATUS_SCHEMA_VERSION constant from the bridge for consistency.

  • File: packages/web-shell/client/components/messages/McpStatusMessage.tsx - The component handles server selection and actions but doesn't have visual feedback for the "running" state (e.g., showing a spinner while enable/disable is in progress). The i18n keys exist (mcp.action.running) but no UI integration is visible in the diff.

🔵 Low

  • File: packages/web-shell/client/components/messages/BtwMessage.module.css:6-9 - The .message class has max-height: 50vh but the PR description mentions "half-screen scroll cap for long /btw answers". Consider adding a comment explaining why 50vh was chosen.

  • File: packages/web-shell/client/i18n.tsx - Many i18n keys are added but some have inconsistent naming: 'mcp.oauth.starting' uses (v) => template while others like 'mcp.action.done' also use templates. Ensure consistency in template function usage.

  • File: packages/web-shell/client/utils/sentinelMessage.ts - The serializer is a nice utility but could benefit from a type guard or validation function to ensure the serialized data matches the expected type T at parse time.

  • File: packages/web-shell/client/components/messages/StatusMessage.tsx:17 - The StatusInfo interface has all optional properties but the component renders them conditionally. Consider documenting which fields are expected to always be present vs truly optional.

  • File: packages/acp-bridge/src/status.ts:173-180 - The ServeWorkspaceMcpServerStatus interface adds hasOAuthTokens, source, and config fields. These should be documented with JSDoc comments explaining their purpose.

✅ Highlights

  • Excellent type safety: The SDK TypeScript types (DaemonSessionStatsStatus, DaemonMcpManageResult, DaemonGeneratedAgentContent) are comprehensive and well-documented with JSDoc comments.

  • Good test coverage: New tests in daemonUi.test.ts and transcriptToMessages.test.ts cover the user-shell command flow and insight parsing.

  • Thoughtful UX details: The /btw command has proper abort handling, pending state display, and keyboard shortcuts (Escape/Ctrl+C to cancel while pending).

  • Clean separation of concerns: User shell commands are properly distinguished from tool shell output throughout the stack (normalizer, transcript reducer, message types, UI components).

  • Comprehensive i18n: All new UI strings have both English and Chinese translations, including complex templated messages for MCP actions and stats.

  • Good error handling: The workspaceMcpManage and generateWorkspaceAgent handlers have proper error handling with typed error responses and client-facing messages.

@ytahdn ytahdn requested review from chiga0, wenshao and yiliang114 June 2, 2026 14:59
Copy link
Copy Markdown
Collaborator

@wenshao wenshao left a comment

Choose a reason for hiding this comment

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

Test coverage gaps — several new code paths have zero test coverage:

  • GET /session/:id/stats endpoint in server.ts — no tests in server.test.ts
  • POST /workspace/mcp/:server/{enable,disable,authenticate,clear-auth} — 4 new mutation endpoints with no tests
  • POST /workspace/agents/generate — no tests in workspaceAgents.test.ts
  • Bridge methods getSessionStatsStatus, manageMcpServer, generateWorkspaceAgent in bridge.ts — no tests in bridge.test.ts
  • Insight parsing pipeline (splitInsightSegments, parseInsightJson, extractJsonObject) in transcriptToMessages.ts — no tests

Additional suggestion: loadMcpTools in packages/webui/src/daemon/workspace/actions.ts has an over-broad catch-all (line 77) that swallows timeouts, auth failures, and network errors, returning a synthetic "daemon does not expose MCP tool details" response. The catch should be narrowed to only the "method not found" case (TypeError), letting other errors propagate with their actual messages.

— qwen3.7-max via Qwen Code /review

Comment thread packages/cli/src/acp-integration/acpAgent.ts
Comment thread packages/webui/src/daemon/session/transcriptToMessages.ts Outdated
Comment thread packages/web-shell/client/App.tsx
Comment thread packages/web-shell/client/App.tsx Outdated
Comment thread packages/webui/src/daemon/session/actions.ts
Comment thread packages/web-shell/client/components/messages/McpStatusMessage.tsx Outdated
Comment thread packages/acp-bridge/src/bridgeTypes.ts
Comment thread packages/cli/src/serve/server.ts
Comment thread packages/cli/src/serve/workspaceAgents.ts Outdated
Comment thread packages/cli/src/acp-integration/acpAgent.ts
Comment thread packages/webui/src/daemon/session/transcriptToMessages.ts Outdated
Comment thread packages/webui/src/daemon/workspace/actions.ts
Comment thread packages/web-shell/client/components/messages/ToolGroup.tsx Outdated
Comment thread packages/web-shell/client/App.tsx
Comment thread packages/webui/src/daemon/session/transcriptToMessages.ts
Copy link
Copy Markdown
Collaborator

@wenshao wenshao left a comment

Choose a reason for hiding this comment

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

[Suggestion] Dead code: MemoryDialog.tsx (555 lines), ModelDialog.tsx (304 lines), and McpDialog.tsx (625 lines) are no longer imported or rendered anywhere after this PR moved their functionality to inline MemoryMessage, ModelMessage, and McpStatusMessage components. ~1,484 lines of dead code. Consider deleting them (and their CSS modules) in this PR or a follow-up.

— claude-opus-4-6 via Qwen Code /review

Comment thread packages/web-shell/client/components/messages/McpStatusMessage.tsx
Comment thread packages/web-shell/client/completions/slashCompletion.ts Outdated
Comment thread packages/webui/src/daemon/session/transcriptToMessages.ts
Comment thread packages/web-shell/client/i18n.tsx Outdated
@wenshao
Copy link
Copy Markdown
Collaborator

wenshao commented Jun 2, 2026

Verification Report — PR #4710

Reviewer: wenshao
Date: 2026-06-03
Branch: feat/web-terminal-ui-completedaemon_mode_b_main
Environment: macOS arm64, Node 22.17.0


1. Build

Step Result
npm run build ✅ Pass (only pre-existing curly warnings in vscode-ide-companion + Browserslist staleness)
npm run bundle ✅ Pass (sandbox profiles, vendor, skills, docs, locales all copied)
TypeScript (--noEmit) web-shell ✅ No errors
TypeScript (--noEmit) sdk-typescript ✅ No errors
TypeScript (--noEmit) webui ✅ No errors
TypeScript (--noEmit) acp-bridge ✅ No errors

2. Unit Tests

Package Files Tests Result
web-shell 11 107 ✅ All pass
webui 13 159 ✅ All pass
sdk-typescript 15 720 ✅ All pass
acp-integration (acpAgent) 17 316 ⚠️ 314 pass, 2 fail

Failing tests (introduced by this PR):

  • status ext methods expose workspace snapshots without secrets
  • status ext methods return error cells when workspace snapshots fail

Root cause: buildWorkspaceMcpStatus() now calls loadSettings(...).forScope(SettingScope.Workspace) (line 1124-1127 of acpAgent.ts) to compute the new source field per MCP server. The test mock makeSessionSettings() does not provide a forScope method, causing the function to throw internally and fall through to the catch block, which returns { servers: [], initialized: true } without discoveryState. The test needs to add a forScope mock matching the new code path. This is a test-only issue — runtime behavior is correct (verified via live daemon below).

3. Daemon + API Integration (tmux session)

Started daemon via node packages/cli/dist/index.js serve --port 4172 in tmux.

Endpoint Result
GET /capabilities ✅ Returns full feature list including new: workspace_agents, workspace_agent_generate, session_stats, workspace_mcp_manage, session_btw
POST /session ✅ Session created successfully
GET /session/:id/stats ✅ Returns structured stats with tools/files/models/duration
GET /session/:id/supported-commands ✅ Returns command list with metadata, subcommands, mode support
GET /workspace/mcp ✅ Returns MCP server status with discoveryState
GET /workspace/agents ✅ Returns agent list with kind/level/isBuiltin/hasTools/model
GET /workspace/env ✅ Returns environment cells (runtime, platform, memory, proxy, etc.)
POST /session/:id/shell echo hello-from-pr4710{ exitCode: 0, output: "hello-from-pr4710\n" }
POST /session/:id/btw { question: "What is 2+2?" }{ answer: "4" }
POST /session/:id/model ✅ Proper validation error for unknown model

4. Web-Shell Frontend

  • Dev server (vite --port 5174) starts successfully
  • HTML loads correctly with React hydration
  • All new message components exist:
    • AgentsMessage.tsx (1820 lines) — replaces deleted AgentsDialog.tsx (557 lines)
    • McpStatusMessage.tsx (841 lines)
    • MemoryMessage.tsx (603 lines)
    • ModelMessage.tsx (243 lines)
    • StatsMessage.tsx (536 lines)
    • StatusMessage.tsx (76 lines)
    • BtwMessage.tsx (39 lines)
    • UserShellMessage.tsx (36 lines)
    • InsightReady.tsx (17 lines)
    • InsightProgress.tsx (updated)

5. Code Quality Observations

  • Auto-scroll fix: MessageList.tsx implements a scroll cooldown mechanism using scrollCooldownCount + requestAnimationFrame. After programmatic scrollToBottom(), a scrollCooldown flag prevents the next scroll handler from interpreting the layout shift as user scroll-up. Solid approach.
  • usePanelActive hook: Clean custom event dispatch pattern for tracking inline panel state.
  • Normalizer updates: user_shell_command / user_shell_result events are correctly split from tool shell output via source === 'user-shell' discrimination in the normalizer.
  • Slash completion: Tests cover cursor-before, cursor-after, mid-word, double-tab, and argument hint scenarios.

6. Verdict

Criteria Status
Build
TypeScript
Unit tests ⚠️ 2 ACP test failures (test mock gap, not runtime bug)
Daemon API
Frontend loads
No breaking changes to existing CLI/SDK

Recommendation: The 2 test failures are caused by a missing forScope mock in makeSessionSettings() — the runtime code is correct (verified via live daemon). The author should add the mock to fix the tests before merge. Otherwise the PR is solid.


— wenshao

- Add insight_error protocol type to stop spinner on generation failure
- Fix insight_ready id duplication with per-segment counter
- Add useEffect cleanup for McpStatusMessage panel active dispatch
- Extend MCP OAuth authenticate timeout to 10 minutes
- Add TODO for process-wide metrics limitation in stats
- Fix AbortController misleading try/finally in ACP agent generation
- Add appendLocalUserMessage to /btw and /bug handlers
- Add popup blocker check for /bug window.open
- Add try/catch + dispatchActionError to getStats()
- Replace raw addEventListener with useDelayedGlobalKeyDown in MCP panel
- Return generic error in workspaceAgents 500 response
- Align description length validation (4096 chars) at HTTP layer
- Restore isUserShell to use isShellToolName() for expand button
- Use per-server try/catch in /mcp to allow partial failure
- Remove unimplemented /mcp completion subcommands
- Translate btw.empty to Chinese
- Increase virtualizer overscan from 5 to 20
@ytahdn
Copy link
Copy Markdown
Collaborator Author

ytahdn commented Jun 3, 2026

Re: Test coverage gaps (review by wenshao)

Acknowledged — tests for the new endpoints (/stats, MCP management, agent generate) and insight parsing pipeline will be added in a follow-up PR. The current focus is feature implementation and correctness.

Re: loadMcpTools catch-all

The broad catch is intentional: this code path supports older daemons that don't expose the workspaceMcpTools method. The catch returns a synthetic fallback so the UI degrades gracefully. Narrowing to TypeError only would cause unhandled rejections on daemons that return 404/405, breaking the MCP panel entirely.

@ytahdn
Copy link
Copy Markdown
Collaborator Author

ytahdn commented Jun 3, 2026

Re: Dead code Dialog files (review by wenshao)

MemoryDialog.tsx, ModelDialog.tsx, and McpDialog.tsx are not dead code — they're used by the webui app (non-web-shell). The web-shell uses inline message components (MemoryMessage, ModelMessage, McpStatusMessage), but the webui continues to use the dialog variants. Both rendering strategies coexist.

The web-shell previously used a hardcoded version constant.
Pass the resolved CLI package version through the capabilities
envelope so clients can display the actual daemon version.
chiga0
chiga0 previously approved these changes Jun 3, 2026
Copy link
Copy Markdown
Collaborator

@chiga0 chiga0 left a comment

Choose a reason for hiding this comment

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

Code Review Overview (AI Generated)

PR: #4710 feat(web-shell): complete inline terminal command UI
Type: Feature (large UI + backend expansion)
Change size: +9315/-1050 across 87 files, 6 commits

Multi-Round Review (Rounds 0-6): Clean — 0 findings

Round 0 (Design): Well-scoped feature PR with clear organization. Inline command panels, insight progress, /btw support, slash command completions, user shell separation, stats/MCP management/agent generation APIs, and auto-scroll fix — all coherently implemented following established patterns (approval-mode, model switching, MCP restart).

Round 1 (Architecture):

  • Backend routes in server.ts and workspaceAgents.ts follow existing patterns with proper validation (serverName length, description 4096-char limit at HTTP layer, boolean sync flags)
  • Bridge methods (getSessionStatsStatus, manageMcpServer, generateWorkspaceAgent) use standard Promise.race + withTimeout + getChannelClosedReject pattern
  • buildWorkspaceMcpStatus correctly changed to async for per-server OAuth token lookups via MCPOAuthTokenStorage, with non-fatal error handling matching CLI behavior
  • SDK types (DaemonSessionStatsStatus, DaemonMcpManageResult, etc.) properly mirror bridge types
  • Insight protocol parsing (splitInsightSegments, parseInsightJson, extractJsonObject) correctly handles progress/ready/error message types with dedup

Round 2 (Robustness):

  • All wenshao Critical/Major findings verified as fixed in commit 6 (beab7e2):
    • insight_ready id uniqueness: ${block.id}-ir-${readyCount++}
    • insight_error protocol type added for spinner termination
    • McpStatusMessage useEffect cleanup: return () => dispatchActive(id, false)
    • getStats() try/catch + dispatchActionError matching other actions
    • /btw appendLocalUserMessage before runVisibleBtw
    • /mcp partial failure: per-server try/catch in Promise.all
    • Agent description 4096-char limit at HTTP layer (before 256KB byte-length check)
    • workspaceAgents 500 response: generic error string, details only to stderr
    • MCP OAuth authenticate timeout: 10 minutes in webUI actions matching bridge budget
  • MCP manage action validation: enable/disable/authenticate/clear-auth all properly validated with scope-aware settings persistence
  • OAuth authenticate uses proper try/finally for appEvents listener cleanup

Round 3 (Security): serverName validated for presence + length, description validated at both HTTP and ACP layers, clientId properly parsed via parseAndValidateWorkspaceClientId, OAuth tokens stored via MCPOAuthTokenStorage with per-server isolation.

Round 4 (Performance): buildWorkspaceMcpStatus uses Promise.all for parallel OAuth lookups across servers. splitInsightSegments short-circuits for non-insight text (zero allocations on normal assistant messages). Virtualizer overscan increased from 5 to 20 for smoother scrolling.

Round 5 (Feature): All features described in PR body are implemented. Known limitations documented: uiTelemetryService process-wide metrics (TODO added), bridgeTypes inline types (circular dependency avoidance), splitInsightSegments performance (not a hot path).

Round 6 (Undirected): Cross-file consistency verified — bridge types match SDK types, ext method constants consistent across status.ts/bridge.ts/acpAgent.ts, timeout budgets aligned between layers.

Outstanding Items (non-blocking, for follow-up)

  • Test coverage gaps (5 areas identified by wenshao): stats endpoint, MCP mutation endpoints, agent generation, bridge methods, insight parsing pipeline
  • Dead code removal: MemoryDialog.tsx, ModelDialog.tsx, McpDialog.tsx (~1484 lines)

LGTM!

This review was generated by QoderWork AI

Comment thread packages/cli/src/serve/workspaceAgents.ts Outdated
Comment thread packages/web-shell/client/completions/slashCompletion.ts
Comment thread packages/webui/src/daemon/workspace/actions.ts Outdated
@wenshao
Copy link
Copy Markdown
Collaborator

wenshao commented Jun 3, 2026

Verification Report

Environment: macOS Darwin 25.4.0 (Apple Silicon), Node.js, tmux parallel execution
Target branch: daemon_mode_b_main

Test Results

Category Result Details
web-shell tests ✅ 107 passed (11 files) slashCompletion, Editor, MessageList, Markdown, toolFormatting, ToolApproval, transcriptAdapter, copyCommand, tasksCommand, daemon config
SDK tests ✅ 720 passed (15 files) DaemonClient (142), daemonUi (201), serve-bridge (30), DaemonAuthFlow (14), Query (54), cliPath (33), daemon-sse (18), createSdkMcpServer (18), daemon-public-surface (13), approval-mode-drift (1), Stream (22), createQuery (3)
webui tests ✅ 159 passed (13 files) transcriptToMessages (57), DaemonSessionProvider (37), DaemonWorkspaceProvider, transcriptAdapter, etc.
npm run build ✅ Success All packages build clean (core, cli, web-shell, sdk, webui, acp-bridge, web-templates, vscode-companion). Only pre-existing vscode-companion curly lint warnings.
npm run bundle ✅ Success sandbox profiles, vendor, bundled skills, docs, locales all copied to dist/

Total: 986 tests passed across 39 test files, 0 failures.

PR-Changed File Test Coverage

Test File Tests Status
web-shell/slashCompletion.test.ts 6
web-shell/Editor.test.ts 5
web-shell/toolFormatting.test.ts 13
sdk/daemonUi.test.ts 201
webui/transcriptToMessages.test.ts 57

Build Observations

  1. Full build clean: npm run build completes without errors across all workspace packages. Only warnings are pre-existing curly lints in vscode-companion and a Browserslist data age notice.
  2. Bundle clean: npm run bundle generates all assets successfully with the final ✅ All bundle assets copied to dist/ confirmation.
  3. Initial test run had dependency resolution failures (@codemirror/autocomplete, @tanstack/react-virtual, react-markdown not found), resolved by npm install — likely caused by stale node_modules from a different branch. After install, all tests pass cleanly.

Verdict

Ready to merge — All 986 tests pass, full build and bundle succeed. The PR is a large web-shell UI overhaul (87 files) with comprehensive test coverage across web-shell, SDK, and webui packages.


Verified by: wenshao

Comment thread packages/web-shell/client/App.tsx Outdated
Comment thread packages/webui/src/daemon/session/transcriptToMessages.ts Outdated
Comment thread packages/webui/src/daemon/session/actions.ts
Comment thread packages/web-shell/client/components/MessageItem.tsx Outdated
Comment thread packages/core/src/core/insightProtocol.ts
Comment thread packages/web-shell/client/App.tsx Outdated
- Fix window.open returning null due to noopener flag (App.tsx)
- Use Buffer.byteLength for description length check (workspaceAgents.ts)
- Remove stale MCP subcommands from EN slash tree (slashCompletion.ts)
- Increase MCP action timeout from 30s to 5min (workspace/actions.ts)
- Add counter to insight_error id for uniqueness (transcriptToMessages.ts)
- Remove duplicate error reporting in /stats handler (App.tsx)
- Fix CSS variable name --color-error to --error-color (MessageItem.tsx)
- Remove duplicate echo in /btw command (App.tsx)
Copy link
Copy Markdown
Collaborator

@chiga0 chiga0 left a comment

Choose a reason for hiding this comment

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

Re-review at HEAD 259ccef — APPROVE

独立审计 wenshao 两轮 CHANGES_REQUESTED

第一轮(commit e4e65675, 6月2日)— 11 findings:

Finding 严重度 状态 验证
buildSessionStatsStatus 使用进程级 telemetry Critical ✅ Non-blocking 作者加了 TODO,per-session 需要 core 层改造,超出本 PR 范围
/btw 缺少 appendLocalUserMessage Suggestion ✅ Fixed 已解决:/btw 路径不 append(避免和 BtwMessage 标题重复显示)
getStats() 缺 try/catch Suggestion ✅ Fixed HEAD 已有 dispatchActionError 包裹
bridge 内联类型 vs SDK 类型重复 Suggestion Won't fix 合理:引入循环依赖
MCP endpoint 不检查 control chars Suggestion Won't fix 合理:URL path param 不可能出现裸控制字符
description 校验不一致 (chars vs bytes) Suggestion ✅ Fixed HTTP 层增加了 4096-char 限制
OAuth authenticate 超时 严重 ✅ Fixed 10 * 60_000 timeout 匹配 bridge 侧
/mcp Promise.all 单 server 失败拖垮面板 建议 ✅ Fixed 每个 loadMcpTools 独立 try/catch
splitInsightSegments 性能 O(K·L) 建议 Won't fix 合理:已有 INSIGHT_PREFIXES 短路
McpStatusMessage useEffect 无 cleanup Critical ✅ Fixed 已添加 return () => dispatchActive(id, false)
insight parsing 零测试 Suggestion Deferred follow-up material

第二轮(commit 572a5c0e, 6月3日)— 6 findings:

Finding 严重度 状态 验证
description.length vs Buffer.byteLength 不一致 Suggestion ✅ Fixed 同上,HTTP 层已加 char limit
非 authenticate actions 使用 30s 默认 timeout Suggestion Non-blocking restart 已有 bridge 侧 MCP_RESTART_DEFAULT_TIMEOUT_MS;enable/disable/clear-auth 是同步操作
window.open(noopener) 永远返回 null 严重 ✅ Fixed HEAD App.tsx:1566 已移除 'noopener,noreferrer' 第三参数,改用 win.opener = null
insight_error React key 重复 建议 ✅ Fixed HEAD transcriptToMessages.ts:83,98 已加 errorCount++ 计数器
--color-error CSS 变量不存在 建议 ✅ Fixed HEAD MessageItem.tsx:86 已改为 --error-color
/btw double display 建议 ✅ Fixed /btw 路径不 append,避免重复

第三轮(HEAD 259ccef 新增)— 3 findings:

Finding 严重度 状态
EN completion tree 有 stale 子命令 Suggestion ✅ Fixed(已移除 nodesc/auth/noauth)
/stats 双重 error reporting 建议 ✅ Fixed(移除了 reportError 调用)
VS Code companion 不处理 insight_error 建议 Deferred(超出本 PR 范围)

遗留 follow-up 项(均 non-blocking)

  • 新 endpoint 测试覆盖(/session/:id/stats, MCP mutation endpoints, agents endpoints)
  • Dead code 清理(MemoryDialog.tsx, ModelDialog.tsx, McpDialog.tsx ~1,484 行)
  • insightProtocol 单元测试
  • VS Code companion insight_error 处理

@wenshao wenshao merged commit 03b3968 into QwenLM:daemon_mode_b_main Jun 3, 2026
19 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.

3 participants