Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion packages/opencode/src/cli/cmd/tui/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { TuiEvent } from "./event"
import { KVProvider, useKV } from "./context/kv"
import { Provider } from "@/provider/provider"
import { ArgsProvider, useArgs, type Args } from "./context/args"
import { PromptRefProvider, usePromptRef } from "./context/prompt"

async function getTerminalBackgroundColor(): Promise<"dark" | "light"> {
// can't set raw mode if not a TTY
Expand Down Expand Up @@ -117,7 +118,9 @@ export function tui(input: { url: string; args: Args; onExit?: () => Promise<voi
<DialogProvider>
<CommandProvider>
<PromptHistoryProvider>
<App />
<PromptRefProvider>
<App />
</PromptRefProvider>
</PromptHistoryProvider>
</CommandProvider>
</DialogProvider>
Expand Down Expand Up @@ -158,6 +161,7 @@ function App() {
const { theme, mode, setMode } = useTheme()
const sync = useSync()
const exit = useExit()
const promptRef = usePromptRef()

createEffect(() => {
console.log(JSON.stringify(route.data))
Expand Down Expand Up @@ -212,8 +216,11 @@ function App() {
keybind: "session_new",
category: "Session",
onSelect: () => {
const current = promptRef.current
const currentPrompt = current && current.focused ? current.current : undefined
route.navigate({
type: "home",
initialPrompt: currentPrompt,
})
dialog.clear()
},
Expand Down
4 changes: 4 additions & 0 deletions packages/opencode/src/cli/cmd/tui/component/prompt/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export type PromptProps = {

export type PromptRef = {
focused: boolean
current: PromptInfo
set(prompt: PromptInfo): void
reset(): void
blur(): void
Expand Down Expand Up @@ -361,6 +362,9 @@ export function Prompt(props: PromptProps) {
get focused() {
return input.focused
},
get current() {
return store.prompt
},
focus() {
input.focus()
},
Expand Down
18 changes: 18 additions & 0 deletions packages/opencode/src/cli/cmd/tui/context/prompt.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { createSimpleContext } from "./helper"
import type { PromptRef } from "../component/prompt"

export const { use: usePromptRef, provider: PromptRefProvider } = createSimpleContext({
name: "PromptRef",
init: () => {
let current: PromptRef | undefined

return {
get current() {
return current
},
set(ref: PromptRef | undefined) {
current = ref
},
}
},
})
2 changes: 2 additions & 0 deletions packages/opencode/src/cli/cmd/tui/context/route.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { createStore } from "solid-js/store"
import { createSimpleContext } from "./helper"
import type { PromptInfo } from "../component/prompt/history"

export type HomeRoute = {
type: "home"
initialPrompt?: PromptInfo
}

export type SessionRoute = {
Expand Down
12 changes: 7 additions & 5 deletions packages/opencode/src/cli/cmd/tui/routes/home.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,21 @@
import { Prompt, type PromptRef } from "@tui/component/prompt"
import { createMemo, Match, onMount, Show, Switch, type ParentProps } from "solid-js"
import { createMemo, Match, onMount, Show, Switch } from "solid-js"
import { useTheme } from "@tui/context/theme"
import { useKeybind } from "../context/keybind"
import type { KeybindsConfig } from "@opencode-ai/sdk"
import { Logo } from "../component/logo"
import { Locale } from "@/util/locale"
import { useSync } from "../context/sync"
import { Toast } from "../ui/toast"
import { useArgs } from "../context/args"
import { Global } from "@/global"
import { useDirectory } from "../context/directory"
import { useRoute, useRouteData } from "@tui/context/route"

// TODO: what is the best way to do this?
let once = false

export function Home() {
const sync = useSync()
const { theme } = useTheme()
const route = useRouteData("home")
const mcp = createMemo(() => Object.keys(sync.data.mcp).length > 0)
const mcpError = createMemo(() => {
return Object.values(sync.data.mcp).some((x) => x.status === "failed")
Expand Down Expand Up @@ -45,7 +44,10 @@ export function Home() {
const args = useArgs()
onMount(() => {
if (once) return
if (args.prompt) {
if (route.initialPrompt) {
prompt.set(route.initialPrompt)
once = true
} else if (args.prompt) {
prompt.set({ input: args.prompt, parts: [] })
once = true
}
Expand Down