feat(app): improve desktop multi-server support (#30678)

Co-authored-by: Brendan Allan <git@brendonovich.dev>
This commit is contained in:
Luke Parker
2026-06-05 06:30:02 +00:00
committed by GitHub
co-authored by Brendan Allan
parent 7ae856a9e9
commit 7f33576f46
62 changed files with 1523 additions and 841 deletions
@@ -10,6 +10,8 @@ import { useLanguage } from "@/context/language"
import { useSDK } from "@/context/sdk"
import { makeEventListener } from "@solid-primitives/event-listener"
import { createResizeObserver } from "@solid-primitives/resize-observer"
import { useServerSDK } from "@/context/server-sdk"
import { ScopedKey } from "@/utils/server-scope"
const cache = new Map<string, { tab: number; answers: QuestionAnswer[]; custom: string[]; customOn: boolean[] }>()
@@ -60,12 +62,14 @@ function Option(props: {
export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit: () => void }> = (props) => {
const sdk = useSDK()
const serverSDK = useServerSDK()
const language = useLanguage()
const cacheKey = ScopedKey.from(serverSDK.scope, props.request.id)
const questions = createMemo(() => props.request.questions)
const total = createMemo(() => questions().length)
const cached = cache.get(props.request.id)
const cached = cache.get(cacheKey)
const [store, setStore] = createStore({
tab: cached?.tab ?? 0,
answers: cached?.answers ?? ([] as QuestionAnswer[]),
@@ -191,7 +195,7 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit
onCleanup(() => {
if (focusFrame !== undefined) cancelAnimationFrame(focusFrame)
if (replied) return
cache.set(props.request.id, {
cache.set(cacheKey, {
tab: store.tab,
answers: store.answers.map((a) => (a ? [...a] : [])),
custom: store.custom.map((s) => s ?? ""),
@@ -211,7 +215,7 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit
},
onSuccess: () => {
replied = true
cache.delete(props.request.id)
cache.delete(cacheKey)
},
onError: fail,
}))
@@ -223,7 +227,7 @@ export const SessionQuestionDock: Component<{ request: QuestionRequest; onSubmit
},
onSuccess: () => {
replied = true
cache.delete(props.request.id)
cache.delete(cacheKey)
},
onError: fail,
}))
@@ -1,19 +1,25 @@
import { useParams } from "@solidjs/router"
import { createMemo } from "solid-js"
import { useLayout } from "@/context/layout"
import { useServer } from "@/context/server"
import { SessionRouteKey, SessionStateKey } from "@/utils/server-scope"
export const useSessionKey = () => {
const params = useParams()
const sessionKey = createMemo(() => `${params.dir}${params.id ? "/" + params.id : ""}`)
return { params, sessionKey }
const server = useServer()
const scope = createMemo(() => server.scope())
const workspaceKey = createMemo(() => SessionStateKey.from(scope(), SessionRouteKey.fromRoute(params.dir)))
const sessionKey = createMemo(() => SessionStateKey.from(scope(), SessionRouteKey.fromRoute(params.dir, params.id)))
return { params, sessionKey, workspaceKey }
}
export const useSessionLayout = () => {
const layout = useLayout()
const { params, sessionKey } = useSessionKey()
const { params, sessionKey, workspaceKey } = useSessionKey()
return {
params,
sessionKey,
workspaceKey,
tabs: createMemo(() => layout.tabs(sessionKey)),
view: createMemo(() => layout.view(sessionKey)),
}
@@ -26,7 +26,7 @@ export function TerminalPanel() {
const terminal = useTerminal()
const language = useLanguage()
const command = useCommand()
const { params, view } = useSessionLayout()
const { params, workspaceKey, view } = useSessionLayout()
const opened = createMemo(() => view().terminal.opened())
const size = createSizing()
@@ -126,7 +126,7 @@ export function TerminalPanel() {
language.locale()
setTerminalHandoff(
dir,
workspaceKey(),
terminal.all().map((pty) =>
terminalTabLabel({
title: pty.title,
@@ -140,7 +140,7 @@ export function TerminalPanel() {
const handoff = createMemo(() => {
const dir = params.dir
if (!dir) return []
return getTerminalHandoff(dir) ?? []
return getTerminalHandoff(workspaceKey()) ?? []
})
const all = terminal.all