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
20 changes: 10 additions & 10 deletions packages/opencode/src/cli/cmd/tui/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -286,22 +286,22 @@ function App() {
const args = useArgs()
onMount(() => {
batch(() => {
if (args.agent) local.agent.set(args.agent)
if (args.model) {
const { providerID, modelID } = Provider.parseModel(args.model)
if (args.data.agent) local.agent.set(args.data.agent)
if (args.data.model) {
const { providerID, modelID } = Provider.parseModel(args.data.model)
if (!providerID || !modelID)
return toast.show({
variant: "warning",
message: `Invalid model format: ${args.model}`,
message: `Invalid model format: ${args.data.model}`,
duration: 3000,
})
local.model.set({ providerID, modelID }, { recent: true })
}
// Handle --session without --fork immediately (fork is handled in createEffect below)
if (args.sessionID && !args.fork) {
if (args.data.sessionID && !args.data.fork) {
route.navigate({
type: "session",
sessionID: args.sessionID,
sessionID: args.data.sessionID,
})
}
})
Expand All @@ -310,13 +310,13 @@ function App() {
let continued = false
createEffect(() => {
// When using -c, session list is loaded in blocking phase, so we can navigate at "partial"
if (continued || sync.status === "loading" || !args.continue) return
if (continued || sync.status === "loading" || !args.data.continue) return
const match = sync.data.session
.toSorted((a, b) => b.time.updated - a.time.updated)
.find((x) => x.parentID === undefined)?.id
if (match) {
continued = true
if (args.fork) {
if (args.data.fork) {
sdk.client.session.fork({ sessionID: match }).then((result) => {
if (result.data?.id) {
route.navigate({ type: "session", sessionID: result.data.id })
Expand All @@ -335,9 +335,9 @@ function App() {
// to avoid a race where reconcile overwrites the newly forked session)
let forked = false
createEffect(() => {
if (forked || sync.status !== "complete" || !args.sessionID || !args.fork) return
if (forked || sync.status !== "complete" || !args.data.sessionID || !args.data.fork) return
forked = true
sdk.client.session.fork({ sessionID: args.sessionID }).then((result) => {
sdk.client.session.fork({ sessionID: args.data.sessionID }).then((result) => {
if (result.data?.id) {
route.navigate({ type: "session", sessionID: result.data.id })
} else {
Expand Down
24 changes: 23 additions & 1 deletion packages/opencode/src/cli/cmd/tui/context/args.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { createStore } from "solid-js/store"
import { createSimpleContext } from "./helper"

export interface Args {
Expand All @@ -11,5 +12,26 @@ export interface Args {

export const { use: useArgs, provider: ArgsProvider } = createSimpleContext({
name: "Args",
init: (props: Args) => props,
init: (props: Args) => {
const [data, setData] = createStore<Args>({
model: props.model,
agent: props.agent,
prompt: props.prompt,
continue: props.continue,
sessionID: props.sessionID,
fork: props.fork,
})

return {
get data() {
return data
},
consumePrompt() {
const value = data.prompt
if (!value) return
setData("prompt", undefined) // clear the prompt from the args once used
return value
},
}
},
})
4 changes: 2 additions & 2 deletions packages/opencode/src/cli/cmd/tui/context/local.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,8 @@ export const { use: useLocal, provider: LocalProvider } = createSimpleContext({

const args = useArgs()
const fallbackModel = createMemo(() => {
if (args.model) {
const { providerID, modelID } = Provider.parseModel(args.model)
if (args.data.model) {
const { providerID, modelID } = Provider.parseModel(args.data.model)
if (isModelValid({ providerID, modelID })) {
return {
providerID,
Expand Down
8 changes: 4 additions & 4 deletions packages/opencode/src/cli/cmd/tui/context/route.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createStore } from "solid-js/store"
import { createSignal } from "solid-js"
import { createSimpleContext } from "./helper"
import type { PromptInfo } from "../component/prompt/history"

Expand All @@ -18,7 +18,7 @@ export type Route = HomeRoute | SessionRoute
export const { use: useRoute, provider: RouteProvider } = createSimpleContext({
name: "Route",
init: () => {
const [store, setStore] = createStore<Route>(
const [data, setData] = createSignal<Route>(
process.env["OPENCODE_ROUTE"]
? JSON.parse(process.env["OPENCODE_ROUTE"])
: {
Expand All @@ -28,11 +28,11 @@ export const { use: useRoute, provider: RouteProvider } = createSimpleContext({

return {
get data() {
return store
return data()
},
navigate(route: Route) {
console.log("navigate", route)
setStore(route)
setData(route)
},
}
},
Expand Down
8 changes: 5 additions & 3 deletions packages/opencode/src/cli/cmd/tui/context/sync.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
providerListPromise,
agentsPromise,
configPromise,
...(args.continue ? [sessionListPromise] : []),
...(args.data.continue ? [sessionListPromise] : []),
]

await Promise.all(blockingRequests)
Expand All @@ -372,7 +372,7 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
const providerListResponse = providerListPromise.then((x) => x.data!)
const agentsResponse = agentsPromise.then((x) => x.data ?? [])
const configResponse = configPromise.then((x) => x.data!)
const sessionListResponse = args.continue ? sessionListPromise : undefined
const sessionListResponse = args.data.continue ? sessionListPromise : undefined

return Promise.all([
providersResponse,
Expand Down Expand Up @@ -401,7 +401,9 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
if (store.status !== "complete") setStore("status", "partial")
// non-blocking
Promise.all([
...(args.continue ? [] : [sessionListPromise.then((sessions) => setStore("session", reconcile(sessions)))]),
...(args.data.continue
? []
: [sessionListPromise.then((sessions) => setStore("session", reconcile(sessions)))]),
sdk.client.command.list().then((x) => setStore("command", reconcile(x.data ?? []))),
sdk.client.lsp.status().then((x) => setStore("lsp", reconcile(x.data!))),
sdk.client.mcp.status().then((x) => setStore("mcp", reconcile(x.data!))),
Expand Down
11 changes: 3 additions & 8 deletions packages/opencode/src/cli/cmd/tui/routes/home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,6 @@ import { Installation } from "@/installation"
import { useKV } from "../context/kv"
import { useCommandDialog } from "../component/dialog-command"

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

export function Home() {
const sync = useSync()
const kv = useKV()
Expand Down Expand Up @@ -77,13 +74,11 @@ export function Home() {
let prompt: PromptRef
const args = useArgs()
onMount(() => {
if (once) return
const argPrompt = args.consumePrompt()
if (route.initialPrompt) {
prompt.set(route.initialPrompt)
once = true
} else if (args.prompt) {
prompt.set({ input: args.prompt, parts: [] })
once = true
} else if (argPrompt) {
prompt.set({ input: argPrompt, parts: [] })
prompt.submit()
}
})
Expand Down
Loading