feat(serve): Add workspace-qualified session export - #6844
Conversation
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
Workspace-qualified session export E2EPurposeVerify that a daemon with two registered workspaces exports the selected active Baseline
This proves clients need the independent Setup
REST scenarios
Results
|
|
Thanks for the PR! Template looks good ✓ — all required sections present, bilingual body included. Problem: This is an observed architectural gap, not theoretical. The legacy export endpoint is intentionally primary-bound, so when the same session id exists in multiple workspaces, a client targeting a secondary workspace either gets a 404 or the wrong transcript. The PR describes a concrete two-workspace reproduction and the gap is a natural consequence of the multi-workspace session architecture. Direction: Aligned. Workspace-qualified export fills a real hole in the multi-workspace story — every other session route already has a workspace-qualified variant, and export was the outlier. Size: ~145 production additions + ~65 deletions = ~210 production lines. Test files: ~399 additions. Docs: ~116 additions. No core module paths ( Approach: Scope feels right. The PR extracts the existing export handler into a shared function and adds a new workspace-qualified route that goes through the same trust/resolution gate as every other plural session route. The SDK refactors the legacy export into the same shared request method. Design doc, docs updates, and comprehensive tests round it out. No scope creep. Moving on to code review. 🔍 中文说明感谢贡献! 模板完整 ✓ — 所有必需部分齐全,包含双语正文。 问题:这是一个已观测到的架构缺陷,而非理论性担忧。legacy export endpoint 按设计绑定 primary workspace,当多个 workspace 存在相同 session id 时,客户端访问 secondary workspace 要么得到 404,要么导出错误的 transcript。PR 描述了具体的双 workspace 复现方案,这个缺陷是多 workspace session 架构的自然结果。 方向:对齐。Workspace-qualified export 填补了多 workspace 故事中的真实空白 — 其他所有 session 路由都已有 workspace-qualified 变体,export 是唯一遗漏的。 规模:~145 行生产代码新增 + ~65 行删除 = ~210 行生产代码。测试文件:~399 行新增。文档:~116 行新增。未触及核心模块路径( 方案:范围合理。PR 将现有 export handler 提取为共享函数,新增一个经过与其他 plural session 路由相同的 trust/resolution 检查的 workspace-qualified 路由。SDK 将 legacy export 重构为使用同一共享请求方法。设计文档、文档更新和全面测试使方案更完整。无范围蔓延。 进入代码审查 🔍 — Qwen Code · qwen3.7-max Reviewed at |
Code ReviewIndependent proposal: add a The PR matches this proposal closely. The No correctness bugs, security holes, or convention violations found. The Test ResultsAll unit tests pass on the PR branch:
Real-Scenario Testing (tmux)Started the PR-built daemon with two workspaces ( The error-handling paths all work correctly in the real daemon: invalid format → 400, unknown workspace → 400, missing session → 404. The session-finding 404s in tests 2-3 are fixture path issues — the Storage class computes project directory names differently from my seeded paths (not a code bug). The 1,036 unit tests with proper Storage-backed fixtures cover the happy path comprehensively. 中文说明代码审查独立方案:添加 PR 的实现与此方案高度一致。 未发现正确性 bug、安全漏洞或违反项目约定。 测试结果所有单元测试在 PR 分支上通过:
真实场景测试(tmux)用两个 workspace 启动 PR 构建的 daemon,通过 curl 测试 API 端点。错误处理路径全部正确:invalid format → 400,unknown workspace → 400,missing session → 404。测试 2-3 中的 session 未找到 404 是 fixture 路径问题(Storage 类的项目目录命名方式与手动种子路径不同,非代码 bug)。1,036 个使用正确 Storage-backed fixture 的单元测试全面覆盖了正常路径。 — Qwen Code · qwen3.7-max Reviewed at |
|
Confidence: 4/5 — Clean, focused implementation that fills a real gap in the multi-workspace story. The only reservation is that I couldn't seed session fixtures through the live daemon's Storage layer for tmux happy-path testing, but the 1,036 unit tests with proper fixtures cover the scenarios comprehensively. This PR does exactly one thing: it adds a workspace-qualified export endpoint so clients can explicitly target a trusted registered workspace instead of being stuck with the primary-bound legacy route. The implementation is a textbook extraction — shared handler, same trust gate, same format contract, same archive coordination. The SDK method forces native REST even with ACP transport, which is the right call for a data-export endpoint. The capability tag is independent and correctly non-inferrable from existing tags. No scope creep, no drive-by refactors, no unnecessary abstractions. The design doc explains the alternatives rejected and why. Tests are thorough and well-organized. Build and typecheck pass. The one thing I couldn't fully verify end-to-end was seeding a session through the daemon's Storage class and then exporting it via curl — my fixture paths didn't match the Storage class's directory naming. But this is a test-harness limitation, not a code concern, and the unit tests (which use the real Storage class) cover this path exhaustively. LGTM. 🚢 中文说明置信度:4/5 — 干净、聚焦的实现,填补了多 workspace 故事中的真实空白。唯一的保留是我无法通过 live daemon 的 Storage 层在 tmux 中成功种子化 session fixture 来测试正常路径,但 1,036 个使用正确 fixture 的单元测试全面覆盖了这些场景。 这个 PR 只做一件事:添加 workspace-qualified export endpoint,让客户端可以显式选择 trusted registered workspace,而不是被 legacy 路由绑定到 primary。实现是教科书式的提取 — 共享 handler、相同的 trust gate、相同的 format 契约、相同的 archive 协调。SDK 方法即使有 ACP transport 也强制使用 native REST,对于数据导出端点来说这是正确选择。Capability tag 独立且正确地从现有 tag 不可推断。 无范围蔓延、无顺手重构、无不必要的抽象。设计文档解释了被拒绝的替代方案及原因。测试全面且组织良好。Build 和 typecheck 通过。 唯一无法完全端到端验证的是通过 daemon 的 Storage 类种子化 session 然后通过 curl 导出 — 我的 fixture 路径与 Storage 类的目录命名不匹配。但这是测试工具的限制,不是代码问题,单元测试(使用真实 Storage 类)彻底覆盖了这条路径。 可以合入。🚢 — Qwen Code · qwen3.7-max Reviewed at |
qwen-code-ci-bot
left a comment
There was a problem hiding this comment.
LGTM, looks ready to ship. ✅
Maintainer verification — local build + real tests ✅Built PR head Environment: macOS 15.7.7 (arm64), Node v22.23.1, npm 10.9.8. Baseline captured with the globally installed 1. PR-touched tests + static checksRan every test file the PR changes, against the PR head, in the isolated worktree — plus
2. Live REST E2E — real bundled daemon, two registered workspaces
What this independently confirms:
VerdictFrom a verification standpoint this is safe to merge: additive route + capability, legacy behavior unchanged, trust/isolation enforced, full error contract and selector precedence confirmed on a real daemon. No regressions or gaps found. 中文说明(点击展开)维护者验证 — 本地构建 + 真实测试 ✅在隔离 worktree 中构建 PR head 环境: macOS 15.7.7 (arm64)、Node v22.23.1、npm 10.9.8。baseline 使用全局安装的 1. PR 改动涉及的测试 + 静态检查在隔离 worktree 中针对 PR head 运行了本 PR 改动的每个测试文件,并对改动文件执行
2. Live REST E2E — 真实 bundle 守护进程 + 两个注册 workspace
本次独立确认的内容:
结论从验证角度可以安全合并:路由与 capability 均为增量新增,legacy 行为不变,trust/隔离已强制执行,完整错误契约与 selector 优先级已在真实守护进程上确认,未发现回归或缺口。 |
wenshao
left a comment
There was a problem hiding this comment.
Reviewed — no blockers. Suggestions are inline.
— qwen3.7-max via Qwen Code /review
| const handleSessionExport = async ( | ||
| req: Request, | ||
| res: Response, | ||
| target: { | ||
| route: string; | ||
| workspaceCwd: string; | ||
| workspaceQualified?: boolean; | ||
| }, |
There was a problem hiding this comment.
[Suggestion] handleSessionExport has no trust precondition in its signature — it relies entirely on the caller to have already called requireTrustedRuntimeForWorkspaceRoute. A future developer adding a third caller could bypass the trust gate unknowingly.
Concrete cost: the function signature gives no compiler-enforced hint that trust must be pre-checked. Consider accepting a trusted: true literal or a branded RuntimeVerified type on target so the precondition is visible at the call site.
— qwen3.7-max via Qwen Code /review
Co-authored-by: Qwen-Coder <qwen-coder@alibabacloud.com>
|
@qwen-code /triage |
|
@qwen-code /resolve |
1 similar comment
|
@qwen-code /resolve |
Resolve conflict in qwen-serve-protocol.md by combining both sides: - main: 'tool toggle' → 'tool and skill toggles' (workspace skill toggle API) - PR: add workspace-qualified session export exclusion and pre-flight note
|
Qwen Code resolved the merge conflicts and pushed the branch update. Merge Conflict Resolution Summary — PR #6844ConflictFile: Both Changes from each sidemain (6 new commits)
PR branch (HEAD)
ResolutionCombined both changes in the single paragraph:
No other files conflicted. The other 5 files auto-merged cleanly. Commit
|
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 #6844Merge performed
Conflicts and resolutions1.
|
|
⏸️ Head moved during review — the PR branch merged My Stage 1–3 review above remains valid for the commit I reviewed ( 中文说明⏸️ 审查期间 head 发生了变更 — PR 分支在我审查 commit 上面的 Stage 1-3 审查对我审查的 commit( — Qwen Code · qwen3.7-max |


What this PR does
This PR adds a workspace-qualified session export endpoint for active persisted sessions. Callers can select a registered workspace by id or URL-encoded absolute cwd and export
html,md,json, orjsonl; the selected runtime must be trusted, and the request never searches another workspace, falls back to primary, resolves a live owner, or starts ACP. The existing primary-bound export remains compatible and shares the same format validation, archive coordination, response headers, filename handling, and transcript exporter.It also advertises the independent
workspace_session_exportcapability, adds a native-REST TypeScript SDK method on workspace clients, attributes telemetry to the selected workspace, and documents the route, trust model, compatibility contract, and verification coverage. WebShell is intentionally unchanged and remains primary-export-only.Why it's needed
The legacy export endpoint is intentionally bound to the primary workspace. A client exporting a session listed under a trusted secondary workspace can therefore receive a 404 or, when the same session id exists in both workspaces, export the primary transcript instead. An explicit workspace-qualified route makes storage ownership deterministic and lets clients safely pre-flight support without inferring it from older capabilities.
Reviewer Test Plan
How to verify
404 session_not_foundwithout fallback or bridge/ACP activity.409 session_archived,400 invalid_export_format,400 workspace_mismatch, and403 untrusted_workspacerespectively, with workspace resolution and trust taking precedence over session and format validation.workspaceById(...).exportSession(...)orworkspaceByCwd(...).exportSession(...)on a client configured with an ACP transport; the request should still use native REST and preserve bearer token, client id, timeout, attachment filename, MIME type, and non-2xx error parsing.Evidence (Before & After)
N/A — this PR does not change WebShell or TUI behavior. Before, secondary export had no workspace-qualified API and the legacy action remained primary-bound; after, REST and SDK callers can explicitly export a trusted registered workspace while WebShell remains primary-export-only.
Tested on
Environment (optional)
macOS 26.4.1 arm64, Node.js 22.22.3, npm 10.9.8. Verification used the locally built bundle, isolated runtime/workspace directories, deterministic persisted JSONL fixtures, and global
qwen0.19.9 for the pre-change baseline.Risk & Scope
workspace_session_exportwhen talking to older daemons.Linked Issues
Related to #6378
中文说明
本 PR 的作用
本 PR 为 active persisted session 新增 workspace-qualified export endpoint。调用方可以通过注册 workspace id 或 URL 编码的绝对 cwd 选择 workspace,并导出
html、md、json或jsonl;所选 runtime 必须可信,请求不会扫描其他 workspace、回退 primary、解析 live owner 或启动 ACP。现有绑定 primary 的 export 保持兼容,并与新路由共用 format 校验、archive 协调、响应 header、filename 处理和 transcript exporter。同时新增独立的
workspace_session_exportcapability、workspace client 上始终使用 native REST 的 TypeScript SDK 方法、归属于所选 workspace 的 telemetry,并补充 route、trust model、兼容契约和验证范围文档。WebShell 明确不在本次变更范围内,继续仅支持 primary export。为什么需要
legacy export endpoint 按设计绑定 primary workspace。客户端导出 trusted secondary workspace 下列出的 session 时,可能得到 404;当两个 workspace 存在相同 session id 时,还可能错误导出 primary transcript。显式 workspace-qualified route 让存储归属具有确定性,并允许客户端通过独立 capability 安全地预检支持情况,而不是从旧 capability 推断。
Reviewer Test Plan
如何验证
404 session_not_found,且不发生 fallback、bridge 或 ACP 活动。409 session_archived、400 invalid_export_format、400 workspace_mismatch和403 untrusted_workspace,其中 workspace 解析与 trust 检查优先于 session 和 format 校验。workspaceById(...).exportSession(...)或workspaceByCwd(...).exportSession(...);请求仍应使用 native REST,并保留 bearer token、client id、timeout、attachment filename、MIME type 和非 2xx 错误解析行为。Evidence(Before & After)
N/A — 本 PR 不改变 WebShell 或 TUI 行为。变更前 secondary export 没有 workspace-qualified API,legacy action 仍绑定 primary;变更后 REST 和 SDK 调用方可以显式导出 trusted registered workspace,而 WebShell 继续仅支持 primary export。
测试平台
环境(可选)
macOS 26.4.1 arm64,Node.js 22.22.3,npm 10.9.8。验证使用本地构建 bundle、隔离的 runtime/workspace 目录、确定性 persisted JSONL fixture,以及 global
qwen0.19.9 作为变更前 baseline。风险与范围
workspace_session_export。关联 Issue
Related to #6378