Skip to content

🤖 feat(goals-tab): consolidate Cost/Budget/Remaining + always show Turn cap#3314

Merged
ammario merged 4 commits into
mainfrom
goals-tab-budget-display
May 18, 2026
Merged

🤖 feat(goals-tab): consolidate Cost/Budget/Remaining + always show Turn cap#3314
ammario merged 4 commits into
mainfrom
goals-tab-budget-display

Conversation

@ammar-agent
Copy link
Copy Markdown
Collaborator

Summary

Cleans up the active-goal stat surface in the right-sidebar Goal tab so
the user can read "spent of cap, X left" without bouncing between
tiles, and so the turn cap is always visible alongside the turns used
— not just after clicking Edit.

Background

Prior layout placed Cost, Budget, and Remaining as three sibling tiles
in a 2-column grid. The Turns tile rendered just turnsUsed when no
cap was configured, so "3" was indistinguishable from "no cap set yet"
vs "limit set higher than current usage". Both behaviors made the user
do mental arithmetic and click Edit to inspect state, which the slot
was supposed to surface in the first place.

Implementation

Two small components extracted from GoalTab.tsx:

  • BudgetTile — consolidates Cost / Budget / Remaining into a single
    full-width card. Renders $1.25 of $5.00 prominently with $3.75 left muted, plus a thin progress bar exposed via role="progressbar"

    • aria-valuetext. Bar turns danger-soft when the goal is in
      budget_limited status or cost meets the cap. When no budget is
      configured (budgetCents == null) the bar collapses and the card
      becomes a Cost-only view with a no budget label.
  • TurnsTile — renders turns / cap plus a secondary X left line.
    When turnCap == null we surface a no cap label instead of
    hiding the cap entirely.

Edit affordances and aria-labels are unchanged so the inline budget
and turn-cap editors continue to work and existing tests targeting
Edit goal budget / Edit goal turn cap still match.

Validation

  • 19/19 GoalTab.test.tsx pass (16 existing + 3 new behavioral tests
    covering: turn cap visible when null; budget tile composite render;
    bar omitted when no budget).
  • 237/237 RightSidebar + workspaceGoalService tests pass.
  • make static-check green locally.

Chromatic will diff the redesigned Active, ActiveWithAccounting,
Paused, and BudgetLimited stories — the new layout is intentional
so those snapshots will need approval.

Risks

Low. The change is contained to the active-goal stat tile rendering
in GoalTab.tsx. Goal record types, lifecycle math, and backend
mutations are untouched. The new components are pure-render with no
new effects, no IPC calls, and no localStorage interaction.


Generated with mux • Model: anthropic:claude-opus-4-7 • Thinking: xhigh • Cost: $203.76

…rn cap

Active-goal stat tiles previously fragmented one concept across multiple
tiles. The user had to mentally re-assemble "I've spent $1.25 of $5.00,
so $3.75 is left" from three separate corners of the panel; the turn
cap was only surfaced inside the edit dialog, so "3" looked the same
whether the cap was 4, 1000, or unset.

Replace the 5-tile grid with three semantically-grouped tiles:

  • Budget (full-width): cost / cap, remaining, and a thin progress
    bar in one card. Bar collapses + tile becomes a Cost-only card
    when budgetCents is null. Bar turns danger-soft once the goal is
    budget_limited or cost meets the cap.

  • Turns (half-width): turns / cap with "X left" secondary line.
    When turnCap is null we surface "no cap" so the user can tell
    "no limit set" from "limit way higher than current usage".

  • Elapsed (half-width): unchanged.

Edit affordances stay on each tile with the existing aria-labels so
the inline editor path is untouched.
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Copy link
Copy Markdown

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

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: f73d56ab40

ℹ️ 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 src/browser/features/RightSidebar/GoalTab.tsx Outdated
Comment thread src/browser/features/RightSidebar/GoalTab.tsx Outdated
…d $0.00 (Codex P2)

Codex caught two parallel defects in the new BudgetTile / TurnsTile
over-cap branches: each computed a single `remaining = max(0, cap -
used)` delta and rendered it with the `over` suffix, so a 25¢
overspend (`costCents: 525`, `budgetCents: 500`) and any over-cap
turn count were both reported as "$0.00 over" / "0 over". The
clamped magnitude hid how far past the limit the goal actually was.

Compute two non-negative deltas per tile and pick the one that
matches the active branch:
- under-limit branch shows `cap - used` with "left" suffix
- over-limit branch shows `used - cap` with "over" suffix

Added two behavioral tests (over-budget BudgetLimited goal +
over-cap Turns goal) to lock the corrected magnitude.
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Addressed both P2 findings: the over-budget and over-cap branches now
compute a separate non-negative overage delta (cost - budget and
turnsUsed - turnCap respectively) instead of reusing the clamped
remaining value, so the tile reports the actual magnitude
(e.g. $0.25 over, 2 over) instead of $0.00 over / 0 over.

Added two behavioral tests covering both branches.

Copy link
Copy Markdown

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

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: 097482c344

ℹ️ 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 src/browser/features/RightSidebar/GoalTab.tsx Outdated
…lutter continuation card (Codex P2)

Two related cleanups in the same diff:

1. Codex P2: the new BudgetTile keyed its over/under-budget rendering
   off `status === "budget_limited"`. The backend (`hasReachedAnyLimit()`
   in workspaceGoalService.ts) sets that status when EITHER limit is
   reached, so a goal at `cost $1.25 of $5.00, turns 10/10` was
   labeled "$0.00 over" — a lie about the money. The fix is to base
   over/under-budget strictly on the budget numbers themselves
   (`costCents >= budgetCents`) and let TurnsTile worry about turn
   overages independently. `status` is no longer a BudgetTile input.

2. The goal-continuation / budget-limit transcript card had double
   chrome (its own border + tinted background sitting inside the
   user-message bubble's border + tinted surface), a `min-w-[18rem]`
   that blew out the bubble for short objectives, and a chunky icon
   badge (`bg-muted/20 p-1.5` around a 16px icon) that didn't scale
   with the 14px title text. Result: an awkwardly oversized inline
   card mid-transcript. Strip the inner card chrome — the parent
   bubble is the visual container — replace the badge with a small
   inline icon (`size-4` + `mt-0.5` to vertically center with the
   first line of text), and let the bubble hug its content. The
   "goal continuation" pill in the meta row still labels the synthetic
   nature of the message.

Added behavioral test locking the budget-tile fix (Codex case:
budget_limited with turn cap reached but cost below budget renders
under-budget, not over).
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Round 2 fixes:

  1. P2 follow-up: BudgetTile no longer keys its over/under-budget rendering off the shared budget_limited lifecycle status. The backend uses that status for both "hit budget" and "hit turn cap" paths (hasReachedAnyLimit()), so the tile now derives over/under strictly from the budget numbers (costCents >= budgetCents). Added a test covering the original Codex case: budget_limited triggered by turn-cap saturation with budget unspent must render as under-budget.

  2. Goal continuation card aesthetic: stripped the inner-card double chrome (the old card had its own border + tinted background nested inside the user bubble), removed min-w-[18rem] that blew out short messages, and replaced the chunky icon badge with a small inline icon (size-4 mt-0.5) so it scales with the title text. Meta-row pill still labels the synthetic nature.

Copy link
Copy Markdown

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

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: 215fe8b9aa

ℹ️ 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 src/browser/features/RightSidebar/GoalTab.tsx Outdated
…'over' (Codex P2 round 3)

At `turnsUsed === turnCap` (the normal cap-reached path used by
`hasReachedTurnLimit()`), the previous render sent the tile down the
"over" branch with `turnsOverBy === 0`, producing "0 over" — a
misleading label since the goal is AT the cap, not past it. Same
applies to budget at `costCents === budgetCents`.

Reserve the "over" copy for STRICT inequality:
- `costCents > budgetCents` / `turnsUsed > turnCap` → "X over"
- exact equality → "0 left"

The bar fill and danger color still trip at `>=` so reaching the cap
exactly is visually signaled — only the textual suffix changed.

Added a behavioral test covering exact-equality saturation on both
tiles.
@ammar-agent
Copy link
Copy Markdown
Collaborator Author

@codex review

Round 3 fix: BudgetTile and TurnsTile now reserve the "over" suffix for strict inequality (>, not >=). Exact saturation at costCents === budgetCents / turnsUsed === turnCap renders "$0.00 left" / "0 left", which matches the linguistic intent — the goal has reached the cap, not exceeded it. The bar fill and danger color still trip at >= so the at-cap state is visually flagged.

Added a behavioral test covering both tiles at exact saturation.

@chatgpt-codex-connector
Copy link
Copy Markdown

Codex Review: Didn't find any major issues. More of your lovely PRs please.

ℹ️ 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".

@ammario ammario merged commit 1f60906 into main May 18, 2026
23 checks passed
@ammario ammario deleted the goals-tab-budget-display branch May 18, 2026 18:42
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.

2 participants