Skip to content

Commit 0a7a00e

Browse files
committed
Merge branch 'shuvcode-dev' into integration
Resolved conflicts in: - bun.lock Closes #242
2 parents b02083f + 486205f commit 0a7a00e

27 files changed

Lines changed: 1367 additions & 1256 deletions

File tree

.github/last-synced-tag

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v1.0.222
1+
v1.0.223

bun.lock

Lines changed: 15 additions & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

flake.lock

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nix/hashes.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
"nodeModules": "sha256-7zMUWgMCnoe2As8WdEKazkKiGEcUIk5rP4zFvX9USgA="
2+
"nodeModules": "sha256-uJDhOieOdMQLORyuOWtgtjLoMnNEQPrDcyij9TX0aTw="
33
}

packages/app/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@opencode-ai/app",
3-
"version": "1.0.222",
3+
"version": "1.0.223",
44
"description": "",
55
"type": "module",
66
"exports": {
Lines changed: 70 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,25 @@
1-
import { createMemo, Show } from "solid-js"
1+
import { Match, Show, Switch, createMemo } from "solid-js"
22
import { Tooltip } from "@opencode-ai/ui/tooltip"
33
import { ProgressCircle } from "@opencode-ai/ui/progress-circle"
4-
import { useSync } from "@/context/sync"
4+
import { Button } from "@opencode-ai/ui/button"
55
import { useParams } from "@solidjs/router"
66
import { AssistantMessage } from "@opencode-ai/sdk/v2/client"
77

8-
export function SessionContextUsage() {
8+
import { useLayout } from "@/context/layout"
9+
import { useSync } from "@/context/sync"
10+
11+
interface SessionContextUsageProps {
12+
variant?: "button" | "indicator"
13+
}
14+
15+
export function SessionContextUsage(props: SessionContextUsageProps) {
916
const sync = useSync()
1017
const params = useParams()
18+
const layout = useLayout()
19+
20+
const variant = createMemo(() => props.variant ?? "button")
21+
const sessionKey = createMemo(() => `${params.dir}${params.id ? "/" + params.id : ""}`)
22+
const tabs = createMemo(() => layout.tabs(sessionKey()))
1123
const messages = createMemo(() => (params.id ? (sync.data.message[params.id] ?? []) : []))
1224

1325
const cost = createMemo(() => {
@@ -19,7 +31,11 @@ export function SessionContextUsage() {
1931
})
2032

2133
const context = createMemo(() => {
22-
const last = messages().findLast((x) => x.role === "assistant" && x.tokens.output > 0) as AssistantMessage
34+
const last = messages().findLast((x) => {
35+
if (x.role !== "assistant") return false
36+
const total = x.tokens.input + x.tokens.output + x.tokens.reasoning + x.tokens.cache.read + x.tokens.cache.write
37+
return total > 0
38+
}) as AssistantMessage
2339
if (!last) return
2440
const total =
2541
last.tokens.input + last.tokens.output + last.tokens.reasoning + last.tokens.cache.read + last.tokens.cache.write
@@ -30,33 +46,57 @@ export function SessionContextUsage() {
3046
}
3147
})
3248

33-
return (
34-
<Show when={context?.()}>
35-
{(ctx) => (
36-
<Tooltip
37-
value={
38-
<div class="">
39-
<div class="flex items-center gap-2">
40-
<span class="text-text-invert-strong">{ctx().tokens}</span>
41-
<span class="text-text-invert-base">Tokens</span>
42-
</div>
43-
<div class="flex items-center gap-2">
44-
<span class="text-text-invert-strong">{ctx().percentage ?? 0}%</span>
45-
<span class="text-text-invert-base">Usage</span>
46-
</div>
47-
<div class="flex items-center gap-2">
48-
<span class="text-text-invert-strong">{cost()}</span>
49-
<span class="text-text-invert-base">Cost</span>
50-
</div>
49+
const openContext = () => {
50+
if (!params.id) return
51+
layout.review.open()
52+
tabs().open("context")
53+
tabs().setActive("context")
54+
}
55+
56+
const circle = () => (
57+
<div class="p-1">
58+
<ProgressCircle size={16} strokeWidth={2} percentage={context()?.percentage ?? 0} />
59+
</div>
60+
)
61+
62+
const tooltipValue = () => (
63+
<div>
64+
<Show when={context()}>
65+
{(ctx) => (
66+
<>
67+
<div class="flex items-center gap-2">
68+
<span class="text-text-invert-strong">{ctx().tokens}</span>
69+
<span class="text-text-invert-base">Tokens</span>
70+
</div>
71+
<div class="flex items-center gap-2">
72+
<span class="text-text-invert-strong">{ctx().percentage ?? 0}%</span>
73+
<span class="text-text-invert-base">Usage</span>
5174
</div>
52-
}
53-
placement="top"
54-
>
55-
<div class="p-1">
56-
<ProgressCircle size={16} strokeWidth={2} percentage={ctx().percentage ?? 0} />
57-
</div>
58-
</Tooltip>
59-
)}
75+
</>
76+
)}
77+
</Show>
78+
<div class="flex items-center gap-2">
79+
<span class="text-text-invert-strong">{cost()}</span>
80+
<span class="text-text-invert-base">Cost</span>
81+
</div>
82+
<Show when={variant() === "button"}>
83+
<div class="text-11-regular text-text-invert-base mt-1">Click to view context</div>
84+
</Show>
85+
</div>
86+
)
87+
88+
return (
89+
<Show when={params.id}>
90+
<Tooltip value={tooltipValue()} placement="top">
91+
<Switch>
92+
<Match when={variant() === "indicator"}>{circle()}</Match>
93+
<Match when={true}>
94+
<Button type="button" variant="ghost" class="size-6" onClick={openContext}>
95+
{circle()}
96+
</Button>
97+
</Match>
98+
</Switch>
99+
</Tooltip>
60100
</Show>
61101
)
62102
}

packages/app/src/context/layout.tsx

Lines changed: 41 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -395,38 +395,58 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
395395
},
396396
async open(tab: string) {
397397
const current = store.sessionTabs[sessionKey] ?? { all: [] }
398-
if (tab !== "review") {
399-
if (!current.all.includes(tab)) {
400-
if (!store.sessionTabs[sessionKey]) {
401-
setStore("sessionTabs", sessionKey, { all: [tab], active: tab })
402-
} else {
403-
setStore("sessionTabs", sessionKey, "all", [...current.all, tab])
404-
setStore("sessionTabs", sessionKey, "active", tab)
405-
}
398+
399+
if (tab === "review") {
400+
if (!store.sessionTabs[sessionKey]) {
401+
setStore("sessionTabs", sessionKey, { all: [], active: tab })
406402
return
407403
}
404+
setStore("sessionTabs", sessionKey, "active", tab)
405+
return
408406
}
409-
if (!store.sessionTabs[sessionKey]) {
410-
setStore("sessionTabs", sessionKey, { all: [], active: tab })
411-
} else {
407+
408+
if (tab === "context") {
409+
const all = [tab, ...current.all.filter((x) => x !== tab)]
410+
if (!store.sessionTabs[sessionKey]) {
411+
setStore("sessionTabs", sessionKey, { all, active: tab })
412+
return
413+
}
414+
setStore("sessionTabs", sessionKey, "all", all)
412415
setStore("sessionTabs", sessionKey, "active", tab)
416+
return
413417
}
418+
419+
if (!current.all.includes(tab)) {
420+
if (!store.sessionTabs[sessionKey]) {
421+
setStore("sessionTabs", sessionKey, { all: [tab], active: tab })
422+
return
423+
}
424+
setStore("sessionTabs", sessionKey, "all", [...current.all, tab])
425+
setStore("sessionTabs", sessionKey, "active", tab)
426+
return
427+
}
428+
429+
if (!store.sessionTabs[sessionKey]) {
430+
setStore("sessionTabs", sessionKey, { all: current.all, active: tab })
431+
return
432+
}
433+
setStore("sessionTabs", sessionKey, "active", tab)
414434
},
415435
close(tab: string) {
416436
const current = store.sessionTabs[sessionKey]
417437
if (!current) return
438+
439+
const all = current.all.filter((x) => x !== tab)
418440
batch(() => {
419-
setStore(
420-
"sessionTabs",
421-
sessionKey,
422-
"all",
423-
current.all.filter((x) => x !== tab),
424-
)
425-
if (current.active === tab) {
426-
const index = current.all.findIndex((f) => f === tab)
427-
const previous = current.all[Math.max(0, index - 1)]
428-
setStore("sessionTabs", sessionKey, "active", previous)
441+
setStore("sessionTabs", sessionKey, "all", all)
442+
if (current.active !== tab) return
443+
444+
const index = current.all.findIndex((f) => f === tab)
445+
if (index <= 0) {
446+
setStore("sessionTabs", sessionKey, "active", undefined)
447+
return
429448
}
449+
setStore("sessionTabs", sessionKey, "active", current.all[index - 1])
430450
})
431451
},
432452
move(tab: string, to: number) {

0 commit comments

Comments
 (0)