summaryrefslogtreecommitdiffhomepage
path: root/packages/desktop/src
diff options
context:
space:
mode:
authorAdam <[email protected]>2025-12-05 10:30:44 -0600
committerAdam <[email protected]>2025-12-05 10:30:48 -0600
commitcfbaf81ef8f360d1df621d800d10b0ac2b3019a8 (patch)
tree424961841d111017d38714010158e270bd688a18 /packages/desktop/src
parent87a791fdb9432d457202da85ec5e23e42f91db4d (diff)
downloadopencode-cfbaf81ef8f360d1df621d800d10b0ac2b3019a8.tar.gz
opencode-cfbaf81ef8f360d1df621d800d10b0ac2b3019a8.zip
fix(desktop): clone pty session on reconnect
Diffstat (limited to 'packages/desktop/src')
-rw-r--r--packages/desktop/src/components/terminal.tsx9
-rw-r--r--packages/desktop/src/context/session.tsx5
-rw-r--r--packages/desktop/src/pages/session.tsx10
3 files changed, 18 insertions, 6 deletions
diff --git a/packages/desktop/src/components/terminal.tsx b/packages/desktop/src/components/terminal.tsx
index 49a45a432..f7b44b0aa 100644
--- a/packages/desktop/src/components/terminal.tsx
+++ b/packages/desktop/src/components/terminal.tsx
@@ -1,6 +1,5 @@
import { init, Terminal as Term, FitAddon } from "ghostty-web"
import { ComponentProps, onCleanup, onMount, splitProps } from "solid-js"
-import { createReconnectingWS, ReconnectingWebSocket } from "@solid-primitives/websocket"
import { useSDK } from "@/context/sdk"
import { SerializeAddon } from "@/addons/serialize"
import { LocalPTY } from "@/context/session"
@@ -11,19 +10,20 @@ export interface TerminalProps extends ComponentProps<"div"> {
pty: LocalPTY
onSubmit?: () => void
onCleanup?: (pty: LocalPTY) => void
+ onConnectError?: (error: unknown) => void
}
export const Terminal = (props: TerminalProps) => {
const sdk = useSDK()
let container!: HTMLDivElement
- const [local, others] = splitProps(props, ["pty", "class", "classList"])
- let ws: ReconnectingWebSocket
+ const [local, others] = splitProps(props, ["pty", "class", "classList", "onConnectError"])
+ let ws: WebSocket
let term: Term
let serializeAddon: SerializeAddon
let fitAddon: FitAddon
onMount(async () => {
- ws = createReconnectingWS(sdk.url + `/pty/${local.pty.id}/connect?directory=${encodeURIComponent(sdk.directory)}`)
+ ws = new WebSocket(sdk.url + `/pty/${local.pty.id}/connect?directory=${encodeURIComponent(sdk.directory)}`)
term = new Term({
cursorBlink: true,
fontSize: 14,
@@ -115,6 +115,7 @@ export const Terminal = (props: TerminalProps) => {
})
ws.addEventListener("error", (error) => {
console.error("WebSocket error:", error)
+ props.onConnectError?.(error)
})
ws.addEventListener("close", () => {
console.log("WebSocket disconnected")
diff --git a/packages/desktop/src/context/session.tsx b/packages/desktop/src/context/session.tsx
index 690653992..b5972f3e3 100644
--- a/packages/desktop/src/context/session.tsx
+++ b/packages/desktop/src/context/session.tsx
@@ -26,7 +26,7 @@ export const { use: useSession, provider: SessionProvider } = createSimpleContex
const params = useParams()
const sync = useSync()
const name = createMemo(
- () => `______${base64Encode(sync.data.project.worktree)}/session${params.id ? "/" + params.id : ""}`,
+ () => `${base64Encode(sync.data.project.worktree)}/session${params.id ? "/" + params.id : ""}.v1`,
)
const [store, setStore] = makePersisted(
@@ -232,6 +232,9 @@ export const { use: useSession, provider: SessionProvider } = createSimpleContex
...pty,
...clone.data,
})
+ if (store.terminals.active === pty.id) {
+ setStore("terminals", "active", clone.data.id)
+ }
},
open(id: string) {
setStore("terminals", "active", id)
diff --git a/packages/desktop/src/pages/session.tsx b/packages/desktop/src/pages/session.tsx
index 773625334..8cd9e9d65 100644
--- a/packages/desktop/src/pages/session.tsx
+++ b/packages/desktop/src/pages/session.tsx
@@ -84,6 +84,10 @@ export default function Page() {
}
if (event.ctrlKey && event.key.toLowerCase() === "`") {
event.preventDefault()
+ if (event.shiftKey) {
+ session.terminal.new()
+ return
+ }
layout.terminal.toggle()
return
}
@@ -663,7 +667,11 @@ export default function Page() {
<For each={session.terminal.all()}>
{(terminal) => (
<Tabs.Content value={terminal.id}>
- <Terminal pty={terminal} onCleanup={session.terminal.update} />
+ <Terminal
+ pty={terminal}
+ onCleanup={session.terminal.update}
+ onConnectError={() => session.terminal.clone(terminal.id)}
+ />
</Tabs.Content>
)}
</For>