Skip to content

fix(app): order the inbox Working shelf by when each run started - #60147

Merged
Brendonovich merged 1 commit into
devfrom
inbox-working-busy
Oct 29, 2026
Merged

Brendonovich merged 1 commit into
devfrom
inbox-working-busy

Conversation

@opencode-agent

Copy link
Copy Markdown
Contributor

The Working shelf in the Inbox sidebar reordered on almost every streamed message, and each row's "Working Ns" timer kept resetting. Both used time.updated, which the server bumps on every message event.

Both now use time.busy (#59910), which records when the session's current run started:

  • The shelf lists the earliest-started run first, so a session that starts working joins the end and rows stay put while they stream.
  • The timer counts from the run's start.

workingSince (new, inbox-working.ts) treats time.busy as the current run's start only when it isn't older than time.idle. When a turn starts, the client marks the session working right away and refetches it to get the new time.busy. Until that arrives, it still holds the previous run's start. A row in that state shows plain "Working" without a duration and sorts last. Servers that don't record time.busy behave the same way.

This replaces the client-side arrival-order tracking in #59692.

Lint on touched files also clears two existing findings in inbox.tsx: a missing blank line before return in DeleteDialog, and the status() as Exclude<…> assertion, which is now a narrowed statusLabel helper.

Testing

  • bun test … src/shell/titlebar/ (28 pass, including the new inbox-working.test.ts)
  • bun run typecheck in packages/app
  • bun run lint:changed: clean

Requested by: @Brendonovich (Brendan via Slack)

@opencodejr opencodejr 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.

The approach looks sound. time.busy is the right signal for both the Working order and the timer, and the sort is stable: earliest-started run first, rows with no known start last, ties broken by key. I checked it with the titlebar tests (28 pass) and tsc -b in packages/app. I couldn't run the desktop/web Inbox here. A short before/after video of the Working shelf while two sessions stream would help reviewers.

Public API: unchanged. The change only reads the existing time.busy field.

One non-blocking point, inline: sessions that aren't loaded in the data store don't get a fresh time.busy when a new run starts. For those, the row shows plain "Working" and sorts last for the whole run.

export function workingSince(session: SessionTime) {
const { busy, idle } = session.time

if (busy === undefined || (idle !== undefined && idle > busy)) return undefined

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The data store only refetches on session.execution.started when the session is already in store.session.info or being synced (packages/client/src/solid/data.ts). Some inbox rows come only from the inbox-sessions list query (staleTime: 30_000, refetched on mount/reconnect), for example an older session rerun from the TUI or another window. For those, time.busy stays at the previous run's value for the whole new run, so the row shows plain "Working" and sorts last until it ends. That's no worse than the old stale time.updated timer. If you want those rows to get a timer too, one option is to refresh the inbox entry (or invalidate the inbox query) when such a session starts executing.

@Brendonovich
Brendonovich merged commit 2999751 into dev Oct 29, 2026
21 checks passed
@Brendonovich
Brendonovich deleted the inbox-working-busy branch October 29, 2026 08:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant