mirror of
https://github.com/openai/codex.git
synced 2026-09-04 15:08:45 +00:00
## Why
[#25345](https://github.com/openai/codex/pull/25345) was approved,
green, and squash-merged into its stacked base branch,
`fcoury/tokenmaxxing-api`. Four minutes later, that base branch was
force-pushed back to an API-only rebased head while preparing
[#25344](https://github.com/openai/codex/pull/25344) for `main`. As a
result, the squash commit from #25345 was orphaned and the TUI command
never reached `main` or a release.
This PR relands the orphaned TUI change from
[`411410b8`](411410b85c)
on current `main`.
## What changed
- Add `/usage`, `/usage daily`, `/usage weekly`, and `/usage cumulative`
for account token activity.
- Fetch account usage asynchronously through the existing
`account/usage/read` app-server RPC.
- Render daily, weekly, and cumulative activity with theme-aware
terminal palettes and bounded transient cards.
- Preserve transcript ordering while assistant streams, history
consolidations, active cells, and hooks complete.
- Hide `/usage` from completion when backend auth is unavailable while
keeping typed-command guidance.
- Carry current-main behavior forward for cwd-aware Markdown parsing,
Windows Terminal color detection, and personal access token auth.
- Clear pending usage cards on thread rollback and delay completed cards
until live hook output is committed.
- Add focused regression and snapshot coverage for loading, auth errors,
invalid views, rollback, hook ordering, layout, and charts.
## Prior review
The original implementation was approved by Eric Traut in #25345 after
testing multiple themes and light/dark terminals. This PR preserves that
reviewed implementation while adapting it to current `main` and adding
regression coverage for newer rollback and hook lifecycle behavior.
## Validation
- `just test -p codex-tui token_activity palette renderable
usage_command` — 37 passed.
- Focused rollback, hook-ordering, and error snapshot tests — 4 passed.
- `just fix -p codex-tui` — passed.
- `UV_CACHE_DIR=/private/tmp/codex-uv-cache just fmt` — passed.
- `cargo insta pending-snapshots` — no pending snapshots.
- `just test -p codex-tui` — 2,870 passed; two unrelated guardian
feature-flag tests failed because their expected `OverrideTurnContext`
event was absent:
-
`update_feature_flags_disabling_guardian_clears_manual_review_policy_without_history`
-
`update_feature_flags_disabling_guardian_clears_review_policy_and_restores_default`
- `just argument-comment-lint` could not complete because the local
Bazel LLVM `compiler-rt` repository is missing `include/sanitizer/*.h`.
The touched Rust diff was manually inspected and no missing
opaque-literal argument comments were found.
73 lines
1.7 KiB
Rust
73 lines
1.7 KiB
Rust
use super::*;
|
|
use pretty_assertions::assert_eq;
|
|
|
|
struct HeightRenderable(u16);
|
|
|
|
impl HeightRenderable {
|
|
fn with_height(height: u16) -> Self {
|
|
Self(height)
|
|
}
|
|
}
|
|
|
|
impl Renderable for HeightRenderable {
|
|
fn render(&self, _area: Rect, _buf: &mut Buffer) {}
|
|
|
|
fn desired_height(&self, _width: u16) -> u16 {
|
|
self.0
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn flex_redistributes_space_unused_by_short_children() {
|
|
let mut flex = FlexRenderable::new();
|
|
flex.push(
|
|
/*flex*/ 1,
|
|
RenderableItem::Owned(Box::new(HeightRenderable::with_height(/*height*/ 20))),
|
|
);
|
|
flex.push(
|
|
/*flex*/ 1,
|
|
RenderableItem::Owned(Box::new(HeightRenderable::with_height(/*height*/ 2))),
|
|
);
|
|
|
|
let allocated = flex.allocate(Rect::new(
|
|
/*x*/ 0, /*y*/ 0, /*width*/ 80, /*height*/ 10,
|
|
));
|
|
|
|
assert_eq!(
|
|
allocated
|
|
.into_iter()
|
|
.map(|area| area.height)
|
|
.collect::<Vec<_>>(),
|
|
vec![8, 2],
|
|
);
|
|
}
|
|
|
|
#[test]
|
|
fn flex_reserves_non_flex_space_before_flexible_children() {
|
|
let mut flex = FlexRenderable::new();
|
|
flex.push(
|
|
/*flex*/ 1,
|
|
RenderableItem::Owned(Box::new(HeightRenderable::with_height(/*height*/ 20))),
|
|
);
|
|
flex.push(
|
|
/*flex*/ 0,
|
|
RenderableItem::Owned(Box::new(HeightRenderable::with_height(/*height*/ 2))),
|
|
);
|
|
flex.push(
|
|
/*flex*/ 1,
|
|
RenderableItem::Owned(Box::new(HeightRenderable::with_height(/*height*/ 20))),
|
|
);
|
|
|
|
let allocated = flex.allocate(Rect::new(
|
|
/*x*/ 0, /*y*/ 0, /*width*/ 80, /*height*/ 10,
|
|
));
|
|
|
|
assert_eq!(
|
|
allocated
|
|
.into_iter()
|
|
.map(|area| area.height)
|
|
.collect::<Vec<_>>(),
|
|
vec![4, 2, 4],
|
|
);
|
|
}
|