summaryrefslogtreecommitdiffhomepage
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/opencode/src/cli/cmd/tui/app.tsx88
1 files changed, 12 insertions, 76 deletions
diff --git a/packages/opencode/src/cli/cmd/tui/app.tsx b/packages/opencode/src/cli/cmd/tui/app.tsx
index 1aee07ad6..5105ee3c6 100644
--- a/packages/opencode/src/cli/cmd/tui/app.tsx
+++ b/packages/opencode/src/cli/cmd/tui/app.tsx
@@ -2,19 +2,9 @@ import { render, useKeyboard, useRenderer, useTerminalDimensions } from "@opentu
import { Clipboard } from "@tui/util/clipboard"
import { TextAttributes } from "@opentui/core"
import { RouteProvider, useRoute } from "@tui/context/route"
-import {
- Switch,
- Match,
- createEffect,
- untrack,
- ErrorBoundary,
- createSignal,
- onMount,
- onCleanup,
- batch,
- on,
-} from "solid-js"
+import { Switch, Match, createEffect, untrack, ErrorBoundary, createSignal, onMount, batch, Show, on } from "solid-js"
import { Installation } from "@/installation"
+import { Global } from "@/global"
import { Flag } from "@/flag/flag"
import { DialogProvider, useDialog } from "@tui/ui/dialog"
import { DialogProvider as DialogProviderList } from "@tui/component/dialog-provider"
@@ -45,7 +35,6 @@ import { Provider } from "@/provider/provider"
import { ArgsProvider, useArgs, type Args } from "./context/args"
import open from "open"
import { PromptRefProvider, usePromptRef } from "./context/prompt"
-import { iife } from "@/util/iife"
async function getTerminalBackgroundColor(): Promise<"dark" | "light"> {
// can't set raw mode if not a TTY
@@ -192,82 +181,29 @@ function App() {
const [terminalTitleEnabled, setTerminalTitleEnabled] = createSignal(kv.get("terminal_title_enabled", true))
- // Update terminal window title based on current route and session
- // Braille spinner animation frames for when agent is running (space + single character for consistent width with "OC")
- const spinnerFrames = [" ⠋", " ⠙", " ⠹", " ⠸", " ⠼", " ⠴", " ⠦", " ⠧", " ⠇", " ⠏"]
- // Permission request animation frames (flashing triangle with leading space)
- const permissionFrames = [" ◭", " "]
- let spinnerInterval: ReturnType<typeof setInterval> | undefined
- let spinnerIndex = 0
- let currentTitle = ""
- let currentAnimationType: "spinner" | "permission" | undefined
-
- // Cleanup interval on component unmount
- onCleanup(() => {
- if (spinnerInterval) {
- clearInterval(spinnerInterval)
- spinnerInterval = undefined
- }
+ createEffect(() => {
+ console.log(JSON.stringify(route.data))
})
+ // Update terminal window title based on current route and session
createEffect(() => {
if (!terminalTitleEnabled() || Flag.OPENCODE_DISABLE_TERMINAL_TITLE) return
if (route.data.type === "home") {
- if (spinnerInterval) {
- clearInterval(spinnerInterval)
- spinnerInterval = undefined
- currentAnimationType = undefined
- }
renderer.setTerminalTitle("OpenCode")
return
}
if (route.data.type === "session") {
- const sessionID = route.data.sessionID
- const session = sync.session.get(sessionID)
- const status = sync.data.session_status[sessionID]
- const isBusy = status?.type === "busy"
- const permissions = sync.data.permission[sessionID] ?? []
- const hasPermissionRequest = permissions.length > 0
- const hasTitle = session && !SessionApi.isDefaultTitle(session.title)
-
- // Truncate title to 40 chars max, fallback to "OpenCode" if no title yet
- currentTitle = iife(() => {
- if (!hasTitle) return "OpenCode"
- if (session.title.length > 40) return session.title.slice(0, 37) + "..."
- return session.title
- })
-
- // Determine which animation to show (permission takes priority)
- const targetAnimation = hasPermissionRequest ? "permission" : isBusy ? "spinner" : undefined
- const frames = hasPermissionRequest ? permissionFrames : spinnerFrames
-
- if (!targetAnimation) {
- // Stop animation and show static title
- if (spinnerInterval) {
- clearInterval(spinnerInterval)
- spinnerInterval = undefined
- currentAnimationType = undefined
- }
- renderer.setTerminalTitle(hasTitle ? `OC | ${currentTitle}` : "OpenCode")
+ const session = sync.session.get(route.data.sessionID)
+ if (!session || SessionApi.isDefaultTitle(session.title)) {
+ renderer.setTerminalTitle("OpenCode")
return
}
- // Start or switch animation
- if (!spinnerInterval || currentAnimationType !== targetAnimation) {
- if (spinnerInterval) clearInterval(spinnerInterval)
- spinnerIndex = 0
- currentAnimationType = targetAnimation
- renderer.setTerminalTitle(`${frames[spinnerIndex]} | ${currentTitle}`)
- spinnerInterval = setInterval(
- () => {
- spinnerIndex = (spinnerIndex + 1) % frames.length
- renderer.setTerminalTitle(`${frames[spinnerIndex]} | ${currentTitle}`)
- },
- hasPermissionRequest ? 400 : 80,
- )
- }
+ // Truncate title to 40 chars max
+ const title = session.title.length > 40 ? session.title.slice(0, 37) + "..." : session.title
+ renderer.setTerminalTitle(`OC | ${title}`)
}
})
@@ -589,7 +525,7 @@ function App() {
sdk.event.on(SessionApi.Event.Error.type, (evt) => {
const error = evt.properties.error
const message = (() => {
- if (!error) return "An error occurred"
+ if (!error) return "An error occured"
if (typeof error === "object") {
const data = error.data