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
13 changes: 13 additions & 0 deletions packages/opencode/src/cli/cmd/tui/app.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { DialogThemeList } from "@tui/component/dialog-theme-list"
import { DialogHelp } from "./ui/dialog-help"
import { CommandProvider, useCommandDialog } from "@tui/component/dialog-command"
import { DialogAgent } from "@tui/component/dialog-agent"
import { DialogChangeDirectory } from "@tui/component/dialog-change-directory"
import { DialogSessionList } from "@tui/component/dialog-session-list"
import { DialogWorkspaceList } from "@tui/component/dialog-workspace-list"
import { KeybindProvider } from "@tui/context/keybind"
Expand Down Expand Up @@ -372,6 +373,18 @@ function App() {
dialog.replace(() => <DialogSessionList />)
},
},
{
title: "Change directory",
value: "directory.change",
category: "Workspace",
slash: {
name: "changedirectory",
aliases: ["cd"],
},
onSelect: () => {
dialog.replace(() => <DialogChangeDirectory />)
},
},
...(Flag.OPENCODE_EXPERIMENTAL_WORKSPACES
? [
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { useDialog } from "@tui/ui/dialog"
import { DialogPrompt } from "@tui/ui/dialog-prompt"
import { useRoute } from "@tui/context/route"
import { useSync } from "@tui/context/sync"
import { useSDK } from "../context/sdk"

export function DialogChangeDirectory() {
const dialog = useDialog()
const route = useRoute()
const sync = useSync()
const sdk = useSDK()

return (
<DialogPrompt
title="Change Directory"
value={sync.data.path.directory || sdk.directory || "/"}
placeholder="/path/to/project"
onConfirm={(value) => {
const dir = value.trim().replace(/\/+$/g, "") || "/"
dialog.clear()
sdk.setDirectory(dir)
route.navigate({ type: "home" })
void sync.bootstrap()
}}
onCancel={() => dialog.clear()}
/>
)
}
16 changes: 14 additions & 2 deletions packages/opencode/src/cli/cmd/tui/context/sdk.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { batch, onCleanup, onMount } from "solid-js"

export type EventSource = {
on: (handler: (event: Event) => void) => () => void
setDirectory?: (directory: string) => void
setWorkspace?: (workspaceID?: string) => void
}

Expand All @@ -18,14 +19,15 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
events?: EventSource
}) => {
const abort = new AbortController()
let directory = props.directory
let workspaceID: string | undefined
let sse: AbortController | undefined

function createSDK() {
return createOpencodeClient({
baseUrl: props.url,
signal: abort.signal,
directory: props.directory,
directory,
fetch: props.fetch,
headers: props.headers,
experimental_workspaceID: workspaceID,
Expand Down Expand Up @@ -109,9 +111,19 @@ export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
get client() {
return sdk
},
directory: props.directory,
get directory() {
return directory
},
event: emitter,
fetch: props.fetch ?? fetch,
setDirectory(next: string) {
if (directory === next) return
directory = next
workspaceID = undefined
sdk = createSDK()
props.events?.setDirectory?.(next)
if (!props.events) startSSE()
},
setWorkspace(next?: string) {
if (workspaceID === next) return
workspaceID = next
Expand Down
3 changes: 3 additions & 0 deletions packages/opencode/src/cli/cmd/tui/thread.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,9 @@ function createWorkerFetch(client: RpcClient): typeof fetch {
function createEventSource(client: RpcClient): EventSource {
return {
on: (handler) => client.on<Event>("event", handler),
setDirectory: (directory) => {
void client.call("setDirectory", { directory })
},
setWorkspace: (workspaceID) => {
void client.call("setWorkspace", { workspaceID })
},
Expand Down
15 changes: 13 additions & 2 deletions packages/opencode/src/cli/cmd/tui/worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ const eventStream = {
abort: undefined as AbortController | undefined,
}

const state = {
directory: process.cwd(),
workspaceID: undefined as string | undefined,
}

const startEventStream = (input: { directory: string; workspaceID?: string }) => {
if (eventStream.abort) eventStream.abort.abort()
const abort = new AbortController()
Expand Down Expand Up @@ -96,7 +101,7 @@ const startEventStream = (input: { directory: string; workspaceID?: string }) =>
})
}

startEventStream({ directory: process.cwd() })
startEventStream({ directory: state.directory })

export const rpc = {
async fetch(input: { url: string; method: string; headers: Record<string, string>; body?: string }) {
Expand Down Expand Up @@ -136,8 +141,14 @@ export const rpc = {
Config.global.reset()
await Instance.disposeAll()
},
async setDirectory(input: { directory: string }) {
state.directory = input.directory
state.workspaceID = undefined
startEventStream({ directory: state.directory })
},
async setWorkspace(input: { workspaceID?: string }) {
startEventStream({ directory: process.cwd(), workspaceID: input.workspaceID })
state.workspaceID = input.workspaceID
startEventStream({ directory: state.directory, workspaceID: state.workspaceID })
},
async shutdown() {
Log.Default.info("worker shutting down")
Expand Down
Loading