summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDax Raad <[email protected]>2025-11-22 00:48:22 -0500
committerDax Raad <[email protected]>2025-11-22 00:49:35 -0500
commit87054ee983f1988ca0cd6a459c0f5bd98cbd61d7 (patch)
treeccf9979ab116200f37bd8441428a1d4d28e60b81
parent81245c254882c2fe18abdebfdc6e21ba26fc0c4b (diff)
downloadopencode-87054ee983f1988ca0cd6a459c0f5bd98cbd61d7.tar.gz
opencode-87054ee983f1988ca0cd6a459c0f5bd98cbd61d7.zip
fix flickering/layout shift during work
-rw-r--r--packages/opencode/src/cli/cmd/tui/routes/session/index.tsx60
1 files changed, 5 insertions, 55 deletions
diff --git a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
index ba4da4d21..43b8cc9de 100644
--- a/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
+++ b/packages/opencode/src/cli/cmd/tui/routes/session/index.tsx
@@ -6,8 +6,6 @@ import {
For,
Match,
on,
- onCleanup,
- onMount,
Show,
Switch,
useContext,
@@ -45,7 +43,6 @@ import type { TaskTool } from "@/tool/task"
import { useKeyboard, useRenderer, useTerminalDimensions, type BoxProps, type JSX } from "@opentui/solid"
import { useSDK } from "@tui/context/sdk"
import { useCommandDialog } from "@tui/component/dialog-command"
-import { Shimmer } from "@tui/ui/shimmer"
import { useKeybind } from "@tui/context/keybind"
import { Header } from "./header"
import { parsePatch } from "diff"
@@ -64,8 +61,6 @@ import { Clipboard } from "../../util/clipboard"
import { Toast, useToast } from "../../ui/toast"
import { useKV } from "../../context/kv.tsx"
import { Editor } from "../../util/editor"
-import { Global } from "@/global"
-import fs from "fs/promises"
import stripAnsi from "strip-ansi"
addDefaultParsers(parsers.parsers)
@@ -106,6 +101,10 @@ export function Session() {
return messages().findLast((x) => x.role === "assistant" && !x.time.completed)?.id
})
+ const lastAssistant = createMemo(() => {
+ return messages().findLast((x) => x.role === "assistant")
+ })
+
const dimensions = useTerminalDimensions()
const [sidebar, setSidebar] = createSignal<"show" | "hide" | "auto">(kv.get("sidebar", "auto"))
const [conceal, setConceal] = createSignal(true)
@@ -513,7 +512,6 @@ export function Session() {
return
}
- console.log(text)
const base64 = Buffer.from(text).toString("base64")
const osc52 = `\x1b]52;c;${base64}\x07`
const finalOsc52 = process.env["TMUX"] ? `\x1bPtmux;\x1b${osc52}\x1b\\` : osc52
@@ -846,7 +844,7 @@ export function Session() {
</Match>
<Match when={message.role === "assistant"}>
<AssistantMessage
- last={pending() === message.id}
+ last={lastAssistant()?.id === message.id}
message={message as AssistantMessage}
parts={sync.data.part[message.id] ?? []}
/>
@@ -975,13 +973,6 @@ function UserMessage(props: {
function AssistantMessage(props: { message: AssistantMessage; parts: Part[]; last: boolean }) {
const local = useLocal()
const { theme } = useTheme()
- const sync = useSync()
- const status = createMemo(
- () =>
- sync.data.session_status[props.message.sessionID] ?? {
- type: "idle",
- },
- )
return (
<>
<For each={props.parts}>
@@ -1014,46 +1005,6 @@ function AssistantMessage(props: { message: AssistantMessage; parts: Part[]; las
</box>
</Show>
<Switch>
- <Match when={props.last && status().type !== "idle" && false}>
- <box paddingLeft={3} flexDirection="row" gap={1} marginTop={1}>
- <text fg={local.agent.color(props.message.mode)}>{Locale.titlecase(props.message.mode)}</text>
- <Shimmer text={props.message.modelID} color={theme.text} />
- {(() => {
- const retry = createMemo(() => {
- const s = status()
- if (s.type !== "retry") return
- return s
- })
- const message = createMemo(() => {
- const r = retry()
- if (!r) return
- if (r.message.includes("exceeded your current quota") && r.message.includes("gemini"))
- return "gemini 3 way too hot right now"
- if (r.message.length > 50) return r.message.slice(0, 50) + "..."
- return r.message
- })
- const [seconds, setSeconds] = createSignal(0)
- onMount(() => {
- const timer = setInterval(() => {
- const next = retry()?.next
- if (next) setSeconds(Math.round((next - Date.now()) / 1000))
- }, 1000)
-
- onCleanup(() => {
- clearInterval(timer)
- })
- })
- return (
- <Show when={retry()}>
- <text fg={theme.error}>
- {message()} [retrying {seconds() > 0 ? `in ${seconds()}s ` : ""}
- attempt #{retry()!.attempt}]
- </text>
- </Show>
- )
- })()}
- </box>
- </Match>
<Match
when={
(props.message.time.completed &&
@@ -1535,7 +1486,6 @@ ToolRegistry.register<typeof EditTool>({
const ft = createMemo(() => filetype(props.input.filePath))
- createEffect(() => console.log(props.metadata.diagnostics))
const diagnostics = createMemo(() => {
const arr = props.metadata.diagnostics?.[props.input.filePath ?? ""] ?? []
return arr.filter((x) => x.severity === 1).slice(0, 3)