ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Qwen Code WebShell 独立会话(Standalone Chats)产品化落地指南:从显式会话上下文到完整聊天产品 UI

Qwen Code WebShell 独立会话(Standalone Chats)产品化落地指南:从显式会话上下文到完整聊天产品 UI Qwen Code WebShell 独立会话Standalone Chats产品化落地指南从显式会话上下文到完整聊天产品 UI【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code本文是 Qwen Code 仓库中docs/plans/2026-08-29-standalone-pr6-webshell-ui.mdPR6的技术实现解析围绕如何把 PR5 交付的显式 daemon 会话上下文{ kind: standalone }转化为 WebShell 中可见、可操作、可维护的独立聊天产品展开。读完本文你将掌握独立会话与工作区会话在入口路由、能力协商、延迟创建、Recents 生命周期、项目专属表面隐藏、深链解析、异常状态呈现等七个层面的完整实现方案以及对应的源码位置、契约边界与验证策略可直接用于理解或评审packages/web-shell中的独立会话功能。一、背景与目标为什么需要 Standalone Chats在独立会话功能出现之前Qwen Code daemon 在客户端未传cwd创建会话时会隐式地把主工作区primary workspace当作目标。这带来两个问题见 standalone-daemon-sessions.md 的 Problem 小节顶层 New Chat 被项目绑定即使用户没有选择任何项目新建会话依然落在某个项目目录上会话生命周期被项目目录绑架目录一旦被移动或删除客户端只能报告当前工作目录不存在无法继续会话。PR6 的目标是把 PR5 已在 daemon/SDK/provider 层就绪的独立会话能力变成 WebShell 中的完整产品Home 与全局 New Chat 创建独立会话在具备能力的 daemon 上项目作用域的入口保持工作区绑定新增顶层 Recents 分组对独立会话执行完整生命周期管理重命名、导出、归档、删除等独立聊天隐藏所有项目专属表面Git 状态、分支、项目文件、pin/group 等任何情况下都不回退到主工作区——除非 daemon 缺少standalone_sessions_v1能力。PR6 是纯 UI 改动只涉及packages/web-shell不新增 daemon 路由不新增 SDK 方法。这是 #9811 WebShell cutoverfe34a5cf22把 PR5 的 provider 表面从packages/webui迁入packages/web-shell/client/daemon/session/之后才可能实现的——provider 与产品 UI 同包不存在跨包发布顺序问题。二、PR6 消费的合并契约daemon / SDK / provider 三层PR6 本身不加契约只消费 PR3/PR4/PR5 已合并到origin/main的 v1 契约。理解这三层是读懂后续 UI 逻辑的前提。2.1 Daemon 层packages/cli/src/serve路由由 registerStandaloneSessionRoutes 注册核心路由族包括方法路径说明POST / GET/standalone/sessions创建 / 分页列表cursor、size、archiveState过滤GET/standalone/sessions/:id精确查找返回 summary 或creating状态POST/standalone/sessions/:id/load加载POST/standalone/sessions/:id/resume恢复POST/standalone/sessions/:id/repair-directory修复私有工作目录PATCH/standalone/sessions/:id/metadata重命名等元数据修改GET/standalone/sessions/:id/export导出POST/standalone/sessions/:id/archive/unarchive归档 / 取消归档批量POST/standalone/sessions/:id/delete删除批量能力标签standalone_sessions_v1在 capabilities.ts 注册只有在完整依赖集manager、service、route、managed-directory 生命周期、内嵌createServeApp配置全部安装时才对外宣告——单一构建常量不足以宣告该能力。契约的严格性体现在请求体校验daemon 侧用requireExactBody对创建请求做白名单校验只允许sessionId、modelServiceId、approvalMode三个字段见 standalone-sessions.ts。任何 workspace-only 请求键cwd、workspaceCwd、sourceType、sourceId、sessionScope、branch、worktree都会得到400 invalid_request。2.2 SDK 层packages/sdk-typescript/src/daemonstandalone-sessions.ts 定义了能力常量与完整类型表面STANDALONE_SESSIONS_CAPABILITY standalone_sessions_v1另有STANDALONE_SESSION_OPTIONS_CAPABILITYDaemonClient提供createStandaloneSession、listStandaloneSessions(Page)、getStandaloneSession精确查找creating / summary / not-found 三态、loadStandaloneSession、resumeStandaloneSession、repairStandaloneSessionDirectory、renameStandaloneSession、exportStandaloneSession、archiveStandaloneSessions、unarchiveStandaloneSessions、deleteStandaloneSessions所有独立会话方法都是能力门控的capability-gatedcreateStandaloneSession由客户端生成 UUID从不自动重试响应丢失时包装为DaemonStandaloneCreationOutcomeUnknownError携带sessionId与精确查找用的recovery信息——这是后面创建结果未知恢复状态机的 SDK 基础批处理方法返回部分成功信封归档返回archived / alreadyArchived / notFound / errors删除返回removed / notFound / errors / fileCleanupPending即使 HTTP 200 也可能是部分成功DaemonSessionClient.createStandalone / loadStandalone / resumeStandalone静态方法与{ kind: standalone }恢复策略位于 DaemonSessionClient.ts恢复分派在 :710。2.3 Session Provider 层packages/web-shell/client/daemon/sessionpost-#9811DaemonProductSessionContexttypes.ts:71是一个判别联合{ kind: workspace; cwd } | { kind: standalone } | { kind: live }DaemonSessionProviderProps.sessionContexttypes.ts:160与遗留的workspaceCwd并存两者冲突时在任何请求发出前直接抛错createSession / loadSession / resumeSession动作接受options.sessionContexttypes.ts:438-471。独立会话创建不重试且豁免通用的 30 秒动作超时Live 创建被此 provider 拒绝独立创建通道createDetachedStandaloneSessionDaemonSessionProvider.tsx:3968只把modelServiceId和approvalMode转发给DaemonSessionClient.createStandalone——workspace-only 字段永远不会到达 daemon连接状态暴露sessionContext与standaloneSession?: DaemonStandaloneConnectionState{ projectlessOutputDirectory?, workingDirectory?, creationRecovery?, errorCode? }目录错误码被复制进standaloneSession.errorCode供 UI 分支session-context.ts提供resolveProviderSessionContext、resolveActionSessionContext、sessionContextKey、restoreSessionContextMatches、getDaemonErrorCode、isDaemonErrorExplicitlyNonRetryable、getStandaloneConnectionState等辅助函数PR5 的隔离保证已内建standalone/Live 会话在 provider 内跳过工作区 providers、skills、ACP preheat、Git status 与工作区事件失效。三、入口点路由每个可见入口绑定显式上下文PR6 把每个可见入口点接到显式上下文表来自设计契约standalone-daemon-sessions.md入口点新会话上下文Home / 全局 New Chatstandalone已选择或锁定项目内的 New ChatworkspaceGoals 与 Git 入口workspace当前会话的 New Chat继承显式上下文Live Voicelive实施映射packages/web-shell/client以下行号以 #9811 cutover 后的origin/main为准Home / 全局 New Chat侧边栏主导航handleNewSession()WebShellSidebar.tsx→createNewSession()App.tsx。具备能力时设置 pending context{ kind: standalone }Home 首条 prompt 路径ensureSessionForPromptApp.tsx:6179消费 pending context而非解析 locked/selected/primary cwd独立创建省略 workspace-only 字段createAndAttachSessionForPrompt总是传sourceType: WEB_SHELL_SESSION_SOURCE_TYPE可能传worktree/branch——daemon 路由与 provider 独立通道都拒绝这些字段因此创建流程分支standalone pending context 只 dispatchcreateSession({ sessionContext: { kind: standalone }, approvalMode? })测试会断言两个分支的精确请求体每个新会话调用方都传显式意图全局 New Chat、当前会话 New Chat、/new、/clear、新会话建议、shell API 都汇聚到同一个createNewSession()。调用方契约变成显式意图{ kind: global }Home/全局 New Chat → 具备能力时 standalone、{ kind: inherit }当前会话入口、或{ kind: workspace, cwd }项目 New Chat、Goals。意图绝不从 undefined cwd 或当前状态推断项目作用域 New ChathandleNewSession(wsCwd)WebShellSidebar.tsx:5514→createNewSession({ kind: workspace, cwd: wsCwd })GoalsonCreateGoalApp.tsx:13223先按现状解析目标 cwdlocked ?? selected ?? primary再调createNewSession({ kind: workspace, cwd: resolved }, { keepView: true })ensureSessionForPrompt保持工作区绑定忽略任何 standalone pending context绝不传裸undefinedcwdGitresolveSessionForWorkspaceApp.tsx:6661与 composer Git chips由gitModeEligible门控App.tsx:6763保持工作区绑定Scheduled Tasks 等工作区维护调用方ScheduledTasksDialog.onCreateViaChat解析显式工作区 cwd 并传{ kind: workspace, cwd }——持久化独立会话调度超出范围活跃 standalone 上下文绝不能在此选 inherit/global当前会话 New Chat{ kind: inherit }继承活跃connection.sessionContext——standalone → pending standaloneworkspace → 带当前 cwd 的 pending workspace。Live 当前会话走既有 Live 专属startLive(new)路径client/live/useLiveVoice绝不静默改道为 standaloneSplit View 在 PR6 中排除 standalone 会话所有入口pane 身份以裸sessionId字符串持久化split URL、sessionStoragepane 归属从工作区 catalog 推导。只挡 Recents 行不够——全局 footer 按钮、?split、sessionStorage 恢复、外部受控splitSessionIds都能注入裸 standalone ID。PR6 对非工作区有效上下文禁用全局 Split View 入口并在所有 seed/URL/storage/受控 prop 边界用fail-closed 的异步分类器在 pane 挂载前清洗 standalone ID具备能力的 daemon 上未映射 ID 用getStandaloneSession精确核查——standalone 或creatingID 被拒绝只有404才继续走工作区归属解析上下文传播WorkspaceSessionProviderWorkspaceSessionProvider.tsx改传解析后的sessionContextpropprovider 在兼容边界归一化遗留 cwd两种形式在 cutover 期间都有效加载既有会话loadSidebarSessionApp.tsx:9114对 standalone 条目调用loadSession(id, { sessionContext: { kind: standalone } })。只传workspaceCwd的遗留调用方保持现状行为不变。四、能力协商的三态行为capability dual behavior能力读取必须来自useWorkspace().capabilities.features——DaemonWorkspaceProvider在启动时任何会话存在之前调用一次client.capabilities()因此入口点在会话之前触发不能依赖会话作用域的connection.capabilities。比较对象是qwen-code/sdk/daemon的STANDALONE_SESSIONS_CAPABILITY。能力值是三态的且只有一种状态允许回退到遗留行为状态行为Loading启动请求在途capabilities undefinedHome 与全局 New Chat等待——standalone 决策被禁用而非默认化。把 loading 当 absent 处理会在具备能力的 daemon 上静默创建主工作区会话Loaded-absent旧 daemon保留遗留行为全局 New Chat 指向主工作区不调用任何 standalone 路由允许提示独立聊天需要升级 daemonLoad errorfail-closed显式重试能力解析前不创建任何上下文的会话Loaded-present但创建失败展示结构化错误并保留 standalone 意图供重试。503归属/运行时失败或409目录冲突后绝不静默创建主工作区会话绝不降级上下文五、延迟创建与 Pending ContextWebShell 采用惰性创建Home 流程中createNewSession只清空界面ensureSessionForPrompt在提交时才真正物化 daemon 会话。PR6 在此延迟意图旁存储显式 pending contextApp 级新增pendingSessionContext: DaemonProductSessionContext | undefined状态App.tsx由上述每个入口点设置。pending context 是DaemonProductSessionContext绝不是裸undefinedcwd——还没有 cwd不等于 standalone 语义ensureSessionForPromptApp.tsx:6179优先消费 pending context{ kind: standalone }→ standalone 创建分支无 workspace-only 字段工作区 pending context → 沿用精确 cwd 路径无 → 遗留 locked/selected/primary 解析pending context 在 attach 提交前一直保持权威普通409/503创建失败不发布 standalone 连接上下文且被清空的 provider 可能仍持有旧工作区上下文——所以路由与草稿 UI 门禁读取pendingSessionContext ?? connection.sessionContextpending 状态只在 create-and-attach 成功完成后清除失败尝试保留 pending standalone 意图及其错误供重试loadSidebarSession/switchWorkspaceApp.tsx:8703用已加载会话的显式上下文覆盖pending contextprovider 自身的延迟路径shouldDeferInitialSessionCreation在底层保持不变。六、Recents 分组与生命周期操作6.1 独立 catalog 通道侧边栏新增顶层Recents分组StandaloneRecents.tsx挂载于 WebShellSidebar.tsx。现状不存在跨上下文列表useScopedSessions/useWebShellSessionssession-catalog/session-catalog-hooks.ts以SessionCatalogQuery { routeKind, workspaceCwd }session-catalog/session-catalog-store.ts:11为键天然按工作区作用域。PR6 新增独立 catalog 通道由listStandaloneSessionsPage游标分页 archiveState过滤供数而不是把 standalone 行塞进工作区 catalog store。Live 会话与项目会话保留各自分组standalone 子会话带parentSessionId的 sub-session永不出现。6.2 内部 cwd 永不泄露独立会话摘要仍保留内部workspaceCwd用于协议路由而既有 session-details 行会把workspaceCwd渲染成项目文件夹。因此 Recents 行使用standalone 专属视图模型彻底丢弃workspaceCwd并使用 standalone 专属动作分发绝不把它传给项目详情、导航或工作区解析器。6.3 逐会话操作复用既有WebShellSidebarSessionActionItem菜单模式WebShellSidebar.tsx:270details | rename | export | delete | pin | archive但分发到 standalone SDK 路由rename→renameStandaloneSessionexport→exportStandaloneSessionarchive / unarchive→ 批量路由delete→deleteStandaloneSessionsworkspace-only 动作pin、group在 standalone 行上不提供。删除保留既有二次确认对话框模式DeleteSessionDialog并说明转录与私有文件会被移除。成功后即使响应携带fileCleanupPending会话也离开 Recents该子集以非阻塞提示呈现而非阻塞错误。6.4 已归档会话保持可达懒加载的 Archived 分区增加 standalonearchiveStatearchived通道——该分区目前只由工作区 catalog 支撑而 umbrella 契约要求已归档独立会话保持可见。由于 PR5 刻意跳过 standalone 上下文的工作区事件失效standalone 通道在创建、prompt 完成与每次生命周期操作后显式刷新。6.5 批量结果的逐 ID 解读archive、unarchive、delete 即使 HTTP 200 也返回部分成功信封。catalog 只在目标 ID 出现在对应数组时更新archived/alreadyArchived、unarchived/alreadyActive、removed/notFoundID 出现在errors中则保留行并展示逐会话 code/message。fileCleanupPending只是对已移除 ID 的附加提示。七、项目专属表面隐藏Project-Only Surface Hiding在 standalone或 Live聊天中隐藏工作区/项目选择器、Git 状态/分支/worktree 控件、项目文件浏览器、项目设置、pin/group 控件、附件/上传standalone MVP 排除上传。保留模型、审批、工具、权限、转录与受支持的元数据控件。7.1 门禁基于有效上下文门禁条件为pendingSessionContext ?? connection.sessionContext——草稿 standalone 聊天在会话存在之前就隐藏项目表面绝不依据 cwd 是否存在。既有可扩展模式是ordinaryWorkspaces/isKnownLiveWorkspaceCwdApp.tsx:2401-2405已为 Live 运行时隐藏项目 UIPR6 把它泛化为当前聊天不是工作区上下文。7.2 Composer 状态隔离不只是隐藏清空工作区会话会保留connection.commands/skillscreateNewSession无 cwd 时会重载主工作区 skillsatWorkspaceCwd在无会话时回退到主工作区——所以useComposerCore会选中工作区作用域的草稿与输入历史键在 standalone 草稿中暴露项目命令/skills。因此commands、skills、atWorkspaceCwd、composer 存储身份全部从有效产品上下文推导——standalone 草稿跳过工作区 skill 重载attach 前只保留本地内建命令使用 standalone 专属草稿/历史身份无主工作区回退attach 后只用 standalone 会话支持的会话数据。7.3 工作区效果与斜杠命令门禁无会话的 App 从 locked/selected/primary 推导activeWorkspaceCwd并启动 Git-status effect/diff、/log、/prs、/settings、/schedule、/memory add可能打开或默认落入工作区作用域流程——光隐藏控件不够。workspace-eligible cwd 只在effectiveContext.kind workspace时推导并门控后台效果、命令发现与提交时 handler测试断言 pending 与 attached standalone 上下文产生零工作区请求或面板。7.4 通用转录分支排除/branch与逐消息 Branch 动作调用POST /session/:id/branch该路由以rejectStandalone: true注册packages/cli/src/serve/routes/session.ts——对 standalone 会话确定性失败。Pending 与 attached standalone 上下文省略 Branch 动作、从命令发现中移除/branch、阻止其提交时 handler。/fork保持独立——受保护的守卫式后台 fork-agent 工作仍受支持。7.5 工作区 Web Terminal 门禁webTerminalAvailableApp.tsx:3206原本只查web_terminal能力但 standalone 连接不暴露产品级workspaceCwdTerminalPanel会在无 cwd 时打开 terminal 路由daemon 以Terminal workspace unavailable拒绝。因此terminal 可用性与打开 handler 要求effectiveContext.kind workspace进入非工作区上下文时丢弃或关闭继承的 terminal 标签页。standalone 会话仍通过会话权限管道在私有目录运行普通 Shell/tool 命令——此处只门禁独立 terminal 表面。7.6 输入历史回退禁用useComposerCore/useInputHistory在作用域历史为空时回退到无作用域的qwen-web-shell-history键——单独用 standalone 专属键仍会暴露工作区时代的历史提示。回退策略变为产品上下文感知非工作区历史身份不做 legacy/global 回退。7.7 组件清单与上传双通道组件清单origin/maincomposer 工作区选择器components/WorkspaceSelector.tsx渲染于ChatEditor.tsx:3116Git chips/popoversGitBranchIndicator、GitModePopover、BranchPickerPopover由gitBranchVisible门控ChatEditor.tsx:2435Git 对话框GitDialog等项目设置面板openPanel(settings) 工作区作用域useSettings-mention 文件浏览器components/AtMentionPanel.tsx、hooks/useAtMentionMenu.tspin/group 控件SESSION_ORGANIZATION_FEATURE侧边栏分组。上传有两条通道standalone MVP 都隐藏① 工作区文件上传——hooks/useFileUpload.ts→client.uploadWorkspaceFile经composer/AddMenu.tsx与 -panel Upload file 渲染已由fileUploadEnabled与workspace_file_upload能力 kill-switchChatEditor.tsx:1585-1588② 内联 prompt 附件——useComposerCore.ts的pastedImages/pastedFiles:1718-1719。通道 2 是会话作用域需要显式上下文检查而非能力检查。7.8 上下文切换时丢弃附件隐藏 paste/drop/upload 控件并不会清空useComposerCore已持有的pastedImages/pastedFilescreateNewSession也不会——工作区中添加的文件可能搭便车进入首条 standalone prompt。切换进 standalone 草稿时清空已持有附件并给出可见提示提交时的非工作区守卫阻止陈旧或程序化提供的附件进入 standalone 会话。Live 聊天通过同一门禁获得同等处理PR5 已在 provider 内为非工作区上下文跳过工作区 providers/skills/Git/preheat本 PR 只隐藏可见控件。八、深链Deep Links/session/ ?contextstandaloneWebShell 没有路由库main.tsxutils/sessionPath.ts拥有/session/id?workspaceworkspaceId方案getSessionIdFromUrl/getWorkspaceIdFromUrlmain.tsx:83-87parseSessionId/buildSessionPathnameApp 通过onSessionIdChangeApp.tsx:8282向上汇报上下文让main.tsx可以replaceStateURL。新 standalone 链接带显式上下文参数/session/id?contextstandalone无?workspace。UUID 在整个 daemon 内保留因此 context 标记的链接不可能与工作区会话冲突。遗留无上下文链接保持既有工作区解析——此功能前不存在 standalone 会话无需迁移。解析发生在根部、provider 挂载之前main.tsx把 URL sessionId 传进WorkspaceSessionProvider后者在 App 外挂载DaemonSessionProvider——若无显式上下文resolveProviderSessionContext会继承主工作区并在任何 App 级查找之前启动工作区恢复。因此根部解析并校验context通过WorkspaceSessionProvider传递显式上下文对contextstandalone抑制 provider 会话加载直到精确getStandaloneSession查找选定路由active summary→ 以{ kind: standalone }挂载 providerarchived summary 绝不直接加载getStandaloneSession对 active 与 archived 一视同仁返回 summary但 daemon 以session_archived拒绝 load/resume——流程先渲染归档状态、执行 Unarchive、校验目标 ID 出现在逐 ID 成功数组中然后才挂载并加载not-found→ 既有 missing-session UIconnection.missingSession→showMissingSessionState。绝不猜测主工作区冷加载测试断言零工作区加载请求。creating查找必须到达终态解析器以有界退避轮询精确查找如最多 30 秒、封顶次数然后停在显式Retry动作绝不在 resolving 状态永久悬挂。陈旧解析在开始加载前取消provider 的 generation guard 只对启动后的加载排序而精确查找与轮询发生在loadSession之前——迟到的creating轮询在用户打开另一会话后解析会启动一个错误获胜的加载。根部解析器provider 之上持有的 route-resolution token 在每次导航时失效并在每次轮询前与loadSession前立即检查。fail-closed 边界情形?contextstandalone携带冲突?workspace参数 → 拒绝而非调和不具备能力的 daemon → 显示需要升级 daemon状态不解析到任何地方具备能力但 Conversations 运行时不可用503→ 显示结构化错误与重试。onSessionIdChange变得上下文感知standalone 会话报告contextstandalone并丢弃workspaceId工作区与 Live 链接保留既有解析器。PR5 的切换语义已序列化跨上下文提交迟到的解析不会覆盖更新的目标。九、Standalone 状态呈现typed state 而非字符串解析PR6 渲染 PR5 的 typed 状态状态UI 行为standaloneSession.workingDirectory.state recreated警告转录幸存但之前的工作区文件未被恢复standaloneSession.errorCode working_directory_missing提供显式repairrepairStandaloneSessionDirectoryrepair 从不重放 prompt。这需要一处 provider/App 范围内的过渡改动当前sendPrompt的 catch 只把 prompt-admission409当作普通提示从不把 typed code 复制进standaloneSessionSDK repair 调用既不清理 provider 错误状态也不重载会话——PR6 在 prompt-admission 拒绝时捕获 typed code 进standaloneSession.errorCode把 Repair 所有者守卫到受影响会话成功后重载同一 standalone 会话仅在重载提交后清除错误standaloneSession.errorCode working_directory_compromisedfail-closed 阻塞状态服务拒绝复用已受损路径而非重建因此不提供 Repair——给用户终态指引导出转录、删除会话standaloneSession.creationRecovery结果未知恢复状态机。provider 把保留 UUID 作为connection.sessionId发布无附加会话因此ensureSessionForPrompt会对既有 ID no-op 而提交在空会话引用上失败——恢复未决期间普通提交与未确认的新会话动作都被阻塞。所有者守卫的Check Status动作执行精确查找对每个恢复状态转换creating→ 有界轮询existing→ 加载并 attach 同一 ID先按isArchived分支归档 summary 先渲染归档状态、Unarchive、校验逐 ID 成功数组、再加载因为 daemon 以session_archived拒绝直接加载absent→ 显式用户触发重试绝不自动创建unknown→ 持久恢复 UI删除响应携带fileCleanupPending非阻塞提示文件清理会自动完成转录已删除四个转换全部有测试覆盖包括冷链接与恢复路径上的归档 summary。十、兼容性与回滚无 daemon / SDK 变更PR6 是纯 UI基于已合并的 v1 契约旧 daemon→ 处处保留遗留主工作区行为旧 WebShell 对新 daemon→ 不变从不调用 standalone 路由post-#9811provider 与产品 UI 同包无跨包发布顺序顾虑。十一、验证策略单元 / 组件测试vitestpackages/web-shell覆盖要点包括路由表每一行的入口点→上下文映射含当前会话继承与 Live 经startLive(new)路由standalone 创建请求体精确断言无workspaceCwd/sourceType/worktree/branch能力三态loading 在任何上下文都不创建、loaded-absent 走遗留路径且零 standalone 请求——可用 e2emockDaemon请求日志断言、load error fail-closed 带重试具备能力但创建失败 → 渲染错误、pending standalone 意图保留且仍对门禁权威、不发出主工作区创建Recents 列表/重命名/导出/归档/取消归档/删除流程、子会话排除、fileCleanupPending移除语义、视图模型绝不向详情/导航暴露内部 cwd按有效上下文的表面隐藏含首条 prompt 前的草稿 standalone 聊天standalone 中上传不可用深链creating轮询到终态停在 Retry、冲突?workspace拒绝、无能力 daemon 显示升级状态、not-found 显示 missing-session UIrecreated警告、仅working_directory_missing提供 repair、working_directory_compromisedfail-closed 无 repair 动作prompt-admissionworking_directory_missing到达standaloneSession.errorCode、Repair 所有者守卫、成功重载并清除错误迟到的creating轮询被用户会话切换取消后不启动加载上下文切换清空持有附件并给可见提示、提交时守卫拒绝陈旧/程序化附件已归档 standalone 通道在生命周期操作后列出并刷新、部分成功批量信封按动作处理冷contextstandalone加载零工作区加载请求、解析在 provider 挂载前于根部完成每个新会话调用方传显式意图、无路径从 undefined cwd 或当前状态推断意图Split View 入口footer 非工作区禁用、?split/sessionStorage/受控 prop 注入在 pane 挂载前拒绝或清洗结果未知恢复四态转换、恢复未决期间阻塞普通提交、绝无自动重创建已归档精确查找 summary 绝不直接加载冷链接与结果恢复两路径都按isArchived分支、Unarchive 逐 ID 校验成功后再加载workspace→standalone 草稿过渡隔离 composer commands/skills/atWorkspaceCwd/草稿/输入历史含陈旧快照Split View 裸 ID 分类器延迟 catalog、standalone/creating拒绝、仅404继续工作区归属解析、受控宿主不能立即重新注入已清洗 IDpending 与 attached standalone 上下文零工作区请求或面板Git-status effect、/diff、/log、/prs、/settings、/schedule、/memory空 standalone 输入历史保持为空而 legacy 全局历史键有数据ScheduledTasksDialog.onCreateViaChat即使在活跃 standalone 上下文也强制工作区意图standalone 上下文省略 Branch 动作、移除/branch发现、阻止 handler——零通用 branch 请求/fork仍可用session-overview、/resume、/delete、/release入口从 pending 与 attached standalone 上下文隐藏或阻止standalone 会话的/resume id只经显式 standalone 上下文路由standalone 与 Live 上下文不创建 terminal WebSocket 并丢弃继承的 terminal 标签页工作区 terminal 不变。相关测试文件StandaloneRecents.test.tsxpackages/web-shell/client/components/sidebar/StandaloneRecents.test.tsx、main.test.tsx深链解析断言、utils/sessionPath.test.ts。E2EPlaywrightpackages/web-shell/client/e2e扩展utils/mockDaemon.ts场景增加standalone_sessions_v1能力开关与 standalone 路由族新增 web-shell.standalone.spec.tsHome New Chat → standalone 创建体断言项目 New Chat → workspace 创建Recents 生命周期能力 loading/absent/error 状态具备能力时失败但意图保留手工 E2E 计划记录于.qwen/e2e-tests/2026-08-29-webshell-standalone-chats.md按仓库工作流在 merge 前对真实qwen servedaemon 做 dry-run。常用命令cd packages/web-shell npx vitest run file # 聚焦测试 npm run verify # lint format:check typecheck test:ci npm run test:e2e # 根目录 npm run build npm run typecheck十二、范围边界PR6不新增standalone 附件/上传等待工作区上传后续、把 standalone 会话移入/派生进项目、持久化 standalone 调度、存储配额、子会话管理 UI。SessionOverviewPanel与ResumeDialog在本 PR 保持工作区作用域且所有入口都被门控裸/resume、/delete、/release挂载以lockedWorkspaceCwd为键的工作区对话框当其未定义时useScopedSessions选择主 WebShell catalog——所以/delete可能从 standalone 上下文作用于无关工作区会话。非工作区有效上下文隐藏或阻止侧边栏canOpenSessionsOverview入口、shellApi.openSessionOverview()与裸工作区对话框命令发出零遗留 catalog 或破坏性请求。顶层 Recents 分组只存在于侧边栏。Split View 保持 workspace-only上下文感知 pane 描述符是后续工作。范围内唯一的 provider 改动是 prompt-admission 错误码捕获 repair-and-reload 过渡Repair UI 依赖它provider 表面发现的其他 typed 缺口作为后续项提出。本 PR 不改变 daemon 生命周期行为、SDK 契约或 PR5 的 provider 切换语义。结语PR6 是独立会话从协议能力走向产品体验的关键一跳它以DaemonProductSessionContext判别联合为单一事实来源把入口路由、能力三态协商、延迟创建、Recents 生命周期、项目表面隐藏、深链解析与 typed 状态呈现串成一条不依赖workspaceCwd推断的完整链路并在每个可能回退到主工作区的边界 fail-closed。无论是评审代码还是二次开发本文梳理的 daemon 路由白名单、SDK 批量信封语义、pending context 权威性、Split View 分类器与结果未知恢复状态机都是理解packages/web-shell独立会话实现的最短路径。【免费下载链接】qwen-codeAn open-source AI coding agent that lives in your terminal.项目地址: https://gitcode.com/GitHub_Trending/qw/qwen-code创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进