Compare commits

...
Author SHA1 Message Date
usrnk1 c4327a67fa test(app): update context button locators 2026-10-07 20:21:07 +02:00
usrnk1 6b9f03b13f feat(desktop): show tokens and cost in context button 2026-10-07 20:20:48 +02:00
3 changed files with 31 additions and 11 deletions

No files matched your search

+3 -3
View File
@@ -143,7 +143,7 @@ test("open file tab browses, searches, and tracks missing files", async ({ page
const panel = page.locator("#review-panel")
const sidebar = panel.locator('[data-slot="session-review-v2-sidebar"]')
const sidebarToggle = panel.getByRole("button", { name: "Toggle file tree" })
const contextButton = page.getByRole("button", { name: "View context usage" })
const contextButton = page.getByRole("button", { name: "Toggle session context" })
const openFile = panel.getByRole("button", { name: "Open file" })
const tab = (name: string) => panel.getByRole("tab", { name, exact: true })
await contextButton.click()
@@ -309,7 +309,7 @@ test("context closes the side region only when its button opened it", async ({ p
})
const panel = page.locator("#review-panel")
const toggle = page.getByRole("button", { name: "Toggle review", exact: true })
const contextButton = page.getByRole("button", { name: "View context usage" })
const contextButton = page.getByRole("button", { name: "Toggle session context" })
const context = panel.getByRole("tab", { name: "Context", exact: true })
await contextButton.click()
@@ -630,7 +630,7 @@ test("restores review state and the side-panel tab per session", async ({ page }
await page.getByRole("option", { name: "Branch changes" }).click()
await page.getByRole("button", { name: "beta.ts" }).click()
await selectedFile("beta.ts")
await page.getByRole("button", { name: "View context usage" }).click()
await page.getByRole("button", { name: "Toggle session context" }).click()
await selectedTab("Context")
await switchSession("Gamma review state")
@@ -5,6 +5,7 @@ export default {
"usage.usage": "Context",
"usage.cost": "Cost",
"usage.view": "View context usage",
"usage.toggle": "Toggle session context",
"systemPrompt.title": "System Prompt",
"rawMessages.title": "Raw messages",
"export.session": "Export session",
@@ -1,6 +1,6 @@
import { Show, createMemo, type ComponentProps, type JSX } from "solid-js"
import { ProgressCircle } from "@opencode/ui/progress-circle"
import { IconButton } from "@opencode/ui/icon-button"
import { Button } from "@opencode/ui/button"
import { Tooltip } from "@opencode/ui/tooltip"
import { useI18n } from "@opencode/ui/context/i18n"
import { useExtension, type MountedSession } from "../sdk"
@@ -62,6 +62,12 @@ export function SessionContextUsage(props: {
}
})
const tokens = createMemo(() =>
new Intl.NumberFormat(i18n.locale(), { notation: "compact", maximumFractionDigits: 0 })
.format(context()?.total ?? 0)
.toLocaleLowerCase(i18n.locale()),
)
const cost = createMemo(() => {
return usd().format(info()?.cost ?? 0)
})
@@ -89,7 +95,7 @@ export function SessionContextUsage(props: {
const compactCircle = () => (
<div class="flex items-center justify-center">
<ProgressCircle appearance="compact" percentage={context()?.usage ?? 0} />
<ProgressCircle appearance="compact" size={16} percentage={context()?.usage ?? 0} />
</div>
)
@@ -103,18 +109,31 @@ export function SessionContextUsage(props: {
return (
<Show when={props.session.id}>
<Tooltip value={tooltipValue()} placement={props.placement ?? "top"} shift={-8}>
<Tooltip
value={variant() === "indicator" ? tooltipValue() : ctx.t("usage.toggle")}
placement={props.placement ?? "top"}
>
<Show
when={variant() === "indicator"}
fallback={
<IconButton
<Button
type="button"
variant="ghost-muted"
size="large"
icon={compactCircle()}
class="group shrink-0"
style={{ padding: "0 6px", color: "var(--v2-text-text-faint)" }}
onClick={openContext}
aria-label={ctx.t("usage.view")}
/>
aria-expanded={layout.state(`${ctx.id}:main`, props.session) === "visible"}
aria-label={ctx.t("usage.toggle")}
>
<span class="flex items-center gap-2 whitespace-nowrap group-active:text-v2-text-text-muted">
{compactCircle()}
<span>{tokens()}</span>
<span aria-hidden="true" class="flex w-1.5 shrink-0 items-center justify-center">
·
</span>
<span>{cost()}</span>
</span>
</Button>
}
>
{circle()}