会话工作区 › 右边栏 › 产物
+产物面板从「只有最新一次」长成「这个项目的每一次」
++ 全页产物工作台已下线,产物只经会话右栏到达。右栏今天只展示这个项目最新一次云任务的产物, + 历史几次无处可达,云任务回流落盘后面板也不知道。本稿在既有面板顶部加一条云任务条—— + 与右栏其它面板的摘要条/页签条同一形制位 —— 承担切换、刷新、以及「有新结果落地」的提示; + 面板内其余一切(卡片、状态、预览三页签、打开前复核)一行不改。不重新引入全页产物页面。 +
+01
+与上一稿的关系
+
+ 视觉血统:current/artifact-workbench/design.html(产物设计的现行权威,PAGE-MAP 指定)
+ × 2026-07-24-session-seam-baseline.md(右栏四面板与宽度契约)
+ × 2026-07-28-req126-shell-navigation-baseline.md §1.3 / S3(全页工作台下线的裁决与其明说的能力差额)。
+ 本稿是这三者之上的一层状态增量:不新增页面、不新增覆盖层、不重排产物面板的信息架构。
+
产物工作台的构件语言
+-
+
- 卡片行:文件名 + 状态 chip + 体积 + 警告计数,行距与圆角一字不改。 +
- 状态 chip 六态与配色:已验证 / 未验证 / 校验不符 / 文件缺失 / 未登记 / 未下载。 +
- 预览三页签「预览 · 源文 · 元数据」与其单渲染器崩溃隔离。 +
- 「打开前复核」闸门:复核未过一律不出预览,失败诚实可重试。 +
右栏形制
+-
+
- 右栏宽度契约 320–560,默认 400,左缘拖拽把手不动。 +
- 顶部四面板胶囊条「审查 · 文件 · 终端 · 产物」不动。 +
- 面板顶部允许有一条自己的条 —— 审查面板是摘要条,终端面板是页签条,文件面板是筛选条。产物面板本来是这四个里唯一没有的。 +
- 时间线产物行 → 右栏定位、Esc 归位的联动不动。 +
三件,全部长在既有挂载点上
+-
+
- 云任务条:一个可展开的选择器,替掉现在那行写死的小标题。展开即这个项目的历次云任务。 +
- 单件取回:把工作台早已有、右栏被砍掉的「未下载 → 下载 → 可预览」动作装回卡片行。 +
- 新结果提示:云任务回流落盘后,条上出现一条可点的提示,不抢焦点、不自动跳。 +
02
+现状审计:今天的面板长什么样、缺什么
++ 以下均为帧外事实,行号对本工作树。本稿的每一个视觉都必须能指回这张表的某一行:要么沿用它,要么补它的缺口。 +
+| 现状 | 今天的实现 | 缺口 |
|---|---|---|
| 只有一次云任务 | +session-rail-artifacts.tsx:59-63 取 projectUsage(directory) 后直接 sortRunUsages(...)[0],再无第二条路径。 |
+ 历史几次无处可达。切换器是本稿主体。 | +
| 小标题写着「本回合产物」 | +artifacts-panel-view.tsx:118 固定渲染 alpha.session.artifactsTurn。 |
+ 这是一句不成立的断言 —— 一个真缺陷,不是措辞问题。数据按项目目录取,选的是排序后的第 0 个,它完全可能来自同项目的另一个会话。用会话级说法罩住项目级数据,用户据此以为「这是我刚才这轮的产出」。切换器把标题换成选中那一次的自述,顺带消掉它。 | +
| 没有云端合并 | +session-rail-artifacts.tsx:77-84 的 deriveCards 只喂本地 entries 与 legacyFiles,刻意不喂 cloudArtifacts。 |
+ 平台上有、本地没落盘的件根本不出现;单件重下也无从谈起。 | +
| 不会自己刷新 | +只有 mount 与 retry() 会推 tick(session-rail-artifacts.tsx:40-45);云任务回流 watcher 只弹一条 toast(cloud-run-watcher.tsx:40-47)。 |
+ 结果落盘了,面板还是旧的。连一个手动刷新按钮都没有(只有出错时才出现「重试」)。 | +
| 面板顶部没有条 | +右栏另三个面板都有:审查摘要条 review-panel.css:26、终端页签条 terminal-rail.css:20、文件筛选条 session-rail-files.css:28。产物面板直接进滚动区。 |
+ 新增的条不是发明,是把这个面板补齐到与同侪一致。 | +
| 模块本体健在 | +右栏 import 了工作台的 workbench-core(卡片派生 + 下载状态机)与 renderers/*(session-rail-artifacts.tsx:16-21);全页组件本身已无挂载点。 |
+ 下载状态机 downloadReducer 已写好且有测试,本稿的取回不是从零实现。 |
+
03
+数据通道真相:哪些今天就有,哪些今天没有
++ 本稿画的每一个可点的东西都必须能指到一条现存通道。下表是逐条勘破的结果 —— + 凡是「今天没有」的,本稿不假装它有:要么不画,要么画成明确需要裁决的选项。 +
+| 面板上的东西 | 它读/写哪条通道 | 今天有吗 | 说明 |
|---|---|---|---|
| 历次云任务列表 | +runArtifacts.projectUsage(directory) → usage.runs[](main/artifact-service.ts:1615) |
+ 有 | +已在面板里被调用,只是只取了第 0 个。遍历 .alpha/runs/*,云端回流写的 run 与本地 run 同在此列。 |
+
| 某次云任务的产物清单 | +runArtifacts.list(directory, runId) |
+ 有 | +已在用,换个 runId 即可,零改动。 |
+
| 每行的「N 个产物 · 体积」「N 个缺失」 | +RunArtifactUsage 的 artifactCount / diskBytes / missingCount / readOnly(artifact-service.ts:1547-1559) |
+ 有 | +字段齐全,与下线的全页工作台那一列同源。 | +
| 项目用量条 | +usage.totalDiskBytes / usage.limits.projectMaxBytes |
+ 有 | +同一次 projectUsage 调用即返回,不多一次 IPC。 |
+
| 「未下载」卡片(平台有、本地无) | +cloud.artifacts(runId) → deriveCards({..., cloudArtifacts}) |
+ 有 | +run 目录名就是平台的 job id,同一个字符串直接传。需登录 + 联网;失败返回 {error} 信封而非抛错,离线/未登录降级成「只显示本地」。 |
+
| 单件下载 / 进度 / 取消 | +cloud.downloadArtifact · cloud.onArtifactProgress · cloud.cancelArtifactDownload |
+ 有 | +字节不过 IPC,落盘后自动写回清单,状态随之从「未下载」变「已验证」。进度事件按 artifact id 到达。 | +
| 整次云任务回流落盘 | +cloud.saveRun,由 CloudRunWatcher 在云任务终态时自动调用 |
+ 有(且已自动) | +关键澄清:回流本身早就自动发生并且真的下载字节。缺的从来不是「取回动作」,是「面板知道它发生了」。 | +
| 回流落盘后通知界面 | +新增一条最小推送事件(只带项目目录 + 任务编号) | +已裁决新增 | +渲染进程此前没有任何「已保存」推送通道,watcher 落盘后只弹 toast。owner 裁决 A1:加这一条通道 —— 一个事件、零轮询,提示与事实严格同步。故提示条是已定形态,不是备选。 | +
| 某次云任务的时间与排序 | +artifacts.json 的 updatedAt,经 RunArtifactUsage 带出 |
+ 已裁决带出 | +时间本来就在盘上,只是 projectUsage 没读、没带。owner 裁决 B1:加这一个字段(不新增 IPC)。行上因此显示真实时刻,排序也从字典序改成真正按时间 —— 现役那句「按编号倒序 ≈ 新在前」是缺陷,不是设计。 |
+
| 某次云任务的成败 | +—— | +没有 | +回流会把完整状态写进 run 目录的 status.json,但没有任何 IPC 读它 —— 纯只写。所以行上不能出现「已完成 / 失败」。 |
+
| 某次云任务的标题 / 归属会话 | +—— | +没有 | +清单里没有标题、没有会话 id、也没有「云 or 本地」的区分。行上唯一稳定的身份就是它自己的编号。 | +
| 删除 / 清理某次云任务 | +—— | +没有,且已裁决不做 | +产物 IPC 刻意无写面(preload/types.ts:897-898:保留策略未定前不暴露删除)。做它意味着开一个写面,外加不可逆动作确认与误删防护 —— 与验收句真正点名的两件事(跨次切换 + 取回云端结果)是两回事。owner 裁决:整体推迟,不属本票。 |
+
04
+词汇表:契约词怎么翻成用户语言
+帧内只出现右列。左列一律不上界面。
+| 内部词 | 界面说法 | 纪律 |
|---|---|---|
| run | 云任务 | 沿用面板既有说法,不另造词。切换器标题即「云任务」。 |
| updatedAt | 时刻(今天 15:02 / 昨天 18:20 / 7月26日 11:05) | 时间是用户认「哪一次」的主要抓手,故在条上与行上都占主位。当天用「今天/昨天 + 时:分」,更早用「月日 + 时:分」。 |
| runId | (不翻译,以等宽短号呈现) | 时间到位后它退居次要身份:只在条上常驻一处(靠右、次要色、等宽、截断中段),行上不再重复。不给它加标签,不说「ID」。 |
| 最新的一次 | 最近一次 / 上一次 | 排序改为真正按时间后,这两枚标记是可证实的,挂在前两行。再往下不排名次 —— 用时间本身足够定位,序数只会添噪音。 |
| manifest 只读 / corrupt | 记录不可读 | 现役 chip 文案是「manifest 只读」——这是内部词,本稿改掉它。 |
| cloud-only | 未下载 | 沿用现役文案。 |
| verify / 打开前复核 | 核对中… / 打开前核对失败 | 沿用现役语义,措辞去掉「复核」的公文腔。 |
| backflow / saveRun | 结果已回到本地 | 提示条只说结果,不说机制,不出现目录路径。 |
05
+基线帧:今天的样子
++ 作为对照。右栏 400,四面板胶囊条在顶,产物面板直接进滚动区:一行小标题、卡片列、预览三页签、预览体。 + 本稿只在小标题那一行动手。 +
+ +-
+
- + + 季度复盘.md + + + +
- + + 渠道对比.csv + + + +
季度复盘
+三条渠道在本季度的表现分化明显,自然流量的贡献首次超过投放。
+- 自然流量:占比 46%,环比 +9
- 合作导入:占比 31%,环比持平
- 付费投放:占比 23%,环比 −9
+ 帧外标注 —— 左侧会话区只作背景,本稿不动它。右栏这一版有两处问题: + 小标题「本回合产物」对的是项目最新一次云任务,并非本回合; + 以及没有任何入口能到别的几次。 +
+06
+云任务条:收起态与展开态
++ 收起态占一行,替掉原来的小标题,并把「这是哪一次」明说出来。右侧一枚刷新按钮 —— 面板此前连手动刷新都没有。 + 展开态就地下推一张列表,不是浮层:右栏本来就是一根滚动柱,浮层在 400 宽里既容易被裁切,也和右栏其余面板的展开语汇不一致。 + 列表按时间倒序 —— 不是按编号。 +
+-
+
- + + 季度复盘.md + + + +
- + + 渠道对比.csv + + + +
季度复盘
+三条渠道在本季度的表现分化明显,自然流量的贡献首次超过投放。
+- 自然流量:占比 46%,环比 +9
- 合作导入:占比 31%,环比持平
- 付费投放:占比 23%,环比 −9
+ 帧外标注 —— 时刻是主标,「最近一次」是可证实的小标记(只在选中的确实是时间最新那一次时出现);
+ 编号退到最右、次要色、等宽、中段截断,悬停出完整值 —— 它仍是唯一稳定身份,但不再是用户认路的东西。
+ 刷新按钮转一圈即完成,不换布局。此帧对应真实数据:projectUsage().runs 按时间排序后取第一个。
+
-
+
+
+
+
+
+
-
+
- + + 季度复盘.md + + + +
- + + 渠道对比.csv + + + +
+ 帧外标注 —— 行上只放能证实的事实:时刻(主)、件数、体积,以及缺失/记录不可读两枚 chip。 + 时刻来自每次任务记录里本就存在的更新时刻,排序按它,不按编号。 + 成败与标题仍然不画 —— 这两样今天的数据里确实没有(见「数据通道真相」),画上去就是编的。 + 「最近一次 / 上一次」只到第二行为止,再往下靠时刻本身定位。 + 底部用量条与下线的全页工作台左栏底部同源同算法。列表超过五行内部滚动,面板其余部分不移位。 +
+-
+
- + + 竞品扫描.docx + + + +
- + + 数据附录.xlsx + + + + +
- + + 原始日志.txt + + + +
+ 帧外标注 —— 停在历史一次时,条上显示那一次的时刻,不再出现「最近一次」。 + 新结果落地只在条上加一条可点提示 + 刷新按钮上一颗点:不抢焦点、不自动跳走 —— + 用户可能正在读历史结果。点「查看」= 跳到那次并收起提示。 + 驱动它的是一条已裁决新增的最小推送事件(只带项目目录 + 任务编号),不是轮询。 +
+07
+云端取回:四态
++ 先分清两件被混称的事。整次结果的回流是自动的、而且早就在跑 —— 云任务一结束就把状态与全部产物下载到本地。 + 这里的四态说的是单件补取:整次回流时某一件下载失败(回流对单件失败是降级不是中止)、 + 或本地文件后来消失了,平台那边还在,那就该能单独把它取回来。四态用的是下线的全页工作台里那台已经写好、已有测试的下载状态机。 +
+单件取回状态机 确定 reducer;终态之后到达的进度帧一律丢弃
+平台有、本地无,或本地文件已消失。卡片带「未下载 / 文件缺失」,行尾一枚「下载」。
百分比 + 「取消」。进度以 aria-live polite 播报,不打断。
落盘即写回清单,状态自动变「已验证」,预览随之可用。
失败留在行上并可重试;取消回到未取回,不留错误痕迹。
-
+
- + + 数据附录.xlsx + + + + +
- + + 竞品扫描.docx + + + +
尚未落盘 —— 下载后可预览。
+ +帧外 —— 「未下载」蓝色 chip 与预览区那句提示都是现役文案,原样沿用。行尾按钮与预览区按钮是同一个动作,给两处入口是因为在 400 宽里行尾按钮很窄。
+-
+
- + + 数据附录.xlsx + + + 43% + +
- + + 竞品扫描.docx + + + +
尚未落盘 —— 下载后可预览。
帧外 —— 百分比等宽、tabular,数字跳动不推挤按钮。那行播报文字对应一个 aria-live="polite" 区域,视觉上是弱化的一行;总进度不来时退化为已下载字节数。取消走的是按 artifact 身份的中止,半截文件会被清掉。
-
+
- + + 数据附录.xlsx + + + +
- + + 竞品扫描.docx + + + +
数据附录
+共 4 张工作表,首表 128 行 × 9 列。
+- 渠道明细
- 成本拆解
- 留存队列
- 口径说明
帧外 —— 取回成功后不弹任何东西:chip 自己从「未下载」变「已验证」,预览就地出现。这不是乐观更新 —— 落盘时清单被真的写回,面板重取的是写回后的清单。Office 件仍走既有的结构检查再放行。
+-
+
- + + 数据附录.xlsx + + + + +
- + + 竞品扫描.docx + + + +
尚未落盘 —— 下载后可预览。
+ 帧外 —— 失败一律行内,不弹框。行上留一枚红 chip + 「重试」,详情作为一条通知落在列表下方。 + 第二条中性通知是另一件事:平台列表取不到(离线或未登录)时,面板诚实降级为只显示本地产物, + 不假装云端没有东西 —— 这句是现役文案,原样沿用。两条并存说明它们互不掩盖。 +
+08
+空态与失败态
++ 现役面板已有四相:加载中 / 出错 / 空 / 有卡片,判定是失败关闭的 —— 没被证明能读的一律不显示成「空」。 + 切换器落地后相不变,只多了「这个项目一次云任务都没有」与「这一次里没有产物」需要分开说。 +
+助手生成的文档会出现在这里。
+帧外 —— 一次云任务都没有时连云任务条都不出现 —— 一个只能选空集的选择器是噪音。现役空态文案与图标原样保留。
+换一次看看,或让助手重新生成。
+帧外 —— 条留着:用户得能从这里换走。这是新增文案 —— 现役只有一句通用空态,分不清「一个都没有」和「这次没有」。
+帧外 —— 某一次读不出来不拖垮切换器:条仍可展开换到别的一次。这是把切换器放在滚动区之外的直接理由。
+-
+
- + + 竞品扫描.docx + + + +
帧外 —— 现役闸门原样保留:核对没过一个字节都不读,不出预览,失败可重试且永不被静默升级成通过。切换器不改这台闸门,只是让它按新的那一次重新跑。
+09
+深色
++ 深色不是另一套设计,是同一套 token 的另一组值。这里固定渲染深色,便于与上面的浅色逐帧对照(页面右上角的切换器影响其余全部)。 + 需要盯的是两处:云任务条在深色下与滚动区的分层,以及状态 chip 的四色在深色底上仍然彼此可分。 +
+-
+
+
+
+
+
-
+
- + + 季度复盘.md + + + +
- + + 渠道对比.csv + + + +
帧外 —— 展开面用 surface 提一级并落一层弱阴影,与其下的滚动区分层;深色下不靠加边框硬分。
+-
+
- + + 数据附录.xlsx + + + + +
- + + 季度复盘.md + + + 43% + +
- + + 原始日志.txt + + + +
- + + 竞品扫描.docx + + + +
帧外 —— 四类 chip(绿=已验证、蓝=未下载、黄=未登记、红=校验不符)在深色底上并置检查:色相彼此可分,且都不与强调紫撞。此帧只为对比,真实面板不会同时出现这四类。
+10
+交互契约
+键盘与焦点
+条本身是一个展开按钮,回车/空格开合,展开时焦点进列表首行;Esc 收起并把焦点还给条。
上下键在行间移动,回车选定并收起 —— 与右栏其它列表同一套漫游焦点。
列表展开时 Esc 只收列表;收起状态下 Esc 才沿用现役行为,把焦点还给时间线上发起的那一行。
换一次之后焦点留在条上,不跳进卡片列 —— 用户可能想连着再换一次。
进度以 polite 播报,不打断当前朗读;完成与失败各播报一次终态。
提示条出现不移动焦点,仅以 polite 播报一次;它可被 Tab 到达。
状态迁移的呈现规则
+换一次即丢弃上一次的选中件、预览模式与核对结果,回到该次的第一件与「预览」页签。不跨次保留选中。
刷新重取列表与清单;正在下载的件不被打断,其进度状态跨刷新存活。
核对失败、下载失败都停在自己那一格,不会因为别处成功而被抹掉,只有显式重试能改写。
11
+裁决记录 2026-07-28 · 全部已定
+五项全部由 owner 拍板。上面所有帧已按裁决后的形态绘制,不再有备选分支。
+ +A · 云任务结果落地后,面板怎么知道 已裁决 · A1
+此前渲染进程没有任何「已保存」推送。裁决:加一条最小推送事件。
+回流落盘成功后,主进程推一条只带项目目录与任务编号的事件;面板收到即显示提示条。一条通道、一个事件、零轮询,提示与事实严格同步。提示条因此是已定形态,不是备选。
零新通道,但用户盯着面板不动时结果落地了也不会动 —— 提示条那一件就得砍掉,验收句里的「取到云端回流的 run」只能靠用户主动点。
反复走磁盘遍历,且「几秒」是个凭空的数,依然不准。
B · 行上要不要有时间 已裁决 · B1
+裁决:把盘上本来就有的时刻带出来,并让排序真的按时间。
+每次云任务的记录里本来就有一个更新时刻,只是没被带进项目统计。带出来之后行上显示人能读的时刻,排序从「按编号倒序」改成真正按时间。不新增 IPC,改动集中在一处结构与其填充。
+ 顺带订正一个缺陷:现役排序按编号字典序倒序,代码注释自陈「≈ 新在前」—— 那是一个近似,不是设计意图。任务编号里没有时间戳,一旦编号生成规则变化,顺序就会静默错乱且没有任何东西会报警。B1 把它从近似换成事实。
零改动,但用户要靠编号认「哪一次是我要的那次」,且排序永远只是近似。
C · 状态 chip 的措辞 已裁决 · 采纳
+现役文案是内部词,已确认改为 「记录不可读」,上方各帧已按此绘制。
+D · 面板顶部那行字 已裁决 · 替换
+固定小标题替换为选中那一次的自述(时刻 + 标记),不保留。理由见下方缺陷记录。
+E · run 级管理动作(删除 / 清理) 已裁决 · 推迟
+票面提到过,但明确不属本次交付。理由:产物通道刻意没有写面,做它意味着开一个写面,外加不可逆动作确认与误删防护 —— 与验收句真正点名的两件事(跨次切换 + 取回云端结果)是两回事。本票关闭不代表它已交付。
+projectUsage(identity.directory)),选的是排序后的第 0 个 —— 它完全可能来自同项目的另一个会话。
+ 用会话级说法("本回合")罩住项目级数据,用户会据此以为「这是我刚才这轮的产出」。
+ 切换器把这行字换成选中那一次的自述,顺带把它消掉。
+ 纪律随之定死:本面板的任何文案都不得再对项目级数据作会话级断言 —— 包括未来给「产物」页签加计数徽标时,那个数也是项目级的,不能叫「本回合产物数」。
+ 12
+不做的
+明确划在外面,免得实现时顺手长回去 —— 也免得日后把本票的关闭读成「这些都做了」。
+-
+
- 全页产物页面不以任何形式回来 —— 不做新路由、不做覆盖层、不做「在新窗口打开」。产物只经会话右栏到达。 +
- 项目选择器不进右栏。右栏的项目由当前会话决定。 +
- 删除 / 清理某次云任务不做(owner 已裁决推迟)。产物通道刻意没有写面;做它要开写面 + 不可逆动作确认 + 误删防护,与本次验收句点名的两件事是两回事。用量条因此只能看,不能在这里清。本票交付不含这一项。 +
- 行上显示成败不做。回流写下的状态今天没有任何读取通道,画上去就是编的。 +
- 跨次搜索 / 过滤产物不做。先把「能到达」解决,过滤是它之上的另一层。 +
- 预览器本身一行不改。Office 结构检查、隔离 HTML 预览、快速查看各归各的交付。 +
- 时间线产物行的联动不改。它今天指向的是当前展示的那一次,切换器落地后仍然如此。 +
- 手动触发整次回流不做。回流由云任务终态自动发生;给用户一个「重新回流」按钮既无对应通道,也会让人以为结果需要手动抢救。 +