Skip to content

fix(dashboard): readable Explore thirds and Goal empty states - #7478

Open
huangruiteng wants to merge 5 commits into
mainfrom
codex/research-workspace-polish-20261026
Open

huangruiteng wants to merge 5 commits into
mainfrom
codex/research-workspace-polish-20261026

Conversation

@huangruiteng

@huangruiteng huangruiteng commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator

完整前端对照 · 20 组 / 40 张

快速查看:Goal 指标 · 管家简报 · 研究时间线 · 成果页 · 非视觉改动与边界。每组左侧为主干、右侧为本 PR;点图可查看原尺寸。展开项包含提示、英文及错误/未知状态的完整对照。

前端范围 覆盖的变化与细节
Goal 指标与样式 — → 未采集 / 暂无观测到的活动;完整空待决 0 → 暂无等待;空值取消跳转与 Tab 停靠,说明入口保留;有值与覆盖不全的对照
管家简报与 i18n 零执行、有安排时补充安排数量;中文说明宿主 App 线程负责;英文 queued 文案;桌面与窄屏
Explore 时间线 小于 6 小时归入“全程 / Whole run”;读法提示与阶段统计同步;长记录保留三段;原问题、结论、失败和未知仍可展开
成果页 可选索引 404/410 显示正常空态与刷新;500、HTML/非法 JSON 继续显示错误;桌面与窄屏

对照版本:Before 为目标主干 dd30e694a 的真实打包页面;After 为当前 PR ed6baf49b 的真实打包页面。两侧使用相同合成输入、视口和语言。这里统一使用目标主干对照,替换此前不同旧版本的分散截图。

桌面 1440×900;窄屏 390×844,HTML 错误长文另用 390×982 展示全文。使用公开 goal-showcase 组合及合成状态;时间线的 12 条合成事件经过真实 Explore SQLite/HTTP 读取 owner。状态、用量、队列和可选索引响应由隔离 HTTP fixture 提供。图中的交付检查失败、缺少分析包及委派接口未接入状态在两侧保留。这些图片验证打包页面,不代表已安装桌面 App,也不证明真实模型收益。

V1. Goal vitals

默认状态直接给出“暂无等待 / 未采集 / 暂无观测到的活动”,不再只用 0 与破折号。空值字体、颜色和悬停语义收敛;DOM 另读回 aria-disabled=true、tabIndex=-1,说明按钮仍可打开。工作总数和其他真实读数保持可见。

场景 Before · main After · PR
完整空待决 + 未采集用量/活动 · 桌面 01-vitals-desktop before 01-vitals-desktop after
相同空态 · 390px 02-vitals-phone before 02-vitals-phone after
展开指标细节:说明入口、已有用量、覆盖不完整(3 组)
场景 Before · main After · PR
成本说明展开 · 不删除解释 03-vitals-help before 03-vitals-help after
已有 3.7h / $18.40、1 项阻塞及 1 项可选 · 数值保留 04-vitals-measured before 04-vitals-measured after
部分记录、已列 0 项、最早时间未知 · 仍为未知,不显示暂无等待 05-vitals-partial-phone before 05-vitals-partial-phone after

V2. Manager brief

“正在执行”仍为 0;新增独立的“1 个已安排 · 由宿主 App 线程负责”。安排数量没有混入已观测执行数量。英文补充 1 queued。

场景 Before · main After · PR
仅安排、无执行 · 桌面 06-manager-desktop before 06-manager-desktop after
相同简报 · 390px 07-manager-phone before 07-manager-phone after
展开英文简报(1 组)
场景 Before · main After · PR
English · Running now 0 + 1 queued 08-manager-english before 08-manager-english after

V3. Explore timeline

同一份 5 分钟、6 条记录:前/中/后三张阅读卡收为一张“全程”,三条结论的确认/反驳/暂定状态仍保留。时间范围、密度和原记录数量不变。

场景 Before · main After · PR
5 分钟短记录 · 桌面 09-timeline-desktop before 09-timeline-desktop after
同一短记录 · 390px 10-timeline-phone before 10-timeline-phone after
展开英文、读法提示、长记录和原结论详情(5 组)
场景 Before · main After · PR
English · Early/Middle/Late → Whole run 11-timeline-english before 11-timeline-english after
读法说明 · 桌面 12-timeline-help before 12-timeline-help after
读法说明 · 390px,键盘焦点展开 13-timeline-help-phone before 13-timeline-help-phone after
20 小时长记录 · 仍为前/中/后三段 14-timeline-long before 14-timeline-long after
选中同一研究项 · 原问题、完整结论、状态与来源入口保留 15-timeline-detail-phone before 15-timeline-detail-phone after

V4. Research results

目标主干在可选索引 404/410 下显示错误;本 PR 显示“本 Goal 暂无可读取的公开研究成果”,刷新入口保留。500 与解码失败继续显示红色错误,不会被索引缺省规则吞掉。下图使用相同 HTTP 状态与响应正文。

场景 Before · main After · PR
HTTP 404 · 桌面 16-files-404-desktop before 16-files-404-desktop after
HTTP 404 · 390px,研究结果区域 17-files-404-phone before 17-files-404-phone after
展开 410、服务器错误和非法 JSON(3 组)
场景 Before · main After · PR
HTTP 410 · 与 404 相同的正常空态 18-files-410-phone before 18-files-410-phone after
HTTP 500 · 两侧都明确报错并保留刷新 19-files-500 before 19-files-500 after
HTTP 200 + HTML(正文含 HTTP 404 字样)· 两侧都报 JSON 错误,390×982 20-files-html-phone before 20-files-html-phone after

V5. Scope and observations

  • 本轮只更新 PR 说明和公开截图,代码 head 保持 ed6baf49b。20 组页面均回读根节点无横向溢出;读取过程中模型请求、状态 action apply、真实历史 owner 的写入尝试均为 0,合成源字节未改变。
  • vite.config.ts 的开发代理转发属于非视觉改动;打包截图不能验证开发代理。共享 explore_timeline.ts 的阈值规则体现在 V3;回归脚本和测试修改没有另增产品界面。代码分别见 Vite 配置、时间线 owner。
  • 此 head 尚存的细节:短时图的可见标题和读法已改为全程,但分组容器的 aria-label 仍沿用三等分描述。本轮图片更新未修改这处无障碍文案。提示图包含键盘展开态,本轮不新增触屏验收结论。
  • 视觉观察:Goal 首屏仍先展示目标、工作和结果检查;空指标退为说明性文本。窄屏标签换行但仍可读。时间线保留原始状态颜色与文字、密度及详情入口;长记录不被压成短记录。错误与覆盖未知保持可见。

以下保留原代码修复的实现摘要与验证范围;此前通过的检查不改写成本轮重新执行。

Summary

  • Short Explore histories (under 6h) use one whole-history reading group; longer histories retain time thirds, avoiding empty phase cards on short runs.
  • Goal vitals distinguish uncollected usage/activity from complete empty attention. Incomplete coverage retains its unknown state and explanation. The manager brief exposes Goals assigned to host App threads without presenting them as verified active execution.
  • The default Files/成果 tab renders a readable empty research state for an optional index returning HTTP 404/410, with Refresh available. Other HTTP errors and invalid JSON retain a visible error. Refresh and Goal switches clear stale results; text mentioning “HTTP 404” does not determine status.
  • Vite forwards the research index and projection read endpoints to the status service instead of returning SPA HTML. Production routing is unchanged.

Validation

Validated correction: ed6baf49bae6262872ae7310f7976f959184e005, including target main dd30e694a0c3db80e59600c781d67647a73d0bc9.

  • Dashboard TypeScript/Vite build and packaged Chat bundle validation.
  • Explore history and Goal workspace digest: 29 tests.
  • Packaged research-results: default 404/410 empty states, keyboard Refresh, HTTP 500, invalid JSON, recovery, Goal switching, English copy, owner-only exclusion and zero model calls.
  • Packaged goal-masthead.
  • Packaged navigation-sorting. Two initial starts exceeded the unchanged 20-second readiness deadline (an isolated startup took 23.5 seconds); the subsequent run started normally and passed without changing the timeout or scenario assertions.
  • Bilingual RFC diff and diff whitespace checks.
  • Standard source-checkout premerge validation: four direct checks, four selected catalog canaries, eight risk-profile smokes and public/private boundary scan passed (13 selected checks, zero failures).
  • Independent review of the updated head and installed desktop App acceptance remain separate. CI was not queried in this author-fix pass.

These are source-checkout packaged-bundle checks, not proof of an installed App update.

@huangruiteng

Copy link
Copy Markdown
Collaborator Author

First-screen verification evidence

Playwright against the live local status/chat servers (same status.json, same registry). Branch served on :5174, current main on :5173.

1. Unmeasured Goal vitals: em dashes with hover → own explanatory value, non-interactive

Before (current main, demo Goal with no measured usage):

After (this branch): Agent 用时 / 成本 show 未采集, 最近活动 shows 暂无观测到的活动, 等你决定 shows 暂无等待; cells are muted and no longer clickable hovers.

2. Manager brief: "正在执行 0" hid the queued Goals

Before: the 0 tile had no sub-line — the 5 Goals handed to host app threads were invisible in this tile.

After: the same tile reads 5 个已安排 · 由宿主 App 线程负责.

3. 成果 tab: dev proxy leaked SPA HTML as a JSON SyntaxError

Before over the vite dev port (/extension-presentation-surfaces returned the SPA): SyntaxError: Unexpected token '<' under both 团队报告 and 研究成果.

After: the dev proxy forwards the status server's extension/report paths; a genuinely missing optional index reads as 本 Goal 暂无可读取的公开研究成果 instead of an error (verified on a real Goal, no HTML leak).

Verification

  • dashboard tsc --noEmit: clean
  • Explore history/research focused node tests: 37 pass; one new control-plane test for the sub-6h whole-history group
  • browser assertions: no — placeholders, no Unexpected token/HTML, queued hint present

Screenshots were captured at 2x DPR; the image upload endpoint rejected attachments from this environment, so I will add the before/after images from the local evidence set (/tmp/lx/pr-shots/) if uploads are available in the web review.

huangruiteng and others added 3 commits October 27, 2026 20:30
When all Explore records fall within a sub-6h window, the time-anchored
reading model split them into three equal phases, leaving two empty
early/middle/late cards (observed on EdgeBench runs whose imported log
spanned minutes). Below the threshold the timeline now renders one
whole-history reading group; long spans keep the three thirds.

Adds a control-plane unit test covering both spans.

Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>
…ion research

- Unmeasured Goal vitals (Agent time, cost, last activity, needs-you at
  zero) rendered bare em dashes with click affordance; they now show
  their own explanatory value (not measured / nothing waiting / no
  activity) as muted, non-interactive cells instead.
- The manager brief hid the queued-Goal count entirely when no verified
  run was present; it now shows a separate queued-only note so Goals
  handed to host app threads stay visible.
- Research results treated a missing optional presentation index
  (404/410) as a read failure and surfaced the dev server's HTML as a
  JSON SyntaxError; a missing index now reads as no published research.
- The dashboard dev proxy forwards the status server's extension and
  periodic-report paths, so the research workspace works over the vite
  port instead of returning the SPA HTML.

Signed-off-by: huangruiteng <huangruiteng@users.noreply.github.com>
Signed-off-by: huangruiteng <huangrt01@163.com>
@huangruiteng
huangruiteng force-pushed the codex/research-workspace-polish-20261026 branch from 0b08c42 to c8d6796 Compare October 27, 2026 12:33

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Reviewer: model_agent; gpt-6.1-sol; OpenAI; runtime_reported; reasoning_effort=max

动机 / Motivation

研究者在 Goal 概览和成果页需要辨认真实进展、未采集数据与没有成果。
短研究记录原先仍分成三个时间组,缺测读数只有破折号;开发服务器还可能把成果接口返回为 HTML。本 PR 收起短记录的空分组、明确缺测和排队状态,并补齐原 status 服务的开发代理。
实际验证确认这些展示路径大体成立,但成果索引返回 404/410 时出现新的空白正文,尚未完成所承诺的可读空态。
范围限于现有展示与开发路由,不改变研究结果、执行准入、计费或已安装 App。

改动思路 / Approach

保留 typed Explore timeline、Goal digest、ContextHelp 和 extension reader 是合适的边界。时间跨度决定一组或三组,仅用于阅读;Goal 的缺测、完整空注意事项和实际执行状态继续取自原 owner,不能由显示文案推导完成。
当前 PR 可以保留这些局部展示与代理改动;最小修复是在现有成果 reader 内让“缺少可选索引”进入完整空态,其他读取失败继续保留错误及刷新。
保持原状会继续留下空卡片和开发接口 HTML 泄漏;新建状态机或配置项则没有必要。Vital.empty 取消无意义跳转但保留独立帮助入口;Vite 只把既有只读路径交给原 status target,不应成为新的配置或权限 owner。

具体改动 / Changes

已读完整十一文件 diff,当前 head 为 c8d679679dac1e7b8c22da888740dafcdf1f4a02。规范依据 docs/development/design.md,accepted revision a704725d6734b618f267568071960760c6620687:

  • Research Workspace / 研究工作台:implemented,完整记录和原始关系保留;短记录改为全程分组,不是评估窗口或因果结论。
  • Status And Control-Plane States:implemented,缺测不补零,完整零等待与覆盖未知分别显示,排队不冒充实际执行。
  • States that are designed, not defaulted:not_met,下面的 404/410 反例留下没有状态正文的成果区,需要本 PR 内修复。

关键代码讲解

  • buildExploreTimeline 在六小时以下建立一个 phase;原 bins、记录时间、负面结论、筛选与原文关系仍由已有模型提供。长跨度保留三个 phase。
  • GoalVitals 仅在 availability 正常、coverage 完整且两个计数均为零时显示“暂无等待”;缺测 usage 保持未知,ContextHelp 仍可聚焦读取。
  • GoalResearchResults 新增 indexMissing;它隐藏了错误,却没有同步空态条件。ManagerBrief 和 Vite 的其余变化分别补回排队提示和原 status endpoints,没有新增执行操作。

独立验证:完整 dashboard/Chat build PASS;两个完整 typed suites 29 PASS;实际 status extension 与 Explore backend 12 PASS;打包的 goal-masthead、navigation-sorting 两个场景均通过。标准 premerge 的 4 direct / 13 selected 命令通过,初始精确 CQR 为 stale hold;独立复验已据当前缺陷记录失败,不能据自动检查通过批准。

对主干的风险 / Risks

[P2] 缺失索引也需要实际渲染空态正文

GoalResearchResults 的外层 catch 将非 2xx 索引请求保存为非空 error。404/410 随后使 indexMissing=true,错误段落被抑制;空态段落却仍要求 !error,因此同样不渲染。实际 Files 调用没有启用 hideEmpty,用户最终只看到“研究成果”和刷新按钮,无法判断是否没有成果或读取仍未结束。

我用原组件和真实 HTTP 200/404/410/500 响应复验,并与 accepted-base 组件同条件比较:200 空集合保留说明,500 保留错误;head 的 404、410 均无正文,刷新后仍然如此。最小修复可在 catch 前把这两种响应明确归为空集合,或让现有空态条件包含 indexMissing;保留其他 HTTP/解析失败、Goal 切换及旧内容清除。补测默认 Files 场景的两种缺失响应、刷新/切换和 500,不能只验证 hideEmpty=true。

其余风险主要是三等分到全程的选择状态、未采集帮助和未知 coverage;已执行的 typed/打包路径支持其当前行为。尚未重新资格正式 App 安装、所有源切换组合或持续用户理解,不用本次截图或测试数代替这些结论。

我的整体评价 / Verdict

REQUEST_CHANGES,仅上述可复现的空态缺陷阻塞本 head。long_horizon 的研究事实和执行权限保持;user_experience 在缺失索引分支发生退化,修复范围很小,不需扩展为新的成果平台。独立检查了带长任务和混合状态的打包桌面/390px 整页,缺测文案与真实数值可区分;Ego 的实际组件/HTTP 对照确认空白状态。视觉观察不等同理解收益;正式安装和完整源切换仍未资格。没有查询、轮询或等待 CI,也未合并、安装或改变作者分支。

English verdict: REQUEST_CHANGES c8d679679dac1e7b8c22da888740dafcdf1f4a02: HTTP 404/410 hides both the error and empty-state body; build, 29 typed tests, 12 backend tests and two packaged scenarios otherwise pass.

</button></header>
{busy ? <p role="status">{zh ? "正在核验研究结果…" : "Verifying research results…"}</p> : null}
{error ? <p role="alert">{zh ? "无法核验研究结果;旧内容已清除。" : "Cannot verify research results; previous content was cleared."} {error}</p> : null}
{error && !indexMissing ? <p role="alert">{zh ? "无法核验研究结果;旧内容已清除。" : "Cannot verify research results; previous content was cleared."} {error}</p> : null}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

[P2] 缺失索引时仍需渲染空态正文

默认 Files 调用未传 hideEmpty。索引返回 HTTP404/410 后,catch 保存非空 error;新增 indexMissing 把错误隐藏,但下面的空态仍要求 !error,因此用户只剩“研究成果”和刷新按钮,刷新后仍空白。用真实 HTTP200/404/410/500 与 accepted-base 组件同条件比较确认,200空态与500错误是控制。请让已知缺失进入原有完整空态,保留其他 HTTP/解析错误与 Goal 切换清旧数据,并补默认 Files 两种缺失响应、刷新/切换及500的回归。

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>
Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

This branch has not been deployed

No deployments
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.

2 participants