Repository navigation
fix(app): keep chosen work views across reload and browser history - #5399
Conversation
Signed-off-by: huangruiteng <huangrt01@163.com>
huangruiteng
left a comment
There was a problem hiding this comment.
Approval conclusion (author-owned PR; GitHub blocks formal self-approval)
未发现阻塞问题。评审版本:78db8ad32a58eb2dcfb3d4e94691fe4ab39f575a;基线:3ad3269af4d2cfae2085693823dcfcda522f9a2b。原生 WebView 与真实接收方协作仍未在这次导航修复中验收。
动机
用户选择管家对话后刷新会回到总览,Goal 的工作页签也无法恢复;源加载还会追加重复历史记录,让返回键看起来失效。基线打包页面、相同合成数据和同一浏览器旅程复现了丢失对话位置。修复减少重复找回工作入口的操作,属于 R3 / handoff RFC §5.11 与 GQ07–GQ09 的可独立验收增量,不代表完整协作已闭环。
改动思路
复用 TanStack 路由作为可恢复的界面状态 owner。WorkspaceGoalTab 已存在,URL 保留原来的 conversation 值,增加既有其他视图。另建 localStorage 视图副本会引入同步问题;仅把管家初始值改为对话也不能解决 Goal 或历史导航。当前实现把 Goal 与视图一起切换,并删去会覆盖子视图的父级回调。commitLoadedStatus 只在源地址确实变化时导航,避免刷新制造无意义历史条目。没有新协调能力、工作状态 writer、后端协议或 Python 决策逻辑。
具体改动
router.tsx扩展已有视图参数;personal-workspace-model.ts的回调传递类型化视图。PersonalWorkspacePage使用受控视图,同时保留其无 router 独立使用时的局部状态;管家、Goal、会话与成果入口共用该路径。已检查唯一生产父调用与 drawer/sidebar/header 周边调用。DashboardPage将路由读回绑定到视图,原子地导航 Goal/视图,删除重复父导航;省略视图时保留既有首次进入行为。- 69 行
workspace-view-recovery场景覆盖刷新、前进/返回、草稿、Goal 身份、窄屏键盘和零 Turn/Goal 写入。以行为断言替换了依赖函数文本的 task-first 检查。现有 source-switch 测试明确指定中文 locale,保留源切换、存储故障和请求竞争检查。 - RFC / roadmap 明确界面恢复与接收方采用、steering、结果回传的验收边界。
对主干的风险
主要风险是切换 Goal 的同时发出两个互相覆盖的导航,或刷新再次产生重复历史。原子 Goal/视图回调与相同源导航抑制处理这两点;真实打包 router 的回退测试会捕捉该退化。零 Turn 请求及零 Goal apply 断言证明恢复界面不重放工作。新鲜入口的总览、侧栏 Goal 的任务优先和已有 conversation 链接保留,长期工作 owner 未变。
校验:chat bundle 构建及 TypeScript 检查通过;30 个打包 workspace 场景、打包 source-switch、workspace contract 通过;premerge 的 10 个 catalog、8 个 risk-profile 和 1 个边界检查通过。最初 premerge 缺少仓库根 TypeScript 依赖,按项目环境指引补齐后完整重跑通过;最初 source-switch 的浏览器语言假设已修正,未弱化业务断言。精确范围质量回执 cqr_c46f6485ff82cf37c29b 有效,safe-fix 一次,没有未解决 blocker。未轮询远端 CI、运行付费模型评测或变更活跃 Goal。
基线/修复后/窄屏视觉证据使用合成数据。全屏布局和控件不变,恢复的是用户已选工作视图。没有新增首屏呈现、确认步骤或状态文案。
我的整体评价
APPROVE。这是完整的导航恢复修复,边界小且可整体回滚。相关重构已在同一所有权边界移除重复状态与父导航,无需另造持久化框架。它仍是待合入的打包前端行为,本机 App 尚未安装这份代码;真实 managed/attached 接收方采用和原入口回传继续按现有 RFC 验收。根据仓库产品表面规则,交给维护者合并,不自行合并。
English verdict: APPROVE - 78db8ad. Existing typed routes restore chosen Manager/Goal views without replaying work; baseline regression, packaged browser journeys, source-switch fencing, typecheck, public-boundary checks and exact-scope premerge passed. Native WebView and live collaboration remain outside this navigation slice. Maintainer merge required.
loopx-project#5399 replaced the manager chat open/close state with the typed workspace view (`selectedGoalTab`) but left the ManagerHomeBoard's "view all operations" handler calling the removed `setManagerChatOpen`. The dashboard therefore no longer type-checks (`tsc --noEmit`, TS2552) and the button throws when clicked. Route the handler through the same typed view owner as the rest of the surface, so the operations tile opens the manager conversation instead of referencing a removed setter. No other loopx-project#5399 leftover is present. Signed-off-by: huangruiteng <huangrt01@163.com>



Goal And Delivered Outcome
Reloading a Manager conversation returned to the overview, and reloading a Goal lost the selected work view. Source loading could also insert a duplicate history entry, so Back appeared to do nothing.
The chosen conversation, tasks or artifacts view now lives in the existing typed workspace route. Reload and Back/Forward restore it while keeping the source, Goal and unsent draft. Navigation starts no model work and writes no Goal state. Fresh-entry defaults remain unchanged.
Anchor: overall roadmap R3 and handoff RFC §5.11, supporting GQ07–GQ09 continuity. Base:
mainat3ad3269af4d2cfae2085693823dcfcda522f9a2b.Scope And Continuation
Complete within the navigation repair: Manager and Goal share one route-owned view, with atomic Goal/view selection. Remove competing parent navigation and independent Manager-open state. Source reload avoids adding an unchanged URL to history. The existing Chinese source-switch fixture now explicitly requests
zh-CN; its request-fencing and storage-failure assertions are preserved.This is proposed packaged frontend behavior, not an installed App update or qualification of receiver adoption, steering, execution takeover or original-route result return. Those remain under the existing R3/§5.11 acceptance. No Lark or CLI behavior changes: navigation is owned by the frontend router and issues no control-plane mutation. No new capability, persisted work contract, Python decision owner or backend refactor.
Validation
78db8ad32a58eb2dcfb3d4e94691fe4ab39f575a(unchanged production sources from the validated bundle).uv run --extra test python scripts/chat_bundle.py build --installincludes dashboard TypeScript checking and source/asset verification.LOOPX_PERSONAL_WORKSPACE_PACKAGED=1 node examples/personal-workspace-browser-smoke.mjs: all 30 packaged browser scenarios passed. Real React/router and packaged HTTP entrypoint; domain API fixtures are synthetic.LOOPX_STATUS_SOURCE_SWITCH_PACKAGED=1 node examples/status-source-switch-browser-smoke.mjs: local/SSH selection, storage failures, request ordering and owning state readback. The initial unmodified run assumed Chinese while the browser selected English; explicit fixture locale repaired that test assumption.cqr_c46f6485ff82cf37c29bverified; one bounded safe-fix pass, no blockers.WorkspaceGoalTab.Coverage: both frontend callers and reload/history paths, not native WebView, paid model evaluation or live receiver adoption. No PostgreSQL owner or state transaction changed. Full viewport review preserves the existing layout and controls; only the chosen view is restored. No fresh first-screen presentation, primary CTA or opening navigation redesign.
Frontend / Visual Evidence
Type of Change
LoopX Area
Shared-authority RFC fixture impact
N/A: presentation routing only; no authority provider, migration, work-state writer or backend contract change.
Boundary Checklist