Skip to content
This repository was archived by the owner on Jul 30, 2026. It is now read-only.

refactor(tui): 重构 Overview、Sessions 与 Daily 视图 - #154

Merged
makoMakoGo merged 19 commits into
personal/local-clientsfrom
codex/issue-153-tui-information-architecture
Jul 17, 2026
Merged

refactor(tui): 重构 Overview、Sessions 与 Daily 视图#154
makoMakoGo merged 19 commits into
personal/local-clientsfrom
codex/issue-153-tui-information-architecture

Conversation

@makoMakoGo

@makoMakoGo makoMakoGo commented Jul 16, 2026

Copy link
Copy Markdown
Owner

背景与目标

Partially addresses #153;剩余事项继续在该 Issue 中跟踪。

原 TUI 的页面职责存在重叠:Overview 同时堆叠多个统计面板,Issues 展示的是 scanner 问题与扁平的 model-session links,Daily 的 Profile 常驻在 Table 上方,页面级交互与通用 Footer 之间也会互相覆盖。

本 PR 重新划分信息架构:

页面 最终职责
Overview 全局趋势图与一屏可读的 Snapshot
Stats Contribution Graph 与 Day Insights
Sessions 按 Source 浏览真实 session 实体及其详情
Daily 在 Daily Table 与按星期聚合的 Daily Profile 间切换
Hourly 在 Hourly Table 与时段分布 Profile 间切换

旧 Issues 页面及其 model-session links 表被删除;CLI 的对应标签名由 issues 正式替换为 sessions

Overview

Overview Graph 始终按清洗后的模型身份聚合,不受当前 Workspace、Harness 或 Provider Group By 影响。图例只渲染能够完整放入可用宽度的项目,移除额外分隔符,并与 Snapshot 内容左边距对齐。

Graph 下方统一为一个响应式、纯文字的 Snapshot

┌─ Snapshot ───────────────────────────────────────────────────────────────────┐
│ Total Tokens          1.42M          Tokens                                  │
│ Peak Daily Tokens      286K          Cache Read      360K    25.0%           │
│                                       Cache Write      30K     2.0%           │
│ Total Cost           $12.48          Input           720K    51.0%           │
│ Peak Daily Cost       $2.31          Output          310K    22.0%           │
│                                                                               │
│ Source Data         812 MiB          Sources                                 │
│ Source Health        96.72%          Clean 118      Degraded 3               │
│                                       Partial 1      Failed 0                 │
│ Models Used               4          Rejected 9                              │
│ Favorite Model  gpt-5.6-sol                                                  │
│                                                                               │
│ Harnesses Used            3                                                  │
│ Favorite Harness      Codex                                                  │
└───────────────────────────────────────────────────────────────────────────────┘
  • 删除 Token 柱状条、内部竖分隔线和重复的 Active Days,Snapshot 保持一眼可读。
  • Total / Peak、Source Data / Health、Models、Harnesses 按语义分组;宽屏使用双列,窄屏按优先级纵向降级。
  • Peak Daily TokensPeak Daily Cost 来自报告范围内的单日最大值。
  • Token 顺序固定为 Cache Read、Cache Write、Input、Output,并使用同一 Token 总量计算百分比。
  • Source Health 保留 scanner 原子 source-unit 语义,计算为 Clean / (Clean + Degraded + Partial + Failed);Rejected 单独展示记录数。
  • Favorite Model 与 Favorite Harness 以 Tokens 为主、Cost 为次确定,并在受限宽度下安全截断。

Sessions

Sessions 使用 Source-first 两层导航,替代无法表达真实会话身份的旧 Issues / model-session links 页面:

┌─ Sessions ───────────────────────────────────────────────────────────────────┐
│ Source                 Sessions   Workspaces       Active          Space     │
│▶ Codex                        28            6     07-17 14:37      82.4 MiB   │
│  OpenCode                     17            4     07-17 12:10     146.8 MiB   │
└───────────────────────────────────────────────────────────────────────────────┘

┌─ Sessions / Codex ───────────────────────────────────────────────────────────┐
│ Session   Workspace   Models                  Msg  Turns Tokens Cost   Active │
│▶ s-001    project-a   gpt-5.6-sol, mini        12      6    150 $1.21  10:48 │
└───────────────────────────────────────────────────────────────────────────────┘

数据语义

  • Session 唯一身份为 (source, session_id):同一 Source 中使用多个模型的同一 session 只生成一个实体;不同 Source 的同名 session 不会合并。
  • Projection 直接来自 parser 清洗后的 UnifiedMessage,不再从 UsageModelEntry.session_count 反推。
  • 每个 session 汇总 Workspace、模型集合、Messages、Turns、Tokens、Cost、首次与最后活跃时间。
  • Source 层的 Sessions 与 Workspaces 分别按 session identity 和 workspace identity 去重,Active 取最新 last_seen
  • Space 来自 scanner 实际发现的输入文件;路径去重后统计真实文件大小,并包含 SQLite 的 WAL、SHM 与 journal sidecar。
  • 已扫描但没有可用 session 的 Source 仍保留在 Source 列表中,用于说明当前扫描范围。

刷新与失败行为

  • Sessions projection 使用 source inventory digest 判断是否需要重建;输入未变化时复用共享的 Arc<SessionSnapshot> 与按 Source 建立的索引。
  • 手动刷新仍可强制重建,避免缓存判定掩盖用户明确请求。
  • 首次构建失败显示 Unavailable;已有成功快照后的刷新失败显示非阻塞 Degraded,保留最后一次有效数据,并在 Sessions 面板底部显示单行诊断。
  • 定价网络或缓存问题不会错误标记 Sessions 为 degraded;成本可用性作为全局状态显示在 Footer。

导航与布局

  • Enter 进入 Source 详情;Esc / Backspace 返回,并保留 Source 层选择与滚动位置。
  • Source 层使用 Active / Sessions / Space 排序;详情层使用 Active / Tokens / Cost 排序。
  • 键盘、鼠标滚轮与窄屏列裁剪均基于当前层级处理,不会移动隐藏视图的选择状态。
  • Header、表头、Footer 摘要、点击区域和快捷键提示均使用 Sessions 语义;tokscale tui --tab sessions 是唯一 CLI 名称,旧 issues 不再作为别名接受。

Daily 与 Hourly Profile

Daily 与 Hourly 都采用互斥的 Table / Profile 结构,通过 v 切换:

Daily Table   ←─ v ─→  Daily Profile
Hourly Table  ←─ v ─→  Hourly Profile

Daily Profile 与 Hourly Profile 共享 usage_profile 渲染模块,统一生成日期范围、权威总量、响应式柱宽、Peak 行和切换提示。

┌─ Daily Profile ───────────────────────────────────────────────────────────────┐
│ When You Work Most  2025-11-10 to 2026-07-18                                │
│ 174 active days  ·  36.4B tokens  ·  $20.5K                                 │
│                                                                               │
│   Monday              3.6B  ██████████░░░░░░░░░░  10.0%                     │
│   ...                                                                         │
│   Friday              7.2B  ████████████████████  19.7%                     │
│                                                                               │
│ Peak day Friday  ·  7.2B tokens  ·  $4.1K                                   │
│                                                                               │
│ Press [v] to switch to table view                                             │
└───────────────────────────────────────────────────────────────────────────────┘
  • Daily 按星期累计 Tokens 与 Cost,展示 Peak Day;Hourly 保留时段分布与 Peak Hour。
  • Profile 的全局 Tokens 与 Cost 始终读取 UsageData.total_tokens / total_cost,不在页面内重新实现汇总逻辑。
  • 短终端中 Profile 支持键盘和鼠标滚轮滚动,并显示 scrollbar;滚动不会暗中修改隐藏 Table 的选择。
  • Daily Profile 中的 Enter 与 j 被当前视图消费,不会触发隐藏 Daily Table 的详情或 today 定位。
  • 对话框打开时输入优先交给对话框,避免方向键同时操作底层 Sessions 或 Profile。

状态化交互与 Footer

  • 新增独立 ViewState 管理 Daily Profile viewport、Sessions 两层选择与滚动状态。
  • Footer 改为一次性、状态感知渲染:根据当前 Tab 与子视图直接选择最终内容,不再先注册通用排序控件再覆盖。
  • Daily Profile 不显示或注册无效的 Table 排序按钮;Sessions 两层 Footer 只注册当前实际显示的排序字段和点击宽度。
  • 鼠标滚轮先交给状态化视图;未消费时再进入通用列表滚动逻辑。
  • Stats Contribution Graph 只为真实日期单元格注册点击区域,None 占位格继续渲染但不会打开无日期的 Day Insights。
  • Footer 与 Overview 覆盖区域显式清理背景,避免切换视图后残留旧文字或点击区域。

定价诊断与成本可用性

  • parser 新增带 pricing diagnostics 的本地 UnifiedMessage API,使 Sessions projection 与主报告使用同一套定价状态来源。
  • 自定义定价解析告警改为收集诊断,不再直接向终端输出原始字符,避免破坏 TUI 渲染。
  • Footer 全局状态行区分:定价可用但有警告、刷新失败并使用缓存、定价完全不可用。
  • 当三个远端定价缓存都不存在但 custom pricing 非空时,仍构造可用的 PricingService;只有 custom 为空且全部远端缓存缺失时才返回 None
  • 缓存持久化警告保持高于瞬时状态消息的显示优先级。

其他调整

  • Group By Picker 仅保留 Model、Harness + Model、Harness + Provider + Model、Workspace + Model。
  • Stats 继续专注 Contribution Graph 与 Day Insights;Source Health 只在 Overview 展示。
  • Core CI checkout 改为完整历史,因为 release pull-request 校验需要读取可能早于临时 merge ref 直接父节点的 PR base commit,避免浅克隆把“未获取到”误判为非法提交。
  • Daily Profile 测试使用独立临时 home,避免读取或写入开发者真实配置目录。

明确暂缓

验证

  • cargo fmt --all -- --check
  • cargo clippy --locked --workspace --all-features -- -D warnings
  • cargo test --locked --workspace --all-features(使用隔离的 XDG_CONFIG_HOME
  • bun run build:core

@coderabbitai

coderabbitai Bot commented Jul 16, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

本次变更以 Sessions 替代旧 Issues 视图,新增会话投影、来源与详情表格、独立视图状态,并重构 Overview、Stats、Daily Profile、Hourly Profile、导航、页脚及定价诊断展示。

Changes

TUI 信息架构重构

Layer / File(s) Summary
Sessions 数据投影与后台刷新
crates/tokscale-core/..., crates/tokscale-cli/src/tui/session_data.rs, crates/tokscale-cli/src/tui/mod.rs
新增会话快照、消息聚合、来源空间统计和定价诊断,并在后台加载流程中刷新 Sessions 投影。
Sessions 交互、表格与视图接线
crates/tokscale-cli/src/tui/view_state.rs, crates/tokscale-cli/src/tui/ui/{sessions,view_footer,mod}.rs
新增 Daily/Sessions 状态管理、来源与详情表格、滚动选择逻辑及状态驱动渲染。
Overview 快照与贡献图
crates/tokscale-cli/src/tui/ui/{overview,overview_snapshot,stats}.rs
Overview 改用聚合图表与快照面板,Stats 增加贡献图指标和日期洞察。
Daily、Hourly Profile 与选择器
crates/tokscale-cli/src/tui/ui/{daily_profile,hourly_profile,usage_profile}.rs, crates/tokscale-cli/src/tui/ui/dialog/group_by_picker.rs
新增 Daily Profile,共享 Profile 渲染辅助逻辑,重构 Hourly Profile,并移除会话分组项。
旧视口、Issues 页面与标签清理
crates/tokscale-cli/src/tui/{app,cli}.rs, crates/tokscale-cli/src/tui/ui/{issues,header,footer,themes,data/mod}.rs
移除旧 Issues 页面和文本视口,更新 Sessions 标签、统计、帮助文案、主题样式及导出。

Estimated code review effort: 5 (Critical) | ~120 minutes

Possibly related issues

Possibly related PRs

Poem

小兔抱着 Sessions 胡萝卜,
把旧 Issues 轻轻藏好;
快照跳进表格里,
图表在月光下闪耀。
Daily、Hourly 一起蹦,
新视图顺着按键跑。

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 26.74% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题准确概括了此次 TUI 重构的核心:Overview、Sessions 和 Daily 视图的调整。
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/issue-153-tui-information-architecture

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@codspeed-hq

codspeed-hq Bot commented Jul 16, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 27 untouched benchmarks


Comparing codex/issue-153-tui-information-architecture (6ad00ae) with personal/local-clients (48cf8bb)1

Open in CodSpeed

Footnotes

  1. No successful run was found on personal/local-clients (b7b1b0a) during the generation of this report, so 48cf8bb was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@makoMakoGo
makoMakoGo force-pushed the codex/issue-153-tui-information-architecture branch from 17e0c89 to 31e0869 Compare July 16, 2026 21:25
makoMakoGo added a commit that referenced this pull request Jul 17, 2026
Takes PR #154's two-section Stats skeleton (contribution graph with
in-graph metrics, Day Insights driven by selected_graph_cell with its
scrollable harness/model breakdown) as-is, and ports this branch's
additions into it: weekday/month crosshair labels, top model/agent
lines, the 24-hour activity strip, and the top-3 model radar chart.
app.rs is restored to the cell-selection state #154 builds on; the
usage 5 Hour label fixes are unchanged.
@makoMakoGo
makoMakoGo force-pushed the codex/issue-153-tui-information-architecture branch from 2e9547b to 260877f Compare July 17, 2026 14:51
@makoMakoGo makoMakoGo changed the title refactor(tui): 重整 Overview、Stats 与 Sessions 信息架构 refactor(tui): 重构 Overview、Sessions 与 Daily 视图 Jul 17, 2026
@makoMakoGo
makoMakoGo force-pushed the codex/issue-153-tui-information-architecture branch from 260877f to 37f9a59 Compare July 17, 2026 15:00
@makoMakoGo
makoMakoGo marked this pull request as ready for review July 17, 2026 17:06
@makoMakoGo

Copy link
Copy Markdown
Owner Author

@codex review

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 8

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@crates/tokscale-cli/src/tui/mod.rs`:
- Around line 94-97: 更新 refresh_session_data 及其 BackgroundLoad 调用链,不要仅记录并吞掉
session_data::refresh 的错误;保留错误或警告并向 TUI 展示,使刷新失败不会返回 Loaded 或
Unchanged。补充回归测试,验证刷新失败时界面显示错误且不会将失败标记为成功。
- Around line 111-117: 更新后台加载流程中的 refresh_session_data 与摘要状态管理:记录 Sessions
投影是否已初始化及其对应摘要。首次从缓存恢复时仍执行刷新,之后仅在投影缺失或摘要发生变化时刷新;摘要匹配且投影已初始化时不要调用
refresh_session_data,保留快速路径。

In `@crates/tokscale-cli/src/tui/session_data.rs`:
- Around line 113-123: Update snapshot_store and snapshot so repeated reads do
not deep-clone the full SessionSnapshot. Store the snapshot behind Arc within
the lock and have snapshot clone only the Arc, or expose an equivalent read-only
callback API; update callers such as source_rows, session_rows, and footer
rendering to use the optimized access path while preserving snapshot contents
and thread-safety.

In `@crates/tokscale-cli/src/tui/ui/overview_snapshot.rs`:
- Around line 69-79: 调整 Snapshot 的布局分配,确保其内部高度至少保留 10 行,避免在 30 行终端中因高度不足而裁掉
Harness、Partial/Failed 和 Rejected 等必需指标;更新当前构造 lines 的流程,移除或改为不会静默隐藏这些指标的 take
限制。增加覆盖 render_with_state 的回归测试,验证紧凑终端高度下所有 Snapshot 指标仍会渲染。

In `@crates/tokscale-cli/src/tui/ui/overview.rs`:
- Around line 188-203: 更新 overview 图例渲染中基于 limit 的固定条目截断逻辑,使用可用区域的 area.width
累计每个模型条目及分隔符的实际显示宽度,仅在放入后仍不超出区域时渲染;保留 app.is_narrow() 对名称宽度的影响,并确保不再因固定渲染 5
个条目导致行内容被裁剪。

In `@crates/tokscale-cli/src/tui/ui/stats.rs`:
- Around line 356-381: Update the model list rendering around the models
collection and loop to use source.models.iter() so each model_key remains
available. Select the display identifier in display_name → color_key → model_key
order when display_name is empty, and use that same identifier for both
truncate_model_display_name and app.model_color_for while preserving the
existing sorting and metrics.
- Around line 119-145: 仅在统计网格单元格匹配到 Some(day) 时注册 GraphCell 点击区域;对于 None
占位格继续渲染现有样式,但不要将其加入 click_areas,避免触发无日期可用的 Day Insights 交互。

In `@crates/tokscale-cli/src/tui/ui/view_footer.rs`:
- Around line 8-25: 将页脚改为单次、状态感知渲染:在 view_footer::render 中不要先调用通用 footer::render
再覆盖,而应根据 ViewState 和当前标签页直接选择最终行渲染器;更新 view_footer.rs
中的状态化渲染器,使其仅按实际显示的字段、顺序和宽度注册点击区域。同步调整 footer.rs
的通用渲染流程,避免为状态化页脚预注册通用排序控件,并让排序可见性接收视图状态或由状态化页脚决定,确保 Daily Profile
不显示无效排序控件。受影响位置:crates/tokscale-cli/src/tui/ui/view_footer.rs:8-25、40-114,以及
crates/tokscale-cli/src/tui/ui/footer.rs:59-69、135-145。
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2d43eec9-dc45-4782-9aee-b422cd348095

📥 Commits

Reviewing files that changed from the base of the PR and between 7647c2f and 0e7f1bc.

📒 Files selected for processing (19)
  • crates/tokscale-cli/src/tui/app.rs
  • crates/tokscale-cli/src/tui/data/mod.rs
  • crates/tokscale-cli/src/tui/mod.rs
  • crates/tokscale-cli/src/tui/session_data.rs
  • crates/tokscale-cli/src/tui/themes.rs
  • crates/tokscale-cli/src/tui/ui/daily_profile.rs
  • crates/tokscale-cli/src/tui/ui/dialog/group_by_picker.rs
  • crates/tokscale-cli/src/tui/ui/footer.rs
  • crates/tokscale-cli/src/tui/ui/header.rs
  • crates/tokscale-cli/src/tui/ui/hourly_profile.rs
  • crates/tokscale-cli/src/tui/ui/issues.rs
  • crates/tokscale-cli/src/tui/ui/mod.rs
  • crates/tokscale-cli/src/tui/ui/overview.rs
  • crates/tokscale-cli/src/tui/ui/overview_snapshot.rs
  • crates/tokscale-cli/src/tui/ui/sessions.rs
  • crates/tokscale-cli/src/tui/ui/stats.rs
  • crates/tokscale-cli/src/tui/ui/usage_profile.rs
  • crates/tokscale-cli/src/tui/ui/view_footer.rs
  • crates/tokscale-cli/src/tui/view_state.rs
💤 Files with no reviewable changes (3)
  • crates/tokscale-cli/src/tui/ui/issues.rs
  • crates/tokscale-cli/src/tui/themes.rs
  • crates/tokscale-cli/src/tui/app.rs

Comment thread crates/tokscale-cli/src/tui/mod.rs Outdated
Comment thread crates/tokscale-cli/src/tui/mod.rs Outdated
Comment thread crates/tokscale-cli/src/tui/session_data.rs Outdated
Comment thread crates/tokscale-cli/src/tui/ui/overview_snapshot.rs
Comment thread crates/tokscale-cli/src/tui/ui/overview.rs
Comment thread crates/tokscale-cli/src/tui/ui/stats.rs Outdated
Comment thread crates/tokscale-cli/src/tui/ui/stats.rs
Comment thread crates/tokscale-cli/src/tui/ui/view_footer.rs Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0e7f1bc6b8

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread crates/tokscale-cli/src/tui/mod.rs Outdated
Comment thread crates/tokscale-cli/src/tui/ui/overview.rs
Comment thread crates/tokscale-cli/src/tui/session_data.rs
Comment thread crates/tokscale-cli/src/tui/ui/view_footer.rs Outdated
Comment thread crates/tokscale-cli/src/tui/mod.rs Outdated
Comment thread crates/tokscale-cli/src/tui/view_state.rs Outdated
Comment thread crates/tokscale-cli/src/tui/mod.rs
Comment thread crates/tokscale-cli/src/tui/ui/header.rs Outdated
Comment thread crates/tokscale-cli/src/tui/session_data.rs Outdated
Comment thread crates/tokscale-cli/src/tui/view_state.rs Outdated
Preserve the last successful Sessions projection when refresh fails and render its degraded state inside the Sessions panel. Align the source header with the panel title.
Track the source digest owned by the Sessions projection and skip rebuilding a ready matching snapshot. Pending, changed, forced, and degraded projections continue to refresh, with failures remaining retryable.
Publish immutable Sessions snapshots through Arc, precompute source summaries and source indexes during refresh, and use constant-time counts for navigation and footer rendering.
Keep placeholder contribution cells visually unchanged while excluding them from Day Insights click targets.
Select the final footer content before rendering, derive sort hitboxes from the displayed labels, and omit table-only controls from Daily Profile.
Route pricing warnings through structured diagnostics so background refreshes do not write into the alternate screen. Keep pricing availability global and independent of Sessions projection health.
Share Sessions navigation between keyboard and mouse input. Consume wheel events in Daily Profile so they cannot mutate the hidden table selection.
Rename the public TuiTab value and internal Tab variant to Sessions, remove the obsolete header translation, and reject the former issues spelling instead of retaining a compatibility alias.
Store the Daily Profile text viewport in ViewState, route keyboard and wheel movement through it, and render a scrollbar when the profile exceeds the available body height without changing the hidden table selection.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
crates/tokscale-cli/src/tui/ui/footer.rs (1)

136-181: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

排序控件为空时让摘要使用整行宽度。

Overview、Stats、Usage 和 Daily Profile 会传入空控件,但这里仍预留 40% 空白,导致摘要在中窄终端被不必要地截断。

建议修改
+    let sort_column_percent = if sort_controls.is_empty() {
+        0
+    } else {
+        sort_column_percent
+    };
     let chunks = Layout::default()
         .direction(Direction::Horizontal)
         .constraints([
             Constraint::Percentage(sort_column_percent),
             Constraint::Percentage(100u16.saturating_sub(sort_column_percent)),
         ])
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-cli/src/tui/ui/footer.rs` around lines 136 - 181, Update the
footer layout around chunks and sort_controls so that when sort_controls is
empty, the summary uses the entire area width instead of reserving the
sort-column percentage. Preserve the existing two-column layout and sort-button
rendering when controls are present, and keep rendering the summary through the
existing chunks[1] path or an equivalent full-width region.
crates/tokscale-core/src/pricing/mod.rs (1)

155-166: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

将自定义定价计入缓存服务的可用性判断。

当前三个远程缓存均缺失时会直接返回 None,即使 custom 包含有效价格。这样 cache-only 或 stale 路径会丢弃用户自定义定价,并把相关成本算成零。请仅在 custom 也为空时返回 None

建议修改
-        if litellm_data.is_none() && openrouter_data.is_none() && models_dev_data.is_none() {
+        if custom.is_empty()
+            && litellm_data.is_none()
+            && openrouter_data.is_none()
+            && models_dev_data.is_none()
+        {
             return None;
         }

同时增加仅提供 CustomPricing、三个远程缓存均为 None 的回归测试。

As per coding guidelines, “Add focused Rust unit tests near the implementation for pure logic.”

Also applies to: 173-191

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-core/src/pricing/mod.rs` around lines 155 - 166, Update
from_cached_datasets so it returns None only when custom is empty and all three
remote datasets (litellm_data, openrouter_data, and models_dev_data) are absent;
otherwise construct the pricing instance with the existing
new_with_custom_and_models_dev flow. Add a focused Rust unit test near this
implementation covering custom-only pricing with all remote caches set to None.

Source: Coding guidelines

crates/tokscale-cli/src/tui/ui/daily_profile.rs (1)

199-212: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

将测试的 home_dir 改为隔离目录

这里的 home_dir: None 会让 App::new_with_cached_data 走系统默认 home/config 目录,容易把本机状态带进测试。改成 tempfile::TempDir 或固定 dummy 路径,避免测试互相污染。

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@crates/tokscale-cli/src/tui/ui/daily_profile.rs` around lines 199 - 212,
Update the test helper make_app and its TuiConfig setup to use an isolated
temporary or dummy home_dir instead of None when calling
App::new_with_cached_data. Ensure the directory is available for the app
initialization and does not rely on or modify the system default home/config
location.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@crates/tokscale-cli/src/tui/ui/daily_profile.rs`:
- Around line 199-212: Update the test helper make_app and its TuiConfig setup
to use an isolated temporary or dummy home_dir instead of None when calling
App::new_with_cached_data. Ensure the directory is available for the app
initialization and does not rely on or modify the system default home/config
location.

In `@crates/tokscale-cli/src/tui/ui/footer.rs`:
- Around line 136-181: Update the footer layout around chunks and sort_controls
so that when sort_controls is empty, the summary uses the entire area width
instead of reserving the sort-column percentage. Preserve the existing
two-column layout and sort-button rendering when controls are present, and keep
rendering the summary through the existing chunks[1] path or an equivalent
full-width region.

In `@crates/tokscale-core/src/pricing/mod.rs`:
- Around line 155-166: Update from_cached_datasets so it returns None only when
custom is empty and all three remote datasets (litellm_data, openrouter_data,
and models_dev_data) are absent; otherwise construct the pricing instance with
the existing new_with_custom_and_models_dev flow. Add a focused Rust unit test
near this implementation covering custom-only pricing with all remote caches set
to None.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e4ddda8b-b158-4a11-bcad-ee62410b54d4

📥 Commits

Reviewing files that changed from the base of the PR and between 0e7f1bc and 0456e0a.

📒 Files selected for processing (18)
  • crates/tokscale-cli/src/cli.rs
  • crates/tokscale-cli/src/main_tests.rs
  • crates/tokscale-cli/src/tui/app.rs
  • crates/tokscale-cli/src/tui/mod.rs
  • crates/tokscale-cli/src/tui/session_data.rs
  • crates/tokscale-cli/src/tui/ui/daily_profile.rs
  • crates/tokscale-cli/src/tui/ui/footer.rs
  • crates/tokscale-cli/src/tui/ui/header.rs
  • crates/tokscale-cli/src/tui/ui/mod.rs
  • crates/tokscale-cli/src/tui/ui/overview.rs
  • crates/tokscale-cli/src/tui/ui/overview_snapshot.rs
  • crates/tokscale-cli/src/tui/ui/sessions.rs
  • crates/tokscale-cli/src/tui/ui/stats.rs
  • crates/tokscale-cli/src/tui/ui/view_footer.rs
  • crates/tokscale-cli/src/tui/view_state.rs
  • crates/tokscale-core/src/lib.rs
  • crates/tokscale-core/src/pricing/custom.rs
  • crates/tokscale-core/src/pricing/mod.rs
🚧 Files skipped from review as they are similar to previous changes (3)
  • crates/tokscale-cli/src/tui/ui/mod.rs
  • crates/tokscale-cli/src/tui/ui/stats.rs
  • crates/tokscale-cli/src/tui/ui/overview.rs

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant