Friday QA Report

Generated at 2026-04-21T10:39:43.866Z. Only scripted evidence is treated as valid. Legacy screenshot-only evidence is rejected until rebuilt.

Total Rules433
PASS433
FAIL0
Pending Rebuild0
ItemRuleStatusAcceptanceEvidenceSummary
P2A-011PASSH01 · snapshot 调用唯一 · 打开 /home 后 Network panel 只见 1 次 `getHome()`(mock 场景替换成 1 次 `__fridayMock.getState()`)· 无重复 fetch 风暴screenshots/P2A-01/h01-home-snapshot-call.jsonboot getState=1, navigationEntries=1
P2A-012PASSH02 · 可见 polling 5s · tab active 时 `advanceClock(5000)` 后触发一次 refetch · 误差 ≤ 200msscreenshots/P2A-01/h02-visible-polling.jsoncalls 1 -> 2, latency=2.1ms
P2A-013PASSH03 · 后台 polling 60s · 切 tab 后 `document.visibilityState === 'hidden'` 时,间隔变 60s · 用 `visibilitychange` 事件验证screenshots/P2A-01/h03-hidden-polling.jsonhidden calls 1 -> 2, latency=2.3ms
P2A-014PASSH04 · 三段独立 loading · 任一段数据未到时只显示该段 skeleton(3 个 shimmer row)· 其他段正常渲染 · MUST NOT 整页 spinnerscreenshots/P2A-01/h04-loading-sections.jsonlive skeletons=3, scheduled skeletons=3, approvals=3
P2A-015PASSH05 · realtime 淡入 · dispatch `run.state_changed(id, 'running' → 'succeeded')` 时对应 card 500ms opacity 0.5 → 1 淡入 + 轻微 translateY(-2px) · 其他 card MUST NOT 重排screenshots/P2A-01/h05-realtime-transition.jsonanimation=run-fade 0.5s, stable=true
P2A-016PASSH06 · approvals 跳转 · 点"全部查看" · URL 变 `/assistant?tab=approvals` · 若 approval 带 packId · `?packId=xxx` 保留screenshots/P2A-01/h06-approvals-navigation.jsonhref=/assistant?tab=approvals&packId=industry-cross-border-ecommerce
P2A-017PASSH07 · approvals 0 条时 · 段不渲染标题,显示空态文案 "暂时没有需要你决定的事" · 不留空白块screenshots/P2A-01/h07-approvals-empty.jsonheaderPresent=false, text=暂时没有需要你决定的事
P2A-018PASSH08 · scheduled 排序 · 按 `nextRunAt` 升序 · 造 6 条数据时只显示前 5 条 + "+1 更多" link 在段底screenshots/P2A-01/h08-scheduled-order.jsonrows=5, more=+1 更多
P2A-019PASSH09 · scheduled disabled 置灰 · `automation.enabled === false` 时 row `opacity: 0.35` · next run 文字替换成 "已暂停"screenshots/P2A-01/h09-scheduled-disabled.jsonopacity=0.35, time=已暂停
P2A-0110PASSH10 · snapshot 失败 · `__fridayMock.forceState('p2a-01', 'snapshot-error')` 后页面显示 inline 错误条(段 1 位置)+ "刷新"按钮 · MUST NOT 跳 splash · shell 保留screenshots/P2A-01/h10-snapshot-error.jsonerrorBar=true, topbar=true
P2A-0111PASSH11 · partial failure · 只 approvals 挂 · 该段显示行内错误 · 其他段正常screenshots/P2A-01/h11-partial-failure.jsonapprovalsError=审批快照暂时不可用, runs=3, scheduled=5
P2A-0112PASSH12 · dev switcher · 6 状态按钮全可切 · 切换无 reload · URL ?__state= 同步screenshots/P2A-01/h12-dev-switcher.jsonstates=6, navigationEntries=1
P2A-0113PASSH13 · intent ribbon · 至少 4 个 pill · 点 pill 滚动到对应段(smooth · 80px offset 避开 topbar)screenshots/P2A-01/h13-intent-ribbon.jsonpillCount=4, behavior=smooth, top=782.484375
P2A-0114PASSH14 · 空状态整页 · runs + approvals + scheduled 全 0 时 · 整页居中友好文案 "今天很清静,来开一场对话?" + 跳 /chat 的 CTAscreenshots/P2A-01/h14-empty-hero.jsontitle=今天很清静,来开一场对话?, cta=/chat
P2A-021PASSruns 为 `[]` 时不渲染段标题,仅空态 · 非空时段标题 "正在进行中 (N)"screenshots/P2A-02/l01-livework-title.jsonemptyHeader=false, filledTitle=正在进行中 (2)
P2A-022PASSstatus pill 按 `ACTIVE_RUN_STATUSES` 9 种状态各有独立配色 · 只能用 tokens 里的 `--success/--warning/--error/--accent/--ink-3`screenshots/P2A-02/l02-status-pills.jsonrendered=9, inlineStyles=0
P2A-023PASShealth tone 用 `toneForRunHealth(run)` · 返回 `healthy/warning/error` 三档screenshots/P2A-02/l03-run-health-tone.jsontones=healthy,warning,error
P2A-024PASS悬浮卡片 300ms delay 后显示 `summarizeRunContext()` tooltip · 位置 top · 箭头对齐screenshots/P2A-02/l04-run-tooltip.jsonbefore=false, after=true, copyLength=50
P2A-025PASS进度条颜色按 health tone · warning 黄 / error 红 / healthy 琥珀screenshots/P2A-02/l05-progress-colors.jsontokens=qa-progress-healthy:--accent, qa-progress-warning:--warning, qa-progress-error:--error
P2A-026PASS时长实时更新 · `advanceClock` 推进时自动变 · 格式 `HH:mm:ss` 或 `m 分 s 秒`(locale)screenshots/P2A-02/l06-duration-update.json1 分 5 秒 -> 1 分 6 秒
P2A-027PASS卡片点击 · 若 run 有 sessionId · 跳 `/chat?session=xxx` · 否则跳 `/sessions?runId=xxx`screenshots/P2A-02/l07-run-navigation.json/chat?session=session-route-proof | /sessions?runId=qa-route-run
P2A-028PASS键盘 · Tab 可聚焦 · Enter 触发点击 · focus ring 2pxscreenshots/P2A-02/l08-run-keyboard.jsonfocus=qa-keyboard-run, route=/chat?session=keyboard-proof
P2A-029PASS`run.state_changed` event · 卡片 500ms 淡入 · 不 reflow 其他卡片screenshots/P2A-02/l09-state-change-fade.jsonanimation=run-fade, stable=true
P2A-031PASS行高 72 · 横向 flex · 左风险 badge 48×48 · 中标题 + meta · 右 "去处理" 按钮screenshots/P2A-03/a01-approvals-layout.jsonrow=74px badge=48x48
P2A-032PASS最多渲染 3 条 · 超过显示 "全部查看 (N)" link · 跳 /assistant?tab=approvals · 保留 packIdscreenshots/P2A-03/a02-approvals-cap.jsonrows=3, route=/assistant?tab=approvals&packId=industry-cross-border-ecommerce
P2A-033PASS风险 badge 3 色 · `low` 琥珀 / `medium` 黄 / `high` 红 · 图标对应 ShieldCheck / ShieldAlert / Sirenscreenshots/P2A-03/a03-approval-badges.jsonapproval-policy:ShieldCheck/--accent, approval-provider:ShieldAlert/--warning, approval-warehouse:Siren/--error
P2A-034PASS标题 2 行截断 · meta 1 行 · 显示 "来自 {channelName} · {timeAgo}"screenshots/P2A-03/a04-approval-copy.json来自 邮件 · 11 分钟前
P2A-035PASS点"去处理" · 跳 /assistant?approvalId=xxx · MUST NOT 在 home 行内处理screenshots/P2A-03/a05-approval-navigation.json/assistant?approvalId=approval-warehouse
P2A-036PASS键盘 Tab 遍历 3 条 + "全部查看" · focus ringscreenshots/P2A-03/a06-approval-keyboard.json/assistant?tab=approvals&packId=industry-cross-border-ecommerce -> /assistant?approvalId=approval-warehouse -> /assistant?approvalId=approval-provider -> /assistant?approvalId=approval-policy
P2A-037PASS空 · 段 3 条文案 "没有待决定事项" · 不留灰块screenshots/P2A-03/a07-approval-empty.json暂时没有需要你决定的事没有待决定事项Friday 会把真正跨过人工边界的动作放回这里。
P2A-041PASS行高 56 · 左时间刻度 80px · 右内容 · 时间格式 `formatAutomationNextRun`(locale 敏感)screenshots/P2A-04/s01-scheduled-layout.json4月20日 14:36 @ 69.671875px
P2A-042PASS按 `nextRunAt` 升序 · null 排最后 · 过滤 `enabled === true` 优先screenshots/P2A-04/s02-scheduled-order.jsonearly -> late -> manual -> disabled-timed -> disabled-manual
P2A-043PASS最多 5 行 · 第 6 行替换成 "+{N-5} 更多" link · 跳 /automationsscreenshots/P2A-04/s03-scheduled-cap.jsonrows=5, route=/automations
P2A-044PASSdisabled 行 opacity 0.35 · time 显示 "已暂停" · cron 文字也置灰screenshots/P2A-04/s04-scheduled-disabled.json已暂停, opacity=0.35
P2A-045PASS悬浮 row · 底色 `--bg-sunken` · cursor pointer · 点跳 /automations?automationId=xxxscreenshots/P2A-04/s05-scheduled-hover.jsonhover=--bg-sunken, route=/automations?automationId=qa-hover-auto
P2A-046PASS时间变化(`advanceClock`)· time 列重算 · 文字更新screenshots/P2A-04/s06-scheduled-clock.json4月20日 14:28 -> 4月20日 14:36
P2A-047PASS0 条 · 段替换成 "接下来没有计划中的自动任务" 文案 · 不渲染段标题screenshots/P2A-04/s07-scheduled-empty.json接下来没有计划中的自动任务
P2A-051PASSC01 · empty · 首次进入 composer 居中(vertical + horizontal)· 快捷 prompt 3 张 · 点击填入 composerscreenshots/P2A-05/c01-empty-layout.jsonquickCards=3, prompt="复核今天的高风险运行"
P2A-052PASSC02 · user-sent · 发送后 user bubble 右侧 · 紧接 "Friday 在思考…" 左侧 typing indicator · 3 个点循环动画 400ms 一轮screenshots/P2A-05/c02-user-thinking.jsonrows=2, dots=3, duration=0.4s
P2A-053PASSC03 · streaming · assistant bubble 字符逐字进入(每 30ms 一字)· 末尾光标闪烁 500ms 周期 · 流结束光标消失screenshots/P2A-05/c03-streaming-timing.jsonmean=30.07ms, stddev=0.76ms, caretStates=1
P2A-054PASSC04 · tool-call 展开 · ChatToolActivity 入流 · 默认折叠 · 显示工具名 + 状态 dot · 点击展开 parameters + result JSONscreenshots/P2A-05/c04-tool-call-expand.jsontool=inventory.fetch, open=true
P2A-055PASSC05 · approval · ChatActionCard 流转 3 态 pending → approved → used · 状态变化有图标切换 + 底色过渡 250msscreenshots/P2A-05/c05-approval-flow.json等待决定 -> 已批准 -> 已使用
P2A-056PASSC06 · autonomous-step · AutonomousStepIndicator 独立行 · "步骤 3/7 · 正在查询渠道日志" · 有小 spinnerscreenshots/P2A-05/c06-step-indicator.json步骤 3/7 · 正在查询渠道日志
P2A-057PASSC07 · grant-evidence · grantId 悬浮卡 · 显示 `{ scope, expiresAt, source }` · 空字段不显示 · 位置 top + 箭头screenshots/P2A-05/c07-grant-tooltip.jsontooltip="Scope: supplier.switchExpires: 2026-04-20T15:10:00-07:00Source: approval-warehouse"
P2A-058PASSC08 · session-resume · 刷新后 sessionKey 从 `localStorage.getItem('friday-chat-session-key')` 读 · 历史气泡顺序与刷新前一致screenshots/P2A-05/c08-session-resume.jsonhash=cd9e78dbb973…, session=chat:default:resume-evidence
P2A-059PASSC09 · disconnected · WS 断开 3 秒内顶部红色条 "连接已断开 · 正在重试 ({retry_count})" · 重连成功后 500ms 淡出screenshots/P2A-05/c09-disconnected-banner.json连接已断开 · 正在重试 (1) -> fading -> hidden
P2A-0510PASS消息最大 840px · 中央对齐 · 左右各 flex gutterscreenshots/P2A-05/c10-message-width.jsontimeline=436px, bubble=288px
P2A-0511PASS新消息自动滚底 · 若用户手动向上滚超过 200px · 不自动滚 · 改显右下 "新消息 ↓" 浮标screenshots/P2A-05/c11-auto-scroll.jsonnearBottom=5908/5908, farGap=829
P2A-0512PASS> 50 条消息启用虚拟化(react-window 或等价)· 滚动 FPS ≥ 55screenshots/P2A-05/c12-virtualized-fps.jsonrendered=21, fps=60.00
P2A-0513PASScomposer Enter 发 · Shift+Enter 换行 · / 唤起 slash 菜单 · Escape 关菜单screenshots/P2A-05/c13-composer-keys.jsonnewline preserved, slashItems=6, history=4
P2A-0514PASScomposer 附件支持拖入 + 点击上传 · 上传中显示进度 bar · 失败有 retryscreenshots/P2A-05/c14-upload-flow.json上传失败,可重试 -> 上传完成
P2A-0515PASSactivity-rail 显示最近 10 个 session · 当前 session 高亮 · 点击切换不丢当前输入screenshots/P2A-05/c15-session-rail.jsonsessions=10, restored="draft-alpha"
P2A-0516PASSside-panel 显示 run 详情 / grant 详情 / trace · Ctrl+\ 切换开关screenshots/P2A-05/c16-side-panel-toggle.jsonRun detail运行侧栏run=session-replenish-watchgrant=grant-warehouse-budgettrace=trace-home-0420ws=1audit
P2A-0517PASSData contract 严格用 `useChatSession` + `useAgentRunEvents` · 不开第二个 WS · Network panel 只 1 条 WSscreenshots/P2A-05/c17-data-contract.jsonlogicalWs=1, networkWs=0, eventSources=0
P2A-0518PASSgit diff 证明 ChatMessageBubble / ChatToolActivity / ChatActionCard / AutonomousStepIndicator 四个组件文件无修改(本静态原型内复制品亦不改 props)screenshots/P2A-05/c18-props-diff.jsonChatMessageBubble: missing=0, extra=0 | ChatToolActivity: missing=0, extra=0 | ChatActionCard: missing=0, extra=0 | AutonomousStepIndicator: missing=0, extra=0
P2A-061PASS`turn.kind` switch 穷举 6 值 · `message | tool | action | step | time-divider | grant` · default branch throw · 不允许 fallback silentscreenshots/P2A-06/l01-switch-exhaustive.jsonUnsupported turn.kind: unknown-kind
P2A-062PASStime-divider · 横线 + 中间日期 · 当某 turn 与上一条相隔 > 10 分钟自动插入screenshots/P2A-06/l02-time-divider.json4月20日 3:15
P2A-063PASS自动滚底逻辑 · 新 turn 进入时若 scrollTop >= scrollHeight - 300 · 平滑滚底screenshots/P2A-06/l03-auto-bottom.jsontop=4526, max=4526
P2A-064PASS> 50 条时虚拟化 · 仅渲染可视 + 上下 5 条 bufferscreenshots/P2A-06/l04-virtual-window.jsonrendered=21/21
P2A-065PASSscroll 位置在 session 切换前写 `localStorage['friday-chat-scroll-' + sessionId]` · 切回恢复screenshots/P2A-06/l05-scroll-restore.jsonrestored=860, localStorage=860
P2A-066PASS每 turn 有 `data-turn-id` 属性 · 便于 e2e 定位screenshots/P2A-06/l06-turn-ids.jsonturn-msg, tool-check, turn-action, goal-test, divider-4, turn-grant
P2A-067PASS同一 turn id 两次更新(stream 过程中)不重渲染整 bubble · React key 稳定screenshots/P2A-06/l07-stable-row.jsonsameRow=true, chars=11->18
P2A-068PASS键盘 · Tab 可进 turn · 方向键在 turns 间切换 focus · Enter 展开工具 / 审批screenshots/P2A-06/l08-keyboard-nav.jsontab=turn-user-1, down=tool-inventory-fetch, actionFocus=chat-action-pill is-approve
P2A-071PASStextarea 初始 80px · 内容增多自动长到 320 · 超过出滚动条 · 不撑破 composer 容器screenshots/P2A-07/i01-composer-height.json80 -> 320px -> 320px
P2A-072PASSEnter 发送 · Shift+Enter 换行 · Cmd+Enter 也发送 · Escape 清空当前内容(需确认)screenshots/P2A-07/i02-send-keys.jsonnewline ok, cmdSend=4, confirm="清空当前输入?"
P2A-073PASS/ 作为首字符唤起 slash 菜单 · 菜单条目从 `slashCommands` 静态数组来 · 至少 6 条screenshots/P2A-07/i03-slash-source.jsonnew, clear, skills, workflows, settings, help
P2A-074PASSslash 菜单在 composer 上方 · max-h 320 带滚动 · ↑↓ 选择 · Enter 确认 · Escape 关screenshots/P2A-07/i04-slash-navigation.jsonactive=/skills技能库, value="/skills "
P2A-075PASS附件 · 支持拖入 composer 区域 · drop 区 dash border 琥珀 · 非允许类型 toast 错误screenshots/P2A-07/i05-invalid-drop.jsonERROR不支持的附件类型
P2A-076PASSstreaming 期间 composer disabled · placeholder 变 "Friday 正在回答,请稍候" · 发送按钮灰screenshots/P2A-07/i06-streaming-disabled.jsonFriday 正在回答,请稍候, opacity=0.4
P2A-077PASS发送按钮 · 琥珀 fill · 空输入时 opacity 0.4 · 点击 200ms press feedbackscreenshots/P2A-07/i07-send-feedback.jsonempty=0.4, filled=rgb(154, 93, 37), pressed=matrix(0.991181, 0, 0, 0.991181, 0, -0.706019)
P2A-078PASS字符计数 · 2000 字以下不显 · 超过显示 "1923 / 2000" · 超限红色 + 禁发screenshots/P2A-07/i08-char-count.json1923 / 2000 / 2001 / 2000
P2A-079PASS草稿 auto-save · 每 500ms debounce 写 `localStorage['friday-chat-draft-' + sessionId]` · 切换 session 恢复screenshots/P2A-07/i09-draft-save.jsondrafts=draft-one/draft-two
P2A-081PASSlocalStorage 键名严格 · `friday-chat-session-key` + `friday-chat-history` · 命名不得变screenshots/P2A-08/h01-storage-keys.jsonsessionKey=true, historyKey=true
P2A-082PASShistory 结构 · `{ sessionKey: string, turns: Turn[], updatedAt: number }` · Turn 类型照真仓screenshots/P2A-08/h02-history-shape.jsonturns=2, updatedAt=1776767457634
P2A-083PASS新建 session · 先 POST 后拿到 key 再写入 · 不得先写本地 fake keyscreenshots/P2A-08/h03-create-session.jsonsessionKey=chat:default:chat-mo8hgx7d-aqe77x
P2A-084PASS刷新后 turns 顺序 index === 刷新前 · 对比 `JSON.stringify` 结构等价screenshots/P2A-08/h04-refresh-hash.jsonhash=2ab1bca10ee8…
P2A-085PASS过期(> 7 天 updatedAt)· 清除 · 进入空态 · 不报错screenshots/P2A-08/h05-expired-history.jsonemptyVisible=true, history={}
P2A-086PASSlocalStorage 不可用(隐身 / 禁用)· graceful 降级 · 页面可用 · 不得 crashscreenshots/P2A-08/h06-storage-blocked.jsoncomposer="still usable", errors=0
P2B-011PASSsnapshot 从 `uixSnapshotsApi.getAssistantInbox()` · polling 12s active / 36s backgroundscreenshots/P2B-01/b01-polling.jsonactive=12000ms, hidden=36000ms
P2B-012PASSURL `?tab=` 3 值有效 · 其他值 fallback approvals · 历史栈前进后退同步screenshots/P2B-01/b02-tabs-history.jsoninvalid=approvals, back=approvals, forward=issues
P2B-013PASStab 切换不刷页 · 仅 section 切换动画 fade 150msscreenshots/P2B-01/b03-tab-fade.jsonassistant-approvals-section -> assistant-issues-section (0.15s)
P2B-014PASS`?packId=` 存在时 · 左列自动 scroll 到该 card · 该 card 高亮 2 秒后恢复screenshots/P2B-01/b04-pack-scroll.jsonscrollTarget=industry-cross-border-ecommerce, restored=assistant-pack-group
P2B-015PASSApprovals 段显示 `pendingApprovals` 全部(不像 home 切 3)screenshots/P2B-01/b05-all-approvals.jsonrendered=5, snapshot=5
P2B-016PASSIssues 段调 `assistantDiagnosticsApi` · 按时间降序screenshots/P2B-01/b06-issues-order.jsonissues=3, descending=true
P2B-017PASSRecovery 段列出 learning insight + 建议动作 · 调 `learningApi`screenshots/P2B-01/b07-learning-recovery.jsoncards=3
P2B-018PASS右 insight panel 默认显示"今日学习" · 可折叠 · 状态持久化 localStoragescreenshots/P2B-01/b08-panel-persist.jsontitle=今日学习, storage=collapsed
P2B-019PASSpack-related card 用 `PackAssistantHandoffCard` · cross-border 用 `CrossBorderAssistantHandoffCard`screenshots/P2B-01/b09-pack-components.jsonpack=true, crossBorder=true
P2B-0110PASS确认 / 拒绝动作触发 `ConfirmDialog` · 二次确认 · high-risk 需输入 pack 名确认screenshots/P2B-01/b10-confirm-dialog.jsonhighRiskInput=跨境经营动作板, mediumHasInput=false
P2B-0111PASS空态 · "没有待办、没有问题、一切正常" · 米色插图(允许 line-art SVG · 不用 emoji)screenshots/P2B-01/b11-empty-state.jsonsvgPaths=1, title=没有待办、没有问题、一切正常
P2B-0112PASS错误态 · inline 错误条 + retry · 不影响其他段screenshots/P2B-01/b12-error-bar.jsonissues=3, recovery=3
P2B-0113PASS计数 badge 实时更新 · dispatch `approval.resolved` 后 -1screenshots/P2B-01/b13-badge-realtime.json4 -> 3
P2B-021PASS卡片宽满列 · min-h 180 · padding 20 · radius 14screenshots/P2B-02/a01-card-box.jsonwidth=448px, radius=14px
P2B-022PASS顶行 · 风险 badge(low/med/high)+ 来源 channel + 时间 · 右侧 Copy ID 按钮screenshots/P2B-02/a02-top-row.jsonhigh, 邮件 · 9 分钟前
P2B-023PASS标题行 · h3 font serif 20 · 不截断 · 允许 2 行screenshots/P2B-02/a03-title-wrap.jsonlineCount=1.00, font=20px
P2B-024PASSCapabilities 列表 · tag 样式 · 每个 capability 有图标 + 文字 · 悬浮 tooltip scope 描述screenshots/P2B-02/a04-capability-tooltip.jsonicon=◎, tooltip="允许 Friday 在本次补货决策里读取并比较预算方案。"
P2B-025PASSEvidence 展开 · 默认折叠 · 点 "查看证据" 展开 · 显示 grantId / toolCalls / timestampsscreenshots/P2B-02/a05-evidence-expand.jsongrantId=grant-warehouse-shift-2042, calls=3
P2B-026PASSpending 状态 · 主按钮 "批准" + 次按钮 "拒绝" · high-risk 时主按钮灰 · 需输入确认词screenshots/P2B-02/a06-pending-actions.jsonhigh=action-button action-button-secondary, medium=action-button action-button-primary
P2B-027PASSapproving/denying 中 · 按钮 spinner 图标 + 禁用 · 250ms 内给反馈screenshots/P2B-02/a07-busy-feedback.jsonelapsed=3.7ms
P2B-028PASSapproved · 整卡 opacity 0.6 · 顶部勾图标 · 文字 "已批准 · {time}"screenshots/P2B-02/a08-approved-card.jsonopacity=0.6, icon=✓
P2B-029PASSdenied · 整卡红底 · 文字 "已拒绝 · {reason}"screenshots/P2B-02/a09-denied-card.jsonmedSlack · 22 分钟前×Copy ID是否允许 Friday 在 provider 降级后自动改用次优模型◌路由切换允许 Friday 在当前运行里把模型切到降级 provider。△SLA 兜底允许 Friday 在质量下降前提下优先守住响应时延。查看证据{ "grantId": "grant-provider-fallback-1881", "toolCalls": [ "provider.health", "routing.preview" ], "timestamps": [ "2026-04-20T20:56:00.000Z", "2026-04-20T21:18:00.000Z" ] }已拒绝 · 暂不接受降级到次优模型
P2B-0210PASSexpired · 虚线 border · 文字 "已过期 · 请重新请求"screenshots/P2B-02/a10-expired-card.jsonmedSlack · 22 分钟前Copy ID是否允许 Friday 在 provider 降级后自动改用次优模型◌路由切换允许 Friday 在当前运行里把模型切到降级 provider。△SLA 兜底允许 Friday 在质量下降前提下优先守住响应时延。查看证据{ "grantId": "grant-provider-fallback-1881", "toolCalls": [ "provider.health", "routing.preview" ], "timestamps": [ "2026-04-20T20:56:00.000Z", "2026-04-20T21:18:00.000Z" ] }已过期 · 请重新请求
P2B-031PASS卡片结构 · 状态 dot + 标题 + "根因" 展开 + recovery 链 + 操作栏screenshots/P2B-03/i01-card-structure.jsonrecoveryRows=2, timelineRows=3
P2B-032PASS状态 · open(红 dot)/ investigating(黄 + spinner)/ recovered(绿 + 勾)/ dismissed(灰 + 叉)screenshots/P2B-03/i02-status-variants.jsonopen=rgb(165, 48, 40), investigating=rgb(143, 84, 19), dismissed=rgba(45, 33, 24, 0.34)
P2B-033PASS根因展开 · 默认折叠 · 点击展开 technical detail · 不暴露堆栈 · 用 `describeRunHealth` 文字screenshots/P2B-03/i03-root-cause-expand.json这是阻塞性失败,需要先处理。
P2B-034PASSrecovery 链 · 最多 3 步 · 每步有 "执行" 按钮 · 执行中 disabledscreenshots/P2B-03/i04-recovery-chain.jsonrows=2, spinner=2
P2B-035PASSdismiss · 二次确认 · "确定不追查?" + 理由文本框(选填)screenshots/P2B-03/i05-dismiss-confirm.json确定不追查?, textarea=true
P2B-036PASS时间线 · 事件有时间戳 · 倒序最新在上screenshots/P2B-03/i06-timeline-order.json14:08 > 14:05 > 14:02
P2B-037PASS关联 runId · 点击跳 `/sessions?runId=xxx`screenshots/P2B-03/i07-run-link.json/sessions?runId=run-provider-circuit
P2B-038PASSrecovered 后卡片 30 秒后自动 collapse 到 60 高 · 可展开screenshots/P2B-03/i08-recovered-collapse.jsoncollapsed=60, expanded=330.046875
P2B-041PASS复用 `LearningInsightCard` · props 不改 · wrap 只负责 data bindingscreenshots/P2B-04/l01-signature-bindings.jsonsource=true, wrapper=true
P2B-042PASStone 3 档 · positive 绿边 / warning 黄边 / neutral 米边screenshots/P2B-04/l02-tone-borders.jsoninsight-route-learning:rgba(47, 122, 73, 0.26) | insight-provider-warning:rgba(184, 106, 23, 0.28) | insight-workflow-neutral:rgba(45, 33, 24, 0.1)
P2B-043PASS点 "应用建议" · 跳对应页(skill / workflow / settings)screenshots/P2B-04/l03-apply-routes.json/skills, /settings?tab=runtime, /workflows
P2B-044PASSdismiss 写 localStorage `friday-insights-dismissed` setscreenshots/P2B-04/l04-dismiss-storage.jsonstorage=["insight-route-learning"]
P2B-051PASS左 sub-nav 200 固定宽 · 4 tab · 竖排 · 当前 tab 左 2px 琥珀竖线 + 粗体screenshots/P2B-05/s01-subnav-layout.jsonwidth=200, tabs=4, stripe=2px
P2B-052PASSURL `?tab=providers|runtime|diagnostics|account` · 默认 providers · 不识别 fallbackscreenshots/P2B-05/s02-tab-url-sync.json?dev=1 -> ?tab=runtime&__state=runtime -> ?dev=1
P2B-053PASS右主区 · 顶 h2 tab 名 · 下表单 + 内容screenshots/P2B-05/s03-main-region.jsondiagnostics=诊断与保留策略, account=身份与偏好
P2B-054PASS底部吸附 Save bar · 128 高 · 仅有 dirty 时显示 · 显示 "有 N 项未保存"screenshots/P2B-05/s04-save-bar-sticky.jsonvisible=true, bottom=1200, height=128
P2B-055PASSdirty 时切换 tab · `ConfirmDialog` "放弃修改?" · 确认走 / 取消留screenshots/P2B-05/s05-tab-switch-confirm.json运行时 -> 账号
P2B-056PASSdirty 时离开 route · `beforeunload` 确认screenshots/P2B-05/s06-beforeunload.jsondirty=true, clean=false
P2B-057PASSSave 按钮 · 禁用当 invalid · loading 时 spinnerscreenshots/P2B-05/s07-save-disabled-loading.jsoninvalid=true, loadingSpinner=true
P2B-058PASSSaved 后 toast 右下 · 3 秒淡出 · "已保存"screenshots/P2B-05/s08-save-toast.jsontoast=SUCCESS已保存, fading=toast-card is-success is-fading
P2B-059PASS字段级错误 · 红边 + 下方错误文字 · i18nscreenshots/P2B-05/s09-field-errors.json请输入有效邮箱地址。 | Enter a valid email address.
P2B-0510PASStab 之间 URL 切换不丢未保存(本 tab)screenshots/P2B-05/s10-tab-draft-preserved.jsonrestored=15000, dirty=["runtime-budget"]
P2B-0511PASSReset 按钮 · 位于 save bar 左 · 二次确认screenshots/P2B-05/s11-reset-confirm.jsonresetX=896.765625, saveX=979.453125, restored=12000
P2B-061PASS每 provider 一行 · 左 logo 24 + 名 · 中 health dot + latency · 右 配额 + actionsscreenshots/P2B-06/p01-provider-row-structure.jsonrows=5, actions=3/3/3/3/3
P2B-062PASShealth dot 3 色 · healthy 绿 / degraded 黄 / offline 红 · 动态脉冲(reduced-motion 下静态)screenshots/P2B-06/p02-health-dots.jsonstates={"healthy":"--success","degraded":"--warning","offline":"--error","cooldown":"--ink-3"}, interval=30000
P2B-063PASSlatency · 显示 p50 / p95 · 数值 mono 字体 · p95 > 1000ms 黄色screenshots/P2B-06/p03-latency-metrics.jsonp50 530ms | p95 1320ms
P2B-064PASScircuit breaker · 3 态 closed(绿)/ open(红)/ half-open(黄)· tooltip 解释screenshots/P2B-06/p04-circuit-tooltip.jsonclosed当前没有命中熔断条件,流量仍走主路径。 | half-open正在小流量试探恢复,下一轮健康检查决定是否回到 closed。 | open熔断已打开,等待冷却结束后才会重试主 provider。
P2B-065PASSopen 时 cooldown 倒计时 · 实时更新 · `mm:ss`screenshots/P2B-06/p05-cooldown-countdown.jsoncooldown 05:05 -> cooldown 05:04
P2B-066PASSedit key · 弹出 modal · input 隐藏(••••)· show/hide togglescreenshots/P2B-06/p06-edit-key-modal.jsonsecret=password -> text
P2B-067PASStest connection 按钮 · 点后 loading 3 秒 · 返回结果 toastscreenshots/P2B-06/p07-test-connection.jsonelapsed=3056.6ms
P2B-068PASSdisable provider · 二次确认 · disabled 后整行置灰 + opacity 0.5screenshots/P2B-06/p08-disable-provider.jsonopacity=0.5, class=provider-row is-disabled
P2B-069PASS添加 provider · 底部 + 按钮 · 弹出 modal · 预设 5 个官方 preset + "自定义"screenshots/P2B-06/p09-add-provider.jsonpresets=6, rows=5->6
P2B-071PASS5 focus 全部可切 · 切换无页面重载 · URL 同步screenshots/P2B-07/o01-focus-tabs-url.jsonmount=observability-shell-v1, deeplink=audit, nav=1
P2B-072PASS时间窗切换 refetch · loading 态显 skeleton · 不清空现有数据screenshots/P2B-07/o02-window-loading.jsonskeletons=3->0, rows=12
P2B-073PASSalerts focus · list 显示 firing + snoozed + resolved 三段 · 按 severity 排序screenshots/P2B-07/o03-alert-sections.jsonfiring=2, snoozed=2, resolved=2
P2B-074PASStraces focus · list 显示 trace row(traceId + duration + spans + status)· 点开 detail drawer(§P2B-08)screenshots/P2B-07/o04-trace-drawer.jsonrows=3, drawer=trace
P2B-075PASSaudit focus · list 显示审计事件 · actor + action + target + time · filter 按 actorscreenshots/P2B-07/o05-audit-filter.jsonfilters=all/friday/jarvis, rows=1
P2B-076PASShealth focus · 显示系统健康大盘 · CPU / mem / queue 三个 sparkline · `selectObservabilityPrimaryHealthComponent`screenshots/P2B-07/o06-health-dashboard.jsonprimary=queue, cards=3
P2B-077PASSacceptance focus · 显示 acceptance criteria pass/fail 聚合 · 点击跳 assistantscreenshots/P2B-07/o07-acceptance-navigation.jsonrows=6, route=/assistant?tab=approvals&phase=2a
P2B-078PASS每 focus 的 list 空态有独立文案 · 不共用screenshots/P2B-07/o08-empty-copy.jsontitles=5, focuses=alerts/traces/audit/health/acceptance
P2B-079PASS每 focus 的 error 态 inline 错误条 · 不跳 splashscreenshots/P2B-07/o09-error-state.jsonfocuses=alerts/traces/audit/health/acceptance
P2B-0710PASS时间窗 15m 时 polling 5s · 1h 时 15s · 24h 时 60sscreenshots/P2B-07/o10-poll-intervals.json15m=5000, 1h=15000, 24h=60000
P2B-0711PASSlist 行 hover 底色 · 点击左边 2px 琥珀条标记 activescreenshots/P2B-07/o11-row-hover-active.jsonhover=rgba(246, 237, 222, 0.973), stripe=2px
P2B-0712PASSdetail 区 · focus 切换时清空并显示 "选择一条查看详情" 空态screenshots/P2B-07/o12-detail-reset.jsonbefore=alert-1, after=选择一条查看详情
P2B-0713PASSalert actions · create(§P2B-09)· snooze · edit · deletescreenshots/P2B-07/o13-alert-actions.jsonactions=新建告警/批量暂停 1h/导出列表, delete=删除这个告警?
P2B-0714PASStraces 行 · 超过 2000ms 红色 latency · 500-2000ms 黄screenshots/P2B-07/o14-trace-latency-colors.json--error/--warning/null
P2B-0715PASSaudit 行有 diff 按钮 · 点开二级 drawer 显示 before / after JSONscreenshots/P2B-07/o15-audit-drawer.jsondrawer=audit, selected=audit-1
P2B-0716PASShealth sparkline · 60 个 data point · hover 显具体时间 + 值screenshots/P2B-07/o16-health-tooltip.jsoncpu=60, tooltip=14:18 · 44%
P2B-0717PASS`buildObservabilityActionQueue` 驱动右上角 action 按钮组 · 按 focus 显示不同按钮screenshots/P2B-07/o17-action-queue.jsonqueues=5, alerts=新建告警/批量暂停 1h/导出列表
P2B-081PASSdrawer 右侧滑入 420 · 200ms ease-out · Escape 关screenshots/P2B-08/t01-trace-drawer-shell.jsonwidth=420, animation=0.2s, closed=false
P2B-082PASS头部 · traceId + duration + status + close 按钮screenshots/P2B-08/t02-trace-header.jsontitle=trace-932af, header=2430ms/failed
P2B-083PASSspan tree 竖排 · 缩进表达 parent-child · 每 span 一行 · 行高 28screenshots/P2B-08/t03-span-tree-indent.jsonrows=4, depths=span-route-root:0,span-tool-inventory:1,span-db-audit:2,span-tool-pricing:1
P2B-084PASSspan 有 3 色 dot · tool 琥珀 / LLM 紫 / DB 青screenshots/P2B-08/t04-span-dot-colors.jsonspan-tool-inventory:--warning, span-route-root:--trace-llm, span-db-audit:--trace-db
P2B-085PASSspan 点击展开 · 显示 start/end/duration/attributes · 默认折叠screenshots/P2B-08/t05-span-expand.jsonvisible=1->3, attrs=1
P2B-086PASSspan 超过 1000ms · 红文字screenshots/P2B-08/t06-slow-span-color.json1180ms -> --error
P2B-087PASS可搜索 spans · 输入框顶部 · 即时过滤screenshots/P2B-08/t07-trace-search.jsonvisible=4->2
P2B-088PASSexport JSON 按钮 · 下载 trace.jsonscreenshots/P2B-08/t08-trace-export.jsontrace.json spans=4
P2B-091PASSlist · 每 alert 一行 · 状态 dot + 名称 + 指标 + 阈值 + 最近触发 + actionsscreenshots/P2B-09/m01-alert-list-row.jsonprovider p95 超阈值 · latency.p95 / > 2000ms / 14:10
P2B-092PASScompose modal · 3 字段必填 · 指标(select 20+ option)+ 阈值(数字 + 比较符)+ 通知渠道(multi-select)screenshots/P2B-09/m02-compose-modal.jsonoptions=23, comparators=5, channels=7
P2B-093PASScompose 验证 · 空字段红边 + 下方错误 · 阈值非数字禁交screenshots/P2B-09/m03-compose-validation.jsonstep1=名称不能为空。, step2=阈值必须是数字。
P2B-094PASSsnooze · 弹出 4 档选项 1h / 4h / 24h / 永久 · 选后 row 变虚线 border + "snoozed until ..."screenshots/P2B-09/m04-alert-snooze.jsonmenu=1 小时/4 小时/24 小时/永久, row=obs-row obs-alert-row is-snoozed is-active
P2B-095PASSfiring row · 红底 + 脉冲 dot · 顶部有 "N 正在触发" bannerscreenshots/P2B-09/m05-firing-banner.json2 正在触发 / --error-soft
P2B-096PASSedit · 行内按钮 · 打开 modal 预填当前值screenshots/P2B-09/m06-edit-prefill.json队列堆积 / >50
P2B-097PASSdelete · 二次确认 · 输入 alert 名二次验证screenshots/P2B-09/m07-delete-confirm.jsonconfirm=删除这个告警?, exact=false
P2B-098PASS新建后自动刷 list · row 入场 fade-in · 滚到其位置screenshots/P2B-09/m08-new-alert-row.jsonrow=alert-custom-0000, scroll=smooth
P2B-099PASSdev switcher · 4 状态 list / creating / snoozed-sample / firing-samplescreenshots/P2B-09/m09-dev-switcher.jsonstates=list/creating/snoozed-sample/firing-sample
P2C-011PASS双列 · 左 pinned 280(单列 card)· 右 catalog flex(3 列 grid)· 1920 下 4 列screenshots/P2C-01/p01-layout.json1440=3 cols, 1920=4 cols
P2C-012PASS顶部 · search input 400 + category filter chips(6-8 个)+ "+ 自定义 pack" 按钮screenshots/P2C-01/p02-topbar.jsonsearch=400px, chips=6
P2C-013PASSsearch 即时过滤(debounce 150ms)· 匹配 pack.title + description + tagsscreenshots/P2C-01/p03-search-debounce.jsontitle=task-support-ops description=task-release-ops
P2C-014PASSfilter chips 多选 · active 琥珀底 · clear all 按钮screenshots/P2C-01/p04-filter-chips.jsonactive=release/security
P2C-015PASSpack card · 240 高 · 顶部产品预览(PackProductPreview 24)· 中标题 · 底 meta + "打开" 按钮screenshots/P2C-01/p05-pack-card.jsonheight=998.375, tiles=4
P2C-016PASSpinned 列 · 拖拽重排 · 拖后写 `useHomeSurfacePreferences`screenshots/P2C-01/p06-pinned-drag.jsonindustry-cross-border-ecommerce -> task-ship-fast => task-ship-fast -> industry-cross-border-ecommerce
P2C-017PASS卡片 hover · 显 PackQuickSheet tooltip(350ms delay)screenshots/P2C-01/p07-hover-sheet.jsondelay=356.5ms, visible@300=false, visible@420=true
P2C-018PASS点击 pack · 跳 `/packs/{packId}/setup`(目前只 cross-border 有 setup · 其他 toast "即将上线")screenshots/P2C-01/p08-launch-route.json/packs/industry-cross-border-ecommerce/setup / toast=WARNING即将上线
P2C-019PASScross-border pack 显示特殊 badge "专属引导"screenshots/P2C-01/p09-guided-badge.jsonbadge=专属引导
P2C-0110PASS空态(search 无结果)· "没找到相关 pack · 试试其他关键词"screenshots/P2C-01/p10-empty-search.jsonfiltered=0
P2C-0111PASSempty pinned · 左列显示 "置顶你常用的 pack" 空态 · 有拖拽动画提示screenshots/P2C-01/p11-empty-pinned.jsontitle=置顶你常用的 pack
P2C-0112PASScustom pack 入口 · 跳 `CustomPackBuilder` modal(复用 core/custom-pack-builder.tsx)screenshots/P2C-01/p12-custom-pack-modal.json自定义 Pack Builder
P2C-0113PASS`FRIDAY_PACKS` registry 穷举 · 不得 hardcode pack 数据在此页screenshots/P2C-01/p13-registry-source.jsonusesRegistry=true, literals=0
P2C-021PASS顶部 stepper · 4 步 · 当前步琥珀底 + 已完成绿勾 + 未来灰screenshots/P2C-02/w01-stepper.json✓/✓/3/4
P2C-022PASSstep 1 目标 · 多选 cards(增长 / 合规 / 成本 / 扩张)· 至少选 1 · 不选禁下一步screenshots/P2C-02/w02-goal-step.jsonselected=成本
P2C-023PASSstep 2 产品 · 表格输入或 CSV 上传 · 每行 SKU + 标题 + 类目 + 目标市场screenshots/P2C-02/w03-products-table.jsonrows=2->3
P2C-024PASSstep 3 渠道 · 多选 channel card(Amazon / Shopify / TikTok / Temu 等)· 每个 card 显示连接状态screenshots/P2C-02/w04-channel-cards.jsonAmazon:连接正常 | Shopify:连接正常 | TikTok:连接延迟 | Temu:连接正常
P2C-025PASSstep 4 确认 · 汇总前 3 步 · 可点各 section 回编辑screenshots/P2C-02/w05-confirm-edit.jsonstep=2
P2C-026PASSsuccess · 全屏祝贺 + "打开 Assistant 查看下一步" · 跳 `/assistant?packId=industry-cross-border-ecommerce`screenshots/P2C-02/w06-success.jsonheight=980, href=/assistant?packId=industry-cross-border-ecommerce
P2C-027PASS每步 prev / next 底部固定 · prev 在左 · next 在右screenshots/P2C-02/w07-footer-bar.jsonposition=fixed, bottomGap=24
P2C-028PASSstep 切换动画 fade 200ms · URL 同步 `?step=1..4`screenshots/P2C-02/w08-step-url.json?dev=1&__state=step2-products&step=2 / 0.2s
P2C-029PASS退出(点 rail 导航)· `ConfirmDialog` "离开会丢失未保存?"screenshots/P2C-02/w09-leave-confirm.json离开会丢失未保存?
P2C-0210PASS草稿自动保存 · 每步切换写 `crossBorderPackApi.saveDraft()` · 重进自动恢复screenshots/P2C-02/w10-draft-resume.jsonsavedStep=2, resume=true
P2C-0211PASS验证 · 每步字段 level inline 错误 · 步级错误 step 头红点screenshots/P2C-02/w11-validation.json至少选择 1 个目标。 / dots=1
P2C-0212PASSkeyboard · Enter 下一步(step 4 变 "完成")· Shift+Enter 上一步 · Escape 退出确认screenshots/P2C-02/w12-keyboard.jsonEnter=3, Shift+Enter=2
P2C-031PASS双列 · 左 categories tree 240 · 右 skill list flexscreenshots/P2C-03/s01-layout.jsonaside=240px, display=grid
P2C-032PASS顶栏 · search + 2 入口按钮 "导入" "扫描" · 右侧 view toggle(grid / list)screenshots/P2C-03/s02-toolbar.json导入/扫描 / grid/list
P2C-033PASScategories tree · 无限层级 · 展开 / 折叠 · 选中类目过滤右列screenshots/P2C-03/s03-tree-filter.jsonactive=operations, filtered=skill-cross-border-review
P2C-034PASSskill list · grid 3 列 · 每 card 240 高 · 名称 + 版本 + 状态 pill + 动作screenshots/P2C-03/s04-skill-card-grid.jsoncols=3, height=348.53125
P2C-035PASSstatus · installed(绿)/ available(灰)/ deprecated(警示橙)/ needs-update(琥珀)screenshots/P2C-03/s05-status-pills.jsonskill-cross-border-review:--success, skill-finance-watch:--ink-3, skill-ticket-triage:--warning, skill-release-guardian:--accent
P2C-036PASSdeprecated skill · 顶部 banner "此技能已弃用 · 建议替换为 X" · 不让启用screenshots/P2C-03/s06-deprecated-banner.json此技能已弃用 · 建议替换为 Release Guardian / 替换
P2C-037PASSimport wizard 入口 · 打开 `SkillImportWizard` · wizard 不在本页渲染 · 跳 modalscreenshots/P2C-03/s07-import-modal.json导入技能
P2C-038PASSscan 入口 · 打开 `SkillScannerPanel` · 同上screenshots/P2C-03/s08-scan-modal.json扫描技能
P2C-039PASSdiscovery panel 在右下浮层 · 显示 Friday 推荐的未安装 skill · 可关闭 · localStorage 记忆screenshots/P2C-03/s09-discovery-panel.jsonrecommendations=Finance Watch,Workflow Scaffold
P2C-0310PASSskill card 点击 · 跳 `buildSkillHref(skill)` · 不在本页展开 detailscreenshots/P2C-03/s10-skill-href.json/skills?skillId=skill-finance-watch -> /skills?skillId=skill-finance-watch
P2C-0311PASSempty · "还没有技能" · 大 CTA "浏览技能库" + "创建你的第一个技能"(跳 generator)screenshots/P2C-03/s11-empty-state.json浏览技能库:/skills?__state=available | 创建你的第一个技能:/skills/generator
P2C-041PASS双列 · 左 prompt + 配置 480 · 右 preview + test 480screenshots/P2C-04/g01-layout.json480 / 480
P2C-042PASS左列 · intent 多行文本(min-h 200)+ scope 选择 + inputs 定义表格 + outputs 定义表格screenshots/P2C-04/g02-left-fields.jsonscope=workspace, headers=Name/Type
P2C-043PASS右列 · 顶 "生成" 按钮 · 生成中 shimmer · 完成显示 skill YAML / TS 代码screenshots/P2C-04/g03-generate-preview.jsongenerating=3, preview=preview
P2C-044PASStest runner · 底部 fixed · 输入 inputs · 点 "run test" · 显示 output + duration + token costscreenshots/P2C-04/g04-test-runner.jsonTest runner输入测试 payload测试通过 · 输出了 3 条候选检查与 1 条回退建议。 · 780ms · 1364 tokensrun test
P2C-045PASSerror 态 · 生成失败 · 显示 error message + suggestions · retry 按钮screenshots/P2C-04/g05-error-retry.json生成失败 / generating
P2C-046PASSpublish · 确认 modal · 显示 skill diff(新增)· 输入 skill name · 发布后跳 /skillsscreenshots/P2C-04/g06-publish-flow.json确认发布技能 -> /skills?__state=installed
P2C-047PASScancel · 二次确认 · 保留草稿到 localStorage `friday-skill-draft`screenshots/P2C-04/g07-cancel-draft.json取消当前草稿? -> /skills
P2C-048PASSstate · draft / generating / preview / published / error 五档 URL ?state= 同步screenshots/P2C-04/g08-state-query-sync.jsondraft:dev=1&__state=draft&state=draft | generating:dev=1&__state=generating&state=generating | preview:dev=1&__state=preview&state=preview | published:dev=1&__state=published&state=published | error:dev=1&__state=error&state=error
P2C-049PASS再次进入若有草稿 · 提示 "继续上次的草稿?" · yes / noscreenshots/P2C-04/g09-resume-prompt.json继续上次的草稿? / 不用,重置/继续
P2C-0410PASSkeyboard Cmd+Enter = 生成 · Cmd+Shift+Enter = test · Cmd+S = publish confirmscreenshots/P2C-04/g10-keyboard-shortcuts.jsongenerate=preview, publish=确认发布技能
P2C-051PASS双列 · 左 workflow list 420 · 右 detail(最近运行 + 部署状态)flexscreenshots/P2C-05/w01-layout.jsonleft=420px
P2C-052PASS顶栏 · "+ 新建" 按钮跳 `/workflows/builder` + search + status filterscreenshots/P2C-05/w02-toolbar.json/workflows/builder / filters=3
P2C-053PASSworkflow row · 名称 + 当前版本 + 最近运行状态 + 下次触发时间 + menu(编辑 / 复制 / 归档)screenshots/P2C-05/w03-workflow-row.json跨境上新守护 / 编辑/复制/归档
P2C-054PASS点 row · 右侧 detail 加载 · 无页面跳转screenshots/P2C-05/w04-select-detail.jsonworkflow-cross-border-launch -> workflow-incident-brief
P2C-055PASSdetail · 顶 "编辑" 按钮(跳 builder) · 中 runs 表(最近 10)· 底 deploy 状态screenshots/P2C-05/w05-detail-panel.json10 runs / 重新部署
P2C-056PASSrun 行 · 状态 pill + 时长 + 触发源 + logs 按钮 · 失败有 retry 按钮screenshots/P2C-05/w06-run-row.jsonfailed -> running
P2C-057PASSrunning 状态 · 行底 2px 琥珀 progress bar · 宽度实时更新screenshots/P2C-05/w07-running-progress.json77% -> 82%
P2C-058PASSdeploy 状态 · 显示 template version + env + 上次部署时间 · redeploy 按钮screenshots/P2C-05/w08-deploy-state.json模板版本: v12 | prod-us | 上次部署 14:02
P2C-059PASSarchive · 二次确认 · archived workflow 单独 section 显示 · 可 restorescreenshots/P2C-05/w09-archive-restore.json归档这个工作流? / restored=true
P2C-0510PASS空态 · "还没有工作流 · 从模板开始" · 展示 5-6 个模板 card · 点击跳 builder preload templatescreenshots/P2C-05/w10-empty-templates.json6 templates -> /workflows/builder?template=release-qa
P2C-0511PASS多个 running 时 · 全局顶 banner "N 个工作流正在运行"screenshots/P2C-05/w11-running-banner.json2 个工作流正在运行
P2C-061PASS左 lib · 节点按类分组(Triggers / Actions / Logic / Integrations)· 搜索过滤screenshots/P2C-06/b01-library-groups.json8 entries -> integration-github
P2C-062PASS节点拖入 canvas · 创建 node · drop 处 snap to gridscreenshots/P2C-06/b02-drop-node.jsonnode=node-action-648054-95 @ (240, 180)
P2C-063PASS节点之间连线 · hover node 边缘出连接点 · 拖连接点到另一 node 建 edgescreenshots/P2C-06/b03-connect-edge.json4 -> 5 edges
P2C-064PASS连线 · SVG 贝塞尔曲线 · 琥珀色 · 悬浮加粗 · 右键删除screenshots/P2C-06/b04-edge-delete.json2px -> 4px, edges=4->3
P2C-065PASS选中 node · 右 inspector 显示 node 配置 · field 级表单screenshots/P2C-06/b05-inspector-fields.json利润阈值判断 / fields=expression
P2C-066PASS多选 · Cmd+click · 选中多 node · 可批量删除 · 可整体拖动screenshots/P2C-06/b06-multiselect-drag-delete.jsonselected=2, nodes=5->3
P2C-067PASSundo/redo · 最近 20 步 · Cmd+Z / Shift+Cmd+Zscreenshots/P2C-06/b07-undo-redo.jsonhistory=20, nodes=21->22
P2C-068PASSsave · Cmd+S · 验证失败显 toast + 点亮错误 node · 成功 toast + 顶部 "saved {time}"screenshots/P2C-06/b08-save-validation.jsonERROR校验失败,请先修复高亮节点 / saved 14:18
P2C-069PASSdirty 指示 · 顶栏文字 "• 未保存" 琥珀screenshots/P2C-06/b09-dirty-indicator.json• 未保存 / --warning
P2C-0610PASStest · Cmd+Shift+T · 底部 slide up 测试面板 · 输入 trigger payload · 运行 · 每 node 亮绿/红screenshots/P2C-06/b10-test-panel.jsonpassed=2, failed=1
P2C-0611PASSpublish · 弹出 modal · 显示 diff · 输入版本号 · 确认后部署screenshots/P2C-06/b11-publish-modal.json发布工作流 / SUCCESS工作流已部署
P2C-0612PASSvalidation 规则 · 必连触发器 · 必连至少 1 action · 无孤立 node · 无环 · 具体错误 UI 提示screenshots/P2C-06/b12-validation-rules.json至少需要一个 trigger。 | 至少需要一个 action。 | 存在孤立节点,请补上连线或删除它们。 | 存在环路,请打断循环依赖。
P2C-0613PASScanvas 缩放 · Cmd+scroll / Cmd+= / Cmd+- / Cmd+0 重置screenshots/P2C-06/b13-zoom-shortcuts.json1 -> 1.1 -> 1.2000000000000002 -> 1.1 -> 1
P2C-0614PASSminimap 右下角 200×150 · 反映 canvas 整体screenshots/P2C-06/b14-minimap.json200x150, rects=6
P2C-0615PASS键盘选中后 Delete / Backspace 删 node · Escape 取消选中screenshots/P2C-06/b15-delete-backspace-escape.jsonnodes=1->0
P2C-0616PASS复制粘贴 Cmd+C / Cmd+V · 复制到右下偏移 20pxscreenshots/P2C-06/b16-copy-paste.jsonnode-cross-assistant -> node-cross-assistant-copy-5841-12
P2C-0617PASSURL `?workflowId=xxx&template=yyy` · 加载对应模板或已存 workflowscreenshots/P2C-06/b17-url-loading.jsonworkflow:workflow-incident-brief / template:release-qa
P2C-0618PASS退出未保存 · `beforeunload` 确认screenshots/P2C-06/b18-beforeunload.jsondirty=true, prevented=true
P2C-071PASSlist · 每 plugin 一行 · 图标 32 + 名 + 版本 + 状态 + 动作screenshots/P2C-07/p01-plugin-row.jsonGitHub / update-available
P2C-072PASS状态 · installed / enabled / disabled / error / update-availablescreenshots/P2C-07/p02-statuses.jsonupdate-available, enabled, installed, disabled, error
P2C-073PASSversion 比较 · 当前版本旁显"最新 v2.1.0 ↑" 琥珀 link · 点跳 update modalscreenshots/P2C-07/p03-version-link.json最新 v2.1.0 ↑ / 更新插件
P2C-074PASSenable/disable toggle · 立刻生效 · error 状态 toggle 禁用screenshots/P2C-07/p04-toggle-state.jsonenabled -> disabled
P2C-075PASSpermissions · 点击 row 展开详情 · 列出 scopes + filesystem + network 权限 · 与 manifest 对齐screenshots/P2C-07/p05-permissions.jsonrepo, pull_request, workflow, filesystem:read, network:github.com
P2C-076PASSerror row · 红边 + 错误文字 + "查看日志" 按钮 · 打开日志 drawerscreenshots/P2C-07/p06-error-log-drawer.jsonrgb(165, 48, 40) / 插件日志
P2C-077PASSupdate · modal 显示 changelog + permissions diff · 需确认新权限screenshots/P2C-07/p07-update-confirm.json2.1.0 / enabled
P2C-078PASSuninstall · 二次确认 · 保留数据 togglescreenshots/P2C-07/p08-uninstall.json卸载插件 / remaining=4
P2C-079PASS顶部 search · 过滤名称 + 描述 · 右 "+ 添加" 按钮 · 接 registry 或手动上传screenshots/P2C-07/p09-search-add.jsonplugin-computer-use / 添加插件
P2C-081PASSlist · 每 server 一行 · 名 + URL + 状态 + 工具数 + 动作screenshots/P2C-08/m01-server-list.jsonDocs MCP / connected
P2C-082PASS状态 · connected(绿)/ disconnected(灰)/ connecting(琥珀脉冲)/ error(红)screenshots/P2C-08/m02-status-dots.jsonmcp-docs:--success, mcp-warehouse:--ink-3, mcp-github:--warning, mcp-browse:--error
P2C-083PASS点 row 展开工具列表 · 每 tool 名 + 描述 + schema 按钮(打开 JSON drawer)screenshots/P2C-08/m03-tools-schema.jsonsearch_docs,fetch_page,list_sections / Tool schema
P2C-084PASSadd · modal 3 字段 · name + url + auth token · 连接测试按钮screenshots/P2C-08/m04-add-modal.json添加 MCP 服务器 / SUCCESSMCP 测试连接通过
P2C-085PASSdisconnected · "重连" 按钮 + "查看错误" linkscreenshots/P2C-08/m05-reconnect-error.json重连 / connected
P2C-086PASSremove · 二次确认 · 确认后 row fade-out 移除screenshots/P2C-08/m06-remove-fade.json移除这个 MCP 服务器? / rows=3
P2C-087PASSempty · "还没有连接的 MCP 服务器" + add CTA + 文档 linkscreenshots/P2C-08/m07-empty-state.json还没有连接的 MCP 服务器 / 添加服务器
P2C-088PASSserver 实时 ping · 每 30s · 状态 dot 自动更新screenshots/P2C-08/m08-ping-trace.json最近 ping 14:18:00 -> 最近 ping 14:18:30
P2D-011PASS双列 · 左 list 420 · 右 config drawer 460(可关闭后右列消失 · 只 list)screenshots/P2D-01/n01-channel-layout.jsonlist=420, drawer=460, closed=true
P2D-012PASSchannel row · type 图标 24 + 名 + 状态 dot + 最近 session time + menuscreenshots/P2D-01/n02-channel-row.jsonAmazon 店铺 / recent=14:18
P2D-013PASS状态 · healthy / degraded / error · degraded 时显示具体指标(latency 高 / 限流)screenshots/P2D-01/n03-channel-statuses.jsonchannel-amazon:healthy, channel-shopify:degraded, channel-tiktok:error
P2D-014PASSclick row · 右侧 config drawer 滑入 · 200msscreenshots/P2D-01/n04-channel-drawer-transition.jsontrace-drawer-slide-in / 0.2s
P2D-015PASSChannelConfigForm 复用 · 包含 webhook url / auth / rate-limit / timeout 字段screenshots/P2D-01/n05-channel-config-form.jsonsource=true, fields=4/4
P2D-016PASS"测试连接" 按钮 · loading → result toast · 失败显示具体 errorscreenshots/P2D-01/n06-channel-test.json测试中... -> 连接测试失败
P2D-017PASSsave · dirty 状态持续显 · diff 对比按钮(旧 vs 新)screenshots/P2D-01/n07-channel-diff.json有 1 项配置未保存 / dirtyKeys=auth
P2D-018PASSadd channel · 顶部 + 按钮 · 弹 modal · 选 type → 填配置screenshots/P2D-01/n08-channel-add-modal.json添加渠道 / created=channel-github-8170
P2D-019PASS最近 sessions 用 `useChannelSessions` hook · 每 channel 显示最近 5 个 sessionscreenshots/P2D-01/n09-channel-sessions-hook.jsonhook=true, sessions=5
P2D-0110PASSdisable channel · 二次确认 · disabled 的 row 整行 opacity 0.5 · sessions 显示历史screenshots/P2D-01/n10-channel-disable.json停用这个渠道? / opacity=0.5 / sessions=4
P2D-0111PASS空态 · "连接你的第一个渠道" + 支持渠道 grid(逐个 provider icon)screenshots/P2D-01/n11-channel-empty.json连接你的第一个渠道 / providers=5
P2D-021PASS3 tab · Queued · Running · History · 计数 badge 实时screenshots/P2D-02/o01-automation-tabs.jsonqueued 2 -> 1
P2D-022PASS每 tab 一列表 · row 含 name + 触发源 + 进度 bar(running)/ 时长 + actionsscreenshots/P2D-02/o02-automation-row-shape.jsonqueued=午后审批窗口, runningProgress=true, history=failed
P2D-023PASSrunning row · progress bar 实时更新 · 来自 `advanceClock` + mock statescreenshots/P2D-02/o03-automation-progress.json98% -> 100%
P2D-024PASSqueued row · 显示"将于 {time} 运行" · 可 cancelscreenshots/P2D-02/o04-automation-queued.jsoncron / 将于 15:00 运行 / / cancel
P2D-025PASShistory · 最近 50 条 · paginate 或虚拟化 · 按时间倒序screenshots/P2D-02/o05-automation-history.jsonhistory=50, page1=10, descending=true
P2D-026PASSclick row · 打开 logs drawer · 日志行带 timestamp + level(info/warn/error)screenshots/P2D-02/o06-automation-log-drawer.json风险汇总简报 / 14:09:18 | info | 开始汇总 provider 与渠道告警。
P2D-027PASSlogs drawer · tail 模式 · 顶部 auto-scroll toggle · search 过滤screenshots/P2D-02/o07-automation-log-tail.jsonautoScroll true -> false, filtered=1
P2D-028PASSfailed automation · retry 按钮 · 点击 dispatch mock event 重新 queuescreenshots/P2D-02/o08-automation-retry.jsonhistory-1 -> history-1-retry
P2D-029PASS空 · 每 tab 有独立文案 · Queued "没有在排队的任务"screenshots/P2D-02/o09-automation-empty-copy.json没有在排队的任务 / 当前没有运行中的任务 / 还没有历史记录
P2D-0210PASSfilter · 按 trigger source(cron / manual / webhook / chat)· chip 多选screenshots/P2D-02/o10-automation-filters.jsonfilters=cron,manual rows=1
P2D-031PASS双列 · 左 filter + list 420 · 右 detail preview flexscreenshots/P2D-03/p01-sessions-layout.json420px 388px
P2D-032PASSfilter · time(<24h / 7d / 30d / custom)· channel(multi)· type(chat / workflow / automation)screenshots/P2D-03/p02-session-filters.jsontime=7d, channels=channel-shopify, types=automation
P2D-033PASSsession row · title + channel icon + last message time + message count + statusscreenshots/P2D-03/p03-session-row.json跨境补货监控 / active
P2D-034PASSclick row · 右侧 preview · 显示最近 10 条消息 · 不可编辑 · "打开完整会话" 按钮跳 /chat?session=xxxscreenshots/P2D-03/p04-session-preview.jsonpreview=10, href=/chat?session=session-refund-triage
P2D-035PASSpreview 不自动 realtime 更新 · 靠 refresh 按钮screenshots/P2D-03/p05-session-refresh.jsonstable=true, refreshed=true
P2D-036PASS顶部 search · 搜 session title + message content(mock 模拟)screenshots/P2D-03/p06-session-search.jsontitle=session-refund-triage content=10
P2D-037PASSsession 操作 · rename · archive · delete · 每个二次确认screenshots/P2D-03/p07-session-actions.json重命名会话? / archivedGone=0 / deletedGone=0
P2D-038PASSkeyboard · Tab list · 方向键选 session · Enter 打开 /chatscreenshots/P2D-03/p08-session-keyboard.jsonselected=session-provider-circuit, route=/chat?session=session-provider-circuit
P2D-039PASSempty · "开始你的第一次对话" + CTAscreenshots/P2D-03/p09-session-empty.json开始你的第一次对话 / /chat
P2D-0310PASSfilter active 时右上角显 filter chip 组 · 点 × 移除单个 · clear all 按钮screenshots/P2D-03/p10-session-filter-chips.jsonchips=3, afterClearAll=0
P2D-041PASS顶 summary 3 数 · "本月 $X" + "预测 $Y" + "上限 $Z" · 大数字 font serif 40 · 每数下有 label + 对比上月变化screenshots/P2D-04/q01-usage-summary.jsonSpend:US$10,980 | Forecast:US$12,298 | Cap:US$12,000
P2D-042PASS主图 · area chart 横轴 日期 / 纵轴 $ · 高 320 · 响应式screenshots/P2D-04/q02-usage-chart-size.jsonwide=1242x320, narrow=894x320
P2D-043PASSchart hover · tooltip 显示当日 $ + 拆分 providerscreenshots/P2D-04/q03-usage-tooltip.json4/4 / US$490 / providers=5
P2D-044PASSchart 预警阈值线 · 水平虚线 · 红色 · 显示 "budget cap"screenshots/P2D-04/q04-usage-cap-line.json6 6 / --error / budget cap
P2D-045PASS时间窗 toggle · this-month / last-30d / custom · URL `?range=` 同步screenshots/P2D-04/q05-usage-range-query.json/usage?dev=1&__state=this-month&range=last-30d -> /usage?dev=1&__state=this-month&range=custom
P2D-046PASSprovider 表 · 每 provider 一行 · 用量 + 成本 + % 占比 bar + 趋势(up/down/flat)screenshots/P2D-04/q06-usage-provider-table.jsonrows=5 / trend=up
P2D-047PASSsort provider 表 · 按成本 / 用量 · 点 header 切换screenshots/P2D-04/q07-usage-sort.jsoncost[0]=provider-openai, usage[0]=provider-local
P2D-048PASSprovider filter · 表头 chips · 主图同步screenshots/P2D-04/q08-usage-provider-filter.jsonfilters=provider-openai rows=1 tooltipProviders=1
P2D-049PASS超支预警 · 当预测 > 上限 · 页顶 red banner + "调整预算" 按钮跳 /settings?tab=runtimescreenshots/P2D-04/q09-usage-budget-banner.jsontrue / /settings?tab=runtime
P2D-0410PASSUsageCharts 组件复用 · props 不改screenshots/P2D-04/q10-usagecharts-props.jsonfields=cap,points
P2D-0411PASSexport CSV 按钮 · 下载当前时间窗原始数据screenshots/P2D-04/q11-usage-export.jsonusage-last-30d.csv / rows=31
P2D-0412PASS空 · "还没有用量数据" · "开始对话后这里会出现详情"screenshots/P2D-04/q12-usage-empty.json还没有用量数据 / 开始对话后这里会出现详情。
P2D-051PASS双列 · 左 tree 260 + 右 detail flexscreenshots/P2D-05/r01-memory-layout.jsontree=260, detail=548
P2D-052PASStree · 按 scope 分组(user / team / project / session)· 可展开 · 每 scope 计数screenshots/P2D-05/r02-memory-tree.jsonscopes=user,team,project,session expanded=user,project,session
P2D-053PASS选 memory · 右显 content + metadata + source session linkscreenshots/P2D-05/r03-memory-detail.json记忆树 / /sessions?sessionId=session-provider-circuit
P2D-054PASS编辑 · 点 "编辑" 按钮进入编辑模式 · textarea · save/cancelscreenshots/P2D-05/r04-memory-edit-mode.json保存 / 取消
P2D-055PASS编辑需二次确认 · "memory 将影响未来所有会话"screenshots/P2D-05/r05-memory-save-confirm.json保存这条记忆? / memory 将影响未来所有会话
P2D-056PASSdelete · 二次确认 · 输入 memory title 验证screenshots/P2D-05/r06-memory-delete-confirm.json删除这条记忆? / disabled true -> false
P2D-057PASSsource session link · 点跳 /sessions?sessionId=xxxscreenshots/P2D-05/r07-memory-source-link.json/sessions?sessionId=session-provider-circuit -> /sessions?sessionId=session-provider-circuit
P2D-058PASS顶部 search · 全文搜索 · 命中关键词黄色高亮screenshots/P2D-05/r08-memory-search-highlight.json预警 / rows=1
P2D-059PASSempty · "Friday 还没有记住任何事" + 说明 linkscreenshots/P2D-05/r09-memory-empty.jsonFriday 还没有记住任何事 / /memory?help=1
P2D-061PASSgrid · 每 device 一 card 240×180 · 型号 + 状态 dot + 心跳 + 资源 bar + 管理screenshots/P2D-06/s01-fleet-grid.jsoncards=3 size=240x235.65625
P2D-062PASS状态 · online(绿)/ offline(灰)/ warning(黄)screenshots/P2D-06/s02-fleet-status-colors.jsondevice-mac-mini:--success, device-apac-gateway:--ink-3, device-eu-runner:--warning
P2D-063PASS心跳 · 秒级 "最近心跳 3s 前" · 随 advanceClock 实时更新screenshots/P2D-06/s03-fleet-heartbeat.json最近心跳 3s 前 -> 最近心跳 5s 前
P2D-064PASS资源 bar · CPU / RAM / disk 三条 · 超过 80% 变黄 · 超过 95% 红screenshots/P2D-06/s04-fleet-resource-bars.json--warning / --error / --success
P2D-065PASS管理 · menu · restart / logs / removescreenshots/P2D-06/s05-fleet-manage-menu.jsonrestart, logs, remove
P2D-066PASSadd device · + 按钮 · modal · 显示 install 命令 mono 字体screenshots/P2D-06/s06-fleet-add-modal.json添加设备 / curl -fsSL https://fleet.friday.dev/install.sh | sh -s -- --name Warehouse Edge
P2D-067PASSselect device · card 琥珀 border + detail drawer 右出screenshots/P2D-06/s07-fleet-selected-drawer.jsontrue / --accent
P2D-068PASSempty · "还没有连接设备"screenshots/P2D-06/s08-fleet-empty.json还没有连接设备
P2E-011PASS全屏居中 · 卡片 440×auto · radius 28 · shadow 大柔光screenshots/P2E-01/lg01-login-layout.jsonsize=440x580.609375 center=(0,31.9921875)
P2E-012PASSlogo 顶部 · Fraunces "Friday" · 下副标题 "你的工作助手"screenshots/P2E-01/lg02-login-brand.jsonFriday / 你的工作助手
P2E-013PASSemail 输入 + "发送登录链接" 按钮 · 按钮琥珀 fillscreenshots/P2E-01/lg03-login-email-cta.json发送登录链接 / --accent
P2E-014PASSOAuth 区(分割线 + 按钮)· Google / GitHub · 左图标右文字screenshots/P2E-01/lg04-login-oauth.json或者 / Google, GitHub
P2E-015PASSsubmit 失败不清空 email · 错误显红色 inline "邮箱格式不正确" 或 "发送失败 · 请重试"screenshots/P2E-01/lg05-login-errors.json邮箱格式不正确 / 发送失败 · 请重试
P2E-016PASSsubmit 成功 · 全卡 fade 到 "已发送" 态 · 显示 email · "没收到?重试" linkscreenshots/P2E-01/lg06-login-success.json已发送 / ops@friday.dev
P2E-017PASS登录成功跳 `state.redirectTo` · 默认 /screenshots/P2E-01/lg07-login-redirect.jsondefault=/ custom=/command-center
P2E-021PASS4 步 · profile / providers / first-skill / done · stepper 顶部screenshots/P2E-02/su01-setup-stepper.jsonProfile / Providers / First skill / Done
P2E-022PASSstep 1 profile · name + role select + company optionalscreenshots/P2E-02/su02-setup-profile-fields.jsonJarvis / Operator / Friday Labs
P2E-023PASSstep 2 providers · 至少配置 1 个 · 提供 OpenAI / Anthropic / 本地 · 每个有 key 输入 + 测试连接screenshots/P2E-02/su03-setup-providers.jsonproviders=3 configured=openai,local
P2E-024PASSstep 3 first-skill · 3 推荐 skill · 点卡片 install · 至少选 1 · 或跳过screenshots/P2E-02/su04-setup-skills.jsoncards=3 selected=1 skippedStep=4
P2E-025PASSstep 4 done · "准备就绪" + 跳 /homescreenshots/P2E-02/su05-setup-done.json准备就绪 / 进入首页
P2E-026PASS每步 prev / next · step 1 无 prevscreenshots/P2E-02/su06-setup-prev-next.jsonstep1 prev=null step2 prev=上一步
P2E-027PASS断线 · 重进 · 从上次完成步继续(`useSetupStatusQuery` 提供)screenshots/P2E-02/su07-setup-resume.jsonlastCompleted=2 resumedStep=3
P2E-028PASS每步 URL `?step=1..4` · 刷新不丢screenshots/P2E-02/su08-setup-step-url.json1:1 / 2:2 / 3:3 / 4:4
P2E-029PASS退出需确认 · "设置未完成"screenshots/P2E-02/su09-setup-exit-confirm.json设置未完成 / setup-leave
P2E-0210PASS完成后 POST `setup/complete` 再跳转screenshots/P2E-02/su10-setup-complete-post.json/home / setup/complete
P2E-0211PASS失败降级 · "稍后设置" link · 跳 /onboardingscreenshots/P2E-02/su11-setup-later.json/onboarding -> /onboarding
P2E-031PASS3-4 屏滚动式 · 每屏满视口 · scroll snap · 大标题 + 插图 + 副文screenshots/P2E-03/ob01-onboarding-layout.jsonscreens=4 snap=y mandatory
P2E-032PASS屏 1 welcome · "欢迎使用 Friday" · 3 句价值主张screenshots/P2E-03/ob02-onboarding-welcome.json欢迎使用 Friday / values=3
P2E-033PASS屏 2 profile-pick · 4 cards(个人 / 小团队 / 企业 / 开发者)· 选中后记录 `useUserProfile`screenshots/P2E-03/ob03-onboarding-profile.jsoncards=4 profile=team
P2E-034PASS屏 3 pack-pick · 基于 profile 推荐 3 pack · 可多选 · 也可跳过screenshots/P2E-03/ob04-onboarding-packs.jsonrecommendations=3 selected=2
P2E-035PASS屏 4 done · "开始吧" + CTA 跳 /homescreenshots/P2E-03/ob05-onboarding-done.json开始吧 -> /home
P2E-036PASS右上跳过 · 写 profile 默认 · 跳 /homescreenshots/P2E-03/ob06-onboarding-skip.jsonsolo -> /home
P2E-037PASSscroll 指示 · 右侧 dots 3-4 个 · click 跳到对应屏screenshots/P2E-03/ob07-onboarding-dots.jsondots=4 active=2
P2E-038PASSkeyboard · ↓ / space 下屏 · ↑ 上屏 · Enter CTAscreenshots/P2E-03/ob08-onboarding-keyboard.jsonscreens=1->2->1 final=/home
P2E-041PASSURL 参数 wizardId · 从 guided registry 加载 · 不存在跳 /assistantscreenshots/P2E-04/gf01-guided-routing.jsoninventory-triage / invalid->/assistant
P2E-042PASS布局 · 顶 journey tracker 80px · 主区 2 列 · 左 step 自动 · 右 investigation panel 360screenshots/P2E-04/gf02-guided-layout.jsontracker=88.15625 panel=360
P2E-043PASSjourney tracker · 显示所有 step · 完成绿勾 · 当前琥珀 · 未来灰 · 分支 fork 图screenshots/P2E-04/gf03-guided-tracker.jsonicons=•,⑂,3,4 classes=guided-step-pill is-complete | guided-step-pill is-current | guided-step-pill | guided-step-pill
P2E-044PASSstep 内容 · 复用 goal-card / choice-card / one-click-action / plan-review-visual · 按 step.kind 渲染screenshots/P2E-04/gf04-guided-step-kinds.jsonintent -> choice -> action -> review
P2E-045PASSinvestigation panel · 显示 Friday 正在做的调查 · 有 spinner · 可展开详情screenshots/P2E-04/gf05-guided-investigation.jsonFriday 正在调查 / detail=true
P2E-046PASSstep-progress bar 顶部 · 当前 step / 总 step · 百分比screenshots/P2E-04/gf06-guided-progress.json第 3 / 4 步 / 50%
P2E-047PASSchoice-card · 选择后自动进下一 step · 轻过渡screenshots/P2E-04/gf07-guided-choice-auto-next.jsonlatency=199.4ms
P2E-048PASS回退 · 左下角 "上一步" button · 保留 state · 不 re-fetchscreenshots/P2E-04/gf08-guided-prev.jsonstep 2 -> 1, fetch=1
P2E-049PASS完成所有 step · 跳 final step · CTA 返回来源页screenshots/P2E-04/gf09-guided-final.json引导已完成 / /assistant?packId=industry-cross-border-ecommerce
P2E-0410PASSstate 持久化 `guided-flow-{wizardId}` localStorage · 断线恢复screenshots/P2E-04/gf10-guided-storage.jsonstorageStep=2 restored=2
P2E-0411PASS空 wizardId 路径 · show "找不到引导" + 跳 /assistant linkscreenshots/P2E-04/gf11-guided-empty.json找不到引导 / /assistant
P2E-0412PASSskip current step · 允许 · 标记 step skipped(灰勾)· tracker 显示screenshots/P2E-04/gf12-guided-skip.json✓ / --ink-3
P2E-0413PASS每 step 右下 "寻求帮助" · 打开 contextual-helpscreenshots/P2E-04/gf13-guided-help.json上下文帮助已打开 · Friday 会把当前 step、调查摘要和回退边界一起带给你。
P2E-051PASS3 栏 · 左 agent list 280 · 中 activity timeline flex · 右 control 320screenshots/P2E-05/cc01-command-layout.json280 / 488 / 320
P2E-052PASSagent list · 每 agent 一 card · name + status + current runscreenshots/P2E-05/cc02-command-agents.jsonagent-ops, agent-qa, agent-builder
P2E-053PASStimeline · `ActivityTimeline` 复用 · 显示所有 agent 的事件合流screenshots/P2E-05/cc03-command-activitytimeline.jsoncallSite=true props=expandedEventId,lanes,locale,runs
P2E-054PASS多 run 并列 · 用 lane 区分 · 每 agent 一 lanescreenshots/P2E-05/cc04-command-lanes.jsonagent-ops:1 / agent-qa:1 / agent-builder:1
P2E-055PASScontrol · 选中 agent 后显示 · pause / resume / stop / inspectscreenshots/P2E-05/cc05-command-control.jsonQA Agent / inspect
P2E-056PASSsummary panel 顶部 · 总运行数 + 失败率 + 平均时长screenshots/P2E-05/cc06-command-summary.json3 / 0% / 17 分 0 秒
P2E-057PASS点 timeline event · 展开 contextscreenshots/P2E-05/cc07-command-event-expand.jsonrun-replenish-watch / lines=3
P2E-058PASS空 · "暂无 agent 活动"screenshots/P2E-05/cc08-command-empty.json暂无 agent 活动
P2E-059PASSmobile/窄屏 · 单列 · 只显 timelinescreenshots/P2E-05/cc09-command-mobile.json988px / asides=none,none
P2F-011PASSroute 切换 < 150ms · 用 `recordNavVisit` + `completeClientRouteTransition` 埋点screenshots/P2F-01/f01-01-nav-metric.jsonduration=1.6ms route=/assistant
P2F-012PASS切换不 FOUC · 下页 mount 前旧页保留 100msscreenshots/P2F-01/f01-02-no-fouc.jsonhold route=/home, overlay=shell-transition-hold-fade, after=/assistant
P2F-013PASSrail 当前路由高亮 · 点击前琥珀 · 点击后立即 activescreenshots/P2F-01/f01-03-rail-highlight.jsonbefore=/home during=/assistant
P2F-014PASSscroll 位置保留 · 回退 / 前进 恢复 · 新进 topscreenshots/P2F-01/f01-04-scroll-restore.jsonhome=1000 restored=1000 assistant=0
P2F-015PASSright rail slot 切换 · fade 150ms · 不闪 · 不 layout shiftscreenshots/P2F-01/f01-05-right-rail.jsonoverlay=shell-transition-right-rail-fade stable=true
P2F-016PASStopbar breadcrumb 同步 · URL 变时 300ms 内更新screenshots/P2F-01/f01-06-breadcrumbs.jsonlatency=0.0ms
P2F-017PASSloading 超过 500ms 才显 splash · 小于不显screenshots/P2F-01/f01-07-splash.jsonshort=false long=true
P2F-018PASS切换失败 · inline error 保留上页 · 不替换screenshots/P2F-01/f01-08-nav-fail.jsonroute=/home retry=retry-last-navigation
P2F-021PASSTweaks 面板右下浮层 240×auto · 开关在 topbarscreenshots/P2F-02/f02-01-panel.jsonwidth=240px right=24px bottom=24px
P2F-022PASS分组 5 个 · Density / Radius / Motion / Accent / Locale Previewscreenshots/P2F-02/f02-02-groups.json密度 / 圆角 / 动效 / 主色强度 / 语言预览
P2F-023PASSDensity · compact / cozy / comfortable · 影响 padding + line-heightscreenshots/P2F-02/f02-03-density.jsonpadding=14px/17px/18px
P2F-024PASSRadius · sharp(4) / default(14) / soft(22) · 全局 radius 变量替换screenshots/P2F-02/f02-04-radius.json4px / 14px / 22px
P2F-025PASSMotion · full / reduced / none · 匹配 prefers-reduced-motion 默认screenshots/P2F-02/f02-05-motion.jsondefault=reduced none=0.01ms linear
P2F-026PASSAccent · intensity 50-150% · 改 --accent 饱和度screenshots/P2F-02/f02-06-accent.jsonrgb(185, 144, 103) | rgb(196, 135, 83) | rgb(154, 93, 37) | rgb(205, 111, 38) | rgb(210, 95, 20)
P2F-027PASSLocale Preview · zh / en · 不改 `friday-locale` · 只临时 previewscreenshots/P2F-02/f02-07-locale-preview.jsonlocale=zh render=en storage=zh
P2F-028PASS切换立刻生效 · CSS variables 改 · 无 flashscreenshots/P2F-02/f02-08-live-apply.json14px -> 4px
P2F-029PASSlocalStorage 持久化 · 键 `friday-tweaks` · reload 保留screenshots/P2F-02/f02-09-persist.json{"density":"compact","radius":"soft","motion":"full","accentIntensity":"150","localePreview":"zh"}
P2F-031PASS每页 empty 文案双语 · zh + en 对齐screenshots/P2F-03/f03-01-bilingual.json6 audited routes
P2F-032PASS语气统一 · 友好 · 有引导 · 不用 "no data"(太冷)或 "好像什么都没有"(太幼稚)screenshots/P2F-03/f03-02-tone.jsonno banned cold/childish phrasing found
P2F-033PASS每 empty 有下一步 CTA · 明确动作 · 带 arrow iconscreenshots/P2F-03/f03-03-cta.jsonHome:1, Chat:3, Channels:1, Usage:1, Memory:1, Fleet:1
P2F-034PASS无 lorem / TBD · grep 检测 0 命中screenshots/P2F-03/f03-04-grep.jsonmatches=0
P2F-035PASS插图 · 米色 line-art SVG · 最多一个 · 不过度screenshots/P2F-03/f03-05-line-art.jsonHome:1, Chat:1, Channels:1, Usage:1, Memory:1, Fleet:1
P2F-036PASScopy 审核清单单独 HTML · 每条 page 一行 · zh 列 + en 列 + 审校人screenshots/P2F-03/f03-06-copy-audit.json6 rows in screenshots/qa/p2f-03-copy-audit.html
P2F-041PASS每页 error 有 retry 按钮 · 主色screenshots/P2F-04/f04-01-retry-primary.json重试 / action-button action-button-primary
P2F-042PASS"为什么?" 可展开 · 默认折叠 · 展开技术描述(人话)screenshots/P2F-04/f04-02-why.json刷新助手收件箱时遇到暂时性错误。
P2F-043PASS不暴露堆栈 / SQL / internal pathsscreenshots/P2F-04/f04-03-sanitized.jsonno stack/sql/internal path leak
P2F-044PASS每 error 有 errorId · 可 copy · 7 字母数字screenshots/P2F-04/f04-04-error-id.jsonOUP0E69
P2F-045PASS双语screenshots/P2F-04/f04-05-bilingual.jsonAssistant 快照暂时不可用 -> Assistant snapshot is unavailable
P2F-046PASS网络断 · 特定文案 "你似乎离线了 · 正在自动重试"screenshots/P2F-04/f04-06-offline.json你似乎离线了 · 正在自动重试
P2F-047PASSrate-limited · "操作太频繁 · 请 N 秒后再试" + 倒计时screenshots/P2F-04/f04-07-rate-limit.json操作太频繁 · 请 5 秒后再试 -> 操作太频繁 · 请 4 秒后再试
P2F-051PASSTab 顺序符合视觉顺序 · 无跳跃screenshots/P2F-05/f05-01-tab-order.json导航已按响应式自动收起 -> 首页 -> 对话 -> 助手收件箱 -> 可观测性 -> 入口库 -> 技能 -> 工作流 -> 渠道 -> 自动化 -> 会话记录 -> 用量 -> 记忆 -> 设备 -> 插件 -> MCP
P2F-052PASSfocus ring 2px 琥珀 + 2px offset · 所有可交互元素screenshots/P2F-05/f05-02-focus-ring.json2px rgb(154, 93, 37) offset=2px
P2F-053PASS所有 icon-only 按钮有 aria-labelscreenshots/P2F-05/f05-03-icon-labels.jsonscanned=48 missing=0
P2F-054PASSmodal / drawer Escape 关 · 开时 focus trap · 关时 focus 回触发源screenshots/P2F-05/f05-04-modal-drawer.jsonmodal=toggle-command-palette drawer=open-approval-drawer
P2F-055PASS列表方向键 · ↑↓ 移动 · Home/End 首末screenshots/P2F-05/f05-05-list-keys.json首页 -> 对话 -> 打开 Workflow 测试面板
P2F-056PASSform label 关联 · input 有 id + label forscreenshots/P2F-05/f05-06-form-labels.jsonprovider=4 alert=2
P2F-057PASS错误与 input 用 aria-describedby 连screenshots/P2F-05/f05-07-describedby.jsonobservability-alert-name-error, observability-alert-threshold-error
P2F-058PASS运行 axe-core · 0 critical · 记录 reportscreenshots/P2F-05/f05-08-axe-report.jsonroutes=33 critical=0
P2F-059PASS色对比 WCAG AA · body text ≥ 4.5 · large ≥ 3screenshots/P2F-05/f05-09-contrast.jsonhome-body:14.71, home-heading:14.33, assistant-heading:15.64, settings-hint:14.71, usage-table:14.71
P2F-0510PASSCmd+K 可导航到所有路由 · 14+ 条目screenshots/P2F-05/f05-10-command-palette.jsoncount=27
P2F-061PASS1280 下三栏(rail 240 · main 996 · rail collapsible)· 无横向滚动screenshots/P2F-06/f06-01-1280-home.jsonrail=64 main=996 right=220
P2F-062PASS1440 下三栏舒展 · rail 可选 collapsescreenshots/P2F-06/f06-02-1440-home.jsonrail=240 main=896 right=304
P2F-063PASS1920 下多列布局激活(如 pack 4 列)screenshots/P2F-06/f06-03-1920-packs.jsoncolumns=5
P2F-064PASS每档截图 5 个关键页 · 对比放入 qa-reportscreenshots/P2F-06/f06-04-screenshot-matrix.json15 responsive screenshots
P2F-065PASS字体大小不缩 · 仍 14/15 基线screenshots/P2F-06/f06-05-font-baseline.json1280:15px/14px, 1440:15px/14px, 1920:15px/14px
P2F-066PASSrail 64 窄态下 icon 居中 + tooltip hover 显示文字screenshots/P2F-06/f06-06-compact-rail-tooltip.jsonrail=64 tooltip="首页"
P2F-081PASSCtrl+P · Home / Assistant / Observability 三页支持 · 其他页显示 "该页不支持打印"screenshots/P2F-08/f08-01-supported-routes.jsonsupported=3 unsupported=该页不支持打印
P2F-082PASSprint CSS · rail + topbar + tweaks 隐藏 · 主内容满宽screenshots/P2F-08/f08-02-print-layout.jsonmain=1440/1440
P2F-083PASS分页正确 · 卡片不被裁断 · 加 `page-break-inside: avoid`screenshots/P2F-08/f08-03-page-breaks.json.obs-row:avoid
P2F-084PASS颜色 · 保留琥珀 accent · 其他灰度screenshots/P2F-08/f08-04-print-colors.jsonaccent=rgb(154, 93, 37) status=rgba(82, 82, 82, 0.86)
P2F-085PASSprint 顶部加 "Friday · {pageName} · {date}" 眉头screenshots/P2F-08/f08-05-print-header.jsonFriday首页2026/04/21
P2F-091PASSgrep 无裸中文 / 英文 · 用脚本 check: `grep -rE '(>[\u4e00-\u9fa5])|(>[A-Z][a-z]{4,})' src/`screenshots/P2F-09/f09-01-bare-string-grep.jsonmatches=0
P2F-092PASS每 user-facing 字符串走 `localize()`screenshots/P2F-09/f09-02-localize-audit.jsonlocalize=1127 localizedText=315
P2F-093PASS切换 locale 无 flash / FOUCscreenshots/P2F-09/f09-03-locale-switch.jsonlatency=1.6ms
P2F-094PASS日期 / 数字 / 货币 按 locale 格式screenshots/P2F-09/f09-04-locale-formatting.jsonUS$10,980 -> $10,980; 2026/04/21 -> 04/21/2026
P2F-095PASS中文长英文短(或反之)不裂 layout · test case 5 页面对比screenshots/P2F-09/f09-05-layout-compare.jsonhome:1440/1440, assistant:1440/1440, observability:1440/1440, settings:1440/1440, usage:1440/1440
P2F-101PASS聚合 G01-G12 通过 · 12 条screenshots/P2F-10/f10-01-guardrails.jsonG01:PASS, G02:PASS, G03:PASS, G04:PASS, G05:PASS, G06:PASS, G07:PASS, G08:PASS, G09:PASS, G10:PASS, G11:PASS, G12:PASS
P2F-102PASS聚合 Phase 2A 12 验收(H01-H06 + C01-C06)screenshots/P2F-10/f10-02-phase-2a.json12/12 targeted Phase 2A checks
P2F-103PASS聚合 Phase 2B 18(B01-B06 + S01-S05 + O01-O07)screenshots/P2F-10/f10-03-phase-2b.json18/18 targeted Phase 2B checks
P2F-104PASS聚合 Phase 2C 27screenshots/P2F-10/f10-04-phase-2c.jsonitems=8 rules=92 fail=0
P2F-105PASS聚合 Phase 2D 若干screenshots/P2F-10/f10-05-phase-2d.jsonitems=6 rules=60 fail=0
P2F-106PASS聚合 Phase 2E 若干screenshots/P2F-10/f10-06-phase-2e.jsonitems=5 rules=48 fail=0
P2F-107PASS聚合 Phase 2F-01..09screenshots/P2F-10/f10-07-phase-2f.jsonitems=8 fail=0
P2F-108PASSqa-report.html 每条一 row · PASS/FAIL + 证据(截图 / cmd 输出)screenshots/P2F-10/f10-08-qa-report.jsonrows=433/433 missingEvidence=0
P2F-109PASSfailing 条不得超过 2 · 超过 retryscreenshots/P2F-10/f10-09-fail-threshold.jsonfail=0 pending=0
P2F-1010PASS最终 qa-report 连同 friday-static.html 一起交付screenshots/P2F-10/f10-10-deliverables.jsonstatic=1123308 qa=151635