Skip to content

Add time-range, session, and prompt reporting - #6

Open
suutari wants to merge 22 commits into
springernature:mainfrom
suutari:main
Open

suutari wants to merge 22 commits into
springernature:mainfrom
suutari:main

Conversation

@suutari

@suutari suutari commented Oct 21, 2026

Copy link
Copy Markdown

This PR expands occe with more flexible reporting and interactive TUI navigation.

New features:

  • Installable occe console script.
  • Calendar selectors for:
    • Months via --month YYYY-MM
    • ISO weeks via --week
    • Days via --day
    • Hours via --hour
  • Session-level reporting with --sessions.
  • Filtering by OpenCode session with --session.
  • Prompt reporting with --prompts, including:
    • Short, long, and full display modes
    • Prompt timestamps and project/session metadata
    • Per-prompt token and credit usage
    • Table and JSON output
  • TUI session, model, and prompt breakdown views.
  • TUI navigation between adjacent periods using f/b or arrow keys.
  • Derived time ranges across the hour, day, week, and month tabs.

Additionally includes some fixes:

  • Today and week chart labels now use local time consistently.
  • Month chart boundaries and daily buckets now use local calendar dates.
  • Month chart points align correctly with their displayed day labels.

Package the top-level modules so uv installs a working launcher when the
project environment is synchronized.  Record the new command in the
Unreleased changelog and ignore generated setuptools metadata.
Group OpenCode messages by session and expose the breakdown through with
table or JSON output.  Preserve the existing model-based output and
document the new report.
Allow reports and the TUI to estimate a selected calendar month with .
Label historical output and the TUI tab with the selected period while
preserving the existing session reports.
Limit TUI charts and non-interactive reports to a selected OpenCode
session while keeping month and session aggregation options composable.
Give project and session names more room and align session IDs under the
Session column for the existing unreleased session report.
Print user prompts and their token, cache, request, and credit data for
a selected OpenCode session.  Support short, long, and full text modes
with table and JSON output.
Support week, day, and hour selectors across the TUI and non-interactive
reports.  Derive the other TUI tabs from the selected anchor so
historical periods remain internally consistent.
Allow browsing adjacent periods with the arrow keys or N/P and return to
live ranges with R.  Keep the configured refresh interval active while
the TUI follows current time.
Allow the TUI breakdown table to switch between model and OpenCode
session views while retaining the current time range and refresh
behavior.
Use local-midnight boundaries and local-time bucket labels for the Today
chart so its visible timeline matches the selected local calendar day.
Align local-month buckets and cumulative chart points with calendar-day
labels, including the current day and the final day boundary.
Provide a prompt view in the TUI for inspecting timestamps, projects,
prompt content, and usage data in the existing breakdown table.
Use the remaining table width for Session names while keeping the
Project and usage columns fixed, matching the prompt table layout.
Let Textual clip session titles according to the flexible Session column
width instead of truncating them to the model-name limit before
rendering.
Use `p` for the prompt view and `f`/`b` for forward/backward period
navigation while retaining the arrow keys as aliases.
Map the TUI `today` tab name to the `day` selector before deriving
ranges so commands such as `--day ... --sessions` complete successfully.
Use the timezone attached to the selected range when building chart
buckets.  The range defines the calendar boundaries, so converting them
to the current timezone can shift bucket labels or assign rows to a
different local day.  In normal use, ranges use the current timezone
local offset, but tests use an explicit offset to remain independent of
the runner timezone.

Calculate hourly bucket positions from UTC elapsed time, then convert
labels back to the range timezone.

Add regression coverage for a range whose timezone differs from the
current timezone.
Keep the wheel's importable modules inside the project namespace to
avoid collisions with unrelated top-level modules.

Include the bundled pricing snapshot there so installed copies can still
estimate credits offline when the cache is empty or GitHub's pricing
page is unavailable.

Keeping the source files in place and supporting direct execution
preserves compatibility with the current Homebrew formula, which
installs and runs estimator.py and pricing.py directly.
When the initial refresh ran before Textual finished mounting the
screen, refresh_data() sometimes failed while querying `#chart`.
Startup raised `WorkerFailed` because `NoMatches: No nodes match #chart
on Screen(id=_default)`.

Fix this issue by deferring the initial refresh until after the screen
refresh, when composed widgets are available.
After switching the time range, the TUI table showed the flexible column
(Prompt, Session or Model) as a single character wide.  The widths only
corrected themselves on the next data refresh, either at the refresh
interval or when pressing `r`.

`DataTable` caches rendered lines.  The table was first drawn with
placeholder widths: the flexible column at `width=1` and the auto-width
columns at their header widths.  The real widths were calculated
afterwards, but nothing told Textual to redraw, so the stale lines
stayed on screen.  The next refresh called `clear()`, which drops those
caches, and that is why it appeared to fix itself.

Measure the new rows immediately after adding them, so the first frame
already has final widths.  Also drop the cached lines and redraw whenever
the column widths change, which covers the flexible column being resized
after the fact.

The regression test checks the rendered line right after changing the
range, rather than `column.width`.  The width is correct by the time it
is inspected, which is why checking it did not catch this.
@suutari
suutari requested a review from sonniesedge as a code owner October 21, 2026 14:37
@suutari

suutari commented Oct 21, 2026

Copy link
Copy Markdown
Author

This is the fixed version of PR #5.

@sonniesedge I fixed the issues you mentioned in #5 (comment). Additionally there's couple other fixes included (last two commits).

Also rebased this on top of the current main and therefore needed to open this as a new PR, because apparently GitHub didn't allow to update the PR via force-push.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant