feat(serve): add HTTP rewind endpoints for daemon/web-shell (issue #4514 T3.2)#4817
feat(serve): add HTTP rewind endpoints for daemon/web-shell (issue #4514 T3.2)#4817doudouOUC wants to merge 4 commits into
Conversation
T3.2) Expose session rewind as structured HTTP API so web-shell and SDK clients can rewind a session's conversation and files to a previous turn without relying on TUI-only dialog interaction. API surface: - GET /session/:id/rewind/snapshots — list rewindable turns with diff stats - POST /session/:id/rewind — execute file restore + conversation truncation Leverages the existing Session.rewindToTurn() for conversation truncation and FileHistoryService.rewind() for file restore. Extends the existing 'rewindSession' ACP extMethod to also support promptId parameter and file history rewind. Error handling: - 409 SessionBusyError when a prompt is running - 400 InvalidRewindTargetError when the target turn is compressed or does not exist - 404 SessionNotFoundError for unknown sessions Cross-client SSE event 'session_rewound' published on success with originatorClientId for echo suppression. 🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
|
Thanks for the PR, @doudouOUC! Template: the PR body doesn't follow the required template. The content quality is good — clear description of the endpoints, error handling table, design rationale — but the headings are custom (
Could you reformat the body to match the template? The content is all there — it just needs the right structure. This is especially important for the Reviewer Test Plan since this PR touches daemon HTTP routes, SSE events, and SDK types across 5 packages. On direction: session rewind for the daemon/web-shell is solidly aligned. Claude Code's CHANGELOG has extensive rewind and On approach: the scope feels right for the feature — two HTTP endpoints, extended ACP extMethod with backward-compatible params, proper error mapping (409/400/404), SSE event for cross-client notification, and SDK types. Leveraging existing Blocking on template compliance — please reformat and I'll continue with code review. 🔍 中文说明感谢 @doudouOUC 的贡献! 模板: PR 正文未按照必填模板的格式编写。内容质量不错——端点描述清晰、错误处理表格完整、设计思路明确——但使用了自定义标题(
请按照模板重新格式化正文。内容都有了,只是需要正确的结构。这个 PR 涉及 daemon HTTP 路由、SSE 事件和 SDK 类型,横跨 5 个包,Reviewer Test Plan 尤其重要。 方向: daemon/web-shell 的会话回退功能与产品方向高度一致。Claude Code 的 CHANGELOG 中有大量 rewind 和 方案: 范围合理——两个 HTTP 端点、向后兼容的 ACP extMethod 扩展、正确的错误映射(409/400/404)、跨客户端 SSE 事件通知、SDK 类型。利用已有的 因模板合规问题暂停,请重新格式化后继续代码审查。🔍 — Qwen Code · qwen3.7-max |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
PR body doesn't follow the required template. Please reformat with the correct headings — see the Stage 1 triage comment above for details.
📋 Review SummaryThis PR implements HTTP rewind endpoints for the 🔍 General Feedback
🎯 Specific Feedback🔴 Critical
🟡 High
🟢 Medium
🔵 Low
✅ Highlights
|
|
Thanks — PR body has been reformatted to follow the required template. |
There was a problem hiding this comment.
Pull request overview
This PR adds first-class “rewind” support to qwen serve for web-shell/SDK clients by introducing dedicated HTTP endpoints, extending the ACP bridge control/status methods, and updating the TypeScript SDK to call the new routes and consume a new session_rewound SSE event.
Changes:
- Add
GET /session/:id/rewind/snapshotsandPOST /session/:id/rewindplus a newsession_rewindcapability tag. - Extend ACP/bridge plumbing to support rewind-by-
promptId(including best-effort file history restore) and map new rewind-specific errors. - Add SDK types/client methods and new
session_rewoundevent typing + reducer support.
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| packages/acp-bridge/src/bridgeErrors.ts | Adds new bridge error classes for busy session and invalid rewind targets. |
| packages/acp-bridge/src/bridgeTypes.ts | Introduces rewind request/response and snapshot info types on the bridge interface. |
| packages/acp-bridge/src/status.ts | Registers new status/control extMethod constants for rewind snapshots + rewind control. |
| packages/cli/src/acp-integration/acpAgent.ts | Implements extMethod handlers for listing rewind snapshots and rewinding via promptId (plus optional file rewind). |
| packages/cli/src/acp-integration/acpAgent.test.ts | Updates/extends tests to reflect the new rewind response shape and setup requirements. |
| packages/cli/src/serve/capabilities.ts | Registers the session_rewind capability tag in the serve capability registry. |
| packages/cli/src/serve/httpAcpBridge.ts | Adds bridge methods to call the new ACP extMethods, publishes session_rewound, and maps rewind-related errors. |
| packages/cli/src/serve/server.ts | Adds the new HTTP routes and maps new errors to HTTP status codes. |
| packages/cli/src/serve/server.test.ts | Updates capability registry ordering expectations to include session_rewind. |
| packages/cli/src/ui/commands/rewindCommand.ts | Enables /rewind command for ACP mode (supportedModes: ['interactive','acp']). |
| packages/sdk-typescript/src/daemon/DaemonClient.ts | Adds SDK HTTP helpers for listing rewind snapshots and triggering rewinds. |
| packages/sdk-typescript/src/daemon/DaemonSessionClient.ts | Adds per-session convenience wrappers (getRewindSnapshots, rewind). |
| packages/sdk-typescript/src/daemon/events.ts | Adds typed session_rewound event support + reducer state fields. |
| packages/sdk-typescript/src/daemon/index.ts | Re-exports the new rewind types/events from the daemon SDK entrypoint. |
| packages/sdk-typescript/src/daemon/types.ts | Introduces SDK wire types for rewind snapshots and rewind results. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
… endpoint
The slash command action returns `{ type: 'dialog' }` which ACP mode
converts to `unsupported`. ACP clients should use the dedicated HTTP
endpoints (GET /rewind/snapshots + POST /rewind) instead.
🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
Code Coverage Summary
CLI Package - Full Text ReportCore Package - Full Text ReportFor detailed HTML reports, please see the 'coverage-reports-22.x-ubuntu-latest' artifact from the main CI run. |
Aligns with the predicate style used by all other event type guards in the same module. 🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
Copilot review response summary
|
…d use strict auth gate
Two fixes from Codex review:
1. promptId suffix is 1-based (Session.turn incremented before
generating promptId) but rewindToTurn expects the count of turns
to KEEP (0-based). Snapshot N captures state before turn N, so
rewinding to it means keeping N-1 turns: turnIndex = parsed - 1.
2. POST /session/:id/rewind can modify/delete workspace files, so it
needs mutate({ strict: true }) like other file-mutating routes.
🤖 Generated with [Qwen Code](https://github.com/QwenLM/qwen-code)
|
Superseded by new PR targeting daemon_mode_b_main. |
What this PR does
Adds HTTP rewind endpoints (
GET /session/:id/rewind/snapshotsandPOST /session/:id/rewind) to the daemon so web-shell and SDK clients can rewind a session's conversation and files to a previous turn — replacing the TUI-only interactive dialog.Extends the existing
rewindSessionACP extMethod to also accept apromptIdparameter and perform file history rewind viaFileHistoryService. AddsSessionBusyError(409) andInvalidRewindTargetError(400) error classes for structured HTTP error responses. Publishes asession_rewoundSSE event for cross-client notification. SDK types, client methods, and event handling are included.Why it's needed
Issue #4514 T3.2:
/rewindis currently interactive-only (opens a TUI dialog). Web-shell and SDK clients have no way to rewind a session. The underlyingFileHistoryServiceis pure filesystem (no git dependency), so this can be exposed over HTTP without a new checkpoint substrate.Reviewer Test Plan
How to verify
npm run dev:daemonGET /session/$SID/rewind/snapshots— verify non-empty list with per-turn diff statsPOST /session/$SID/rewindwith a validpromptIdfrom the list — verify files restored, conversation truncated,session_rewoundevent on SSEPOST /session/$SID/rewindwith an invalid promptId — verify 400POST /session/$SID/rewindwhile a prompt is running — verify 409Evidence (Before & After)
N/A — new HTTP endpoints, no UI changes.
Tested on
Environment (optional)
Local
npm run dev:daemon+curl.Risk & Scope
getDiffStatsfor all snapshots (up to 100) inPromise.all— acceptable for MVP but may need pagination for long sessions./restore(depends on gitService, planned for deprecation). Unrewind/unrevert not implemented per design decision.rewindSessionextMethod callers (VSCode extension) are backward-compatible — oldtargetTurnIndexparam still works whenpromptIdis absent.Linked Issues
Closes T3.2 of #4514.
中文说明
为 daemon 新增 HTTP rewind 端点(
GET /session/:id/rewind/snapshots和POST /session/:id/rewind),使 web-shell 和 SDK 客户端能将会话的对话和文件回退到之前的 turn,替代仅 TUI 可用的交互式对话框。扩展已有的
rewindSessionACP extMethod 以支持promptId参数和通过FileHistoryService进行文件历史回退。新增SessionBusyError(409)和InvalidRewindTargetError(400)错误类用于结构化 HTTP 错误响应。成功后发布session_rewoundSSE 事件用于跨客户端通知。包含 SDK 类型、客户端方法和事件处理。动机:Issue #4514 T3.2 —
/rewind当前仅支持交互模式(打开 TUI 对话框),web-shell 和 SDK 客户端无法回退会话。底层FileHistoryService是纯文件系统操作(不依赖 git),可以直接通过 HTTP 暴露。🤖 Generated with Qwen Code