refactor(app): rename global context files to server context files

This commit is contained in:
Brendan Allan 2026-05-22 15:11:41 +08:00
parent 76d9c2cd76
commit bf8fcc07fa
No known key found for this signature in database
GPG key ID: 41E835AEA046A32E
53 changed files with 332 additions and 332 deletions

View file

@ -30,8 +30,8 @@ import { Dynamic } from "solid-js/web"
import { CommandProvider } from "@/context/command"
import { CommentsProvider } from "@/context/comments"
import { FileProvider } from "@/context/file"
import { GlobalSDKProvider } from "@/context/global-sdk"
import { GlobalSyncProvider } from "@/context/global-sync"
import { ServerSDKProvider } from "@/context/server-sdk"
import { ServerSyncProvider } from "@/context/server-sync"
import { HighlightsProvider } from "@/context/highlights"
import { LanguageProvider, type Locale, useLanguage } from "@/context/language"
import { LayoutProvider } from "@/context/layout"
@ -304,8 +304,8 @@ export function AppInterface(props: {
<ConnectionGate disableHealthCheck={props.disableHealthCheck}>
<ServerKey>
<QueryProvider>
<GlobalSDKProvider>
<GlobalSyncProvider>
<ServerSDKProvider>
<ServerSyncProvider>
<Dynamic
component={props.router ?? Router}
root={(routerProps) => <RouterRoot appChildren={props.children}>{routerProps.children}</RouterRoot>}
@ -316,8 +316,8 @@ export function AppInterface(props: {
<Route path="/session/:id?" component={SessionRoute} />
</Route>
</Dynamic>
</GlobalSyncProvider>
</GlobalSDKProvider>
</ServerSyncProvider>
</ServerSDKProvider>
</QueryProvider>
</ServerKey>
</ConnectionGate>

View file

@ -12,15 +12,15 @@ import { showToast } from "@opencode-ai/ui/toast"
import { createEffect, createMemo, createResource, Match, onCleanup, onMount, Switch } from "solid-js"
import { createStore, produce } from "solid-js/store"
import { Link } from "@/components/link"
import { useGlobalSDK } from "@/context/global-sdk"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSDK } from "@/context/server-sdk"
import { useServerSync } from "@/context/server-sync"
import { useLanguage } from "@/context/language"
import { useProviders } from "@/hooks/use-providers"
export function DialogConnectProvider(props: { provider: string }) {
const dialog = useDialog()
const globalSync = useGlobalSync()
const globalSDK = useGlobalSDK()
const serverSync = useServerSync()
const serverSDK = useServerSDK()
const language = useLanguage()
const providers = useProviders()
@ -41,7 +41,7 @@ export function DialogConnectProvider(props: { provider: string }) {
})
const provider = createMemo(
() => providers.all().get(props.provider) ?? globalSync.data.provider.all.get(props.provider)!,
() => providers.all().get(props.provider) ?? serverSync.data.provider.all.get(props.provider)!,
)
const fallback = createMemo<ProviderAuthMethod[]>(() => [
{
@ -52,16 +52,16 @@ export function DialogConnectProvider(props: { provider: string }) {
const [auth] = createResource(
() => props.provider,
async () => {
const cached = globalSync.data.provider_auth[props.provider]
const cached = serverSync.data.provider_auth[props.provider]
if (cached) return cached
const res = await globalSDK.client.provider.auth()
const res = await serverSDK.client.provider.auth()
if (!alive.value) return fallback()
globalSync.set("provider_auth", res.data ?? {})
serverSync.set("provider_auth", res.data ?? {})
return res.data?.[props.provider] ?? fallback()
},
)
const loading = createMemo(() => auth.loading && !globalSync.data.provider_auth[props.provider])
const methods = createMemo(() => auth.latest ?? globalSync.data.provider_auth[props.provider] ?? fallback())
const loading = createMemo(() => auth.loading && !serverSync.data.provider_auth[props.provider])
const methods = createMemo(() => auth.latest ?? serverSync.data.provider_auth[props.provider] ?? fallback())
const [store, setStore] = createStore({
methodIndex: undefined as undefined | number,
authorization: undefined as undefined | ProviderAuthAuthorization,
@ -158,7 +158,7 @@ export function DialogConnectProvider(props: { provider: string }) {
}
dispatch({ type: "auth.pending" })
const start = Date.now()
await globalSDK.client.provider.oauth
await serverSDK.client.provider.oauth
.authorize(
{
providerID: props.provider,
@ -330,7 +330,7 @@ export function DialogConnectProvider(props: { provider: string }) {
})
async function complete() {
await globalSDK.client.global.dispose()
await serverSDK.client.global.dispose()
dialog.close()
showToast({
variant: "success",
@ -407,7 +407,7 @@ export function DialogConnectProvider(props: { provider: string }) {
}
setFormStore("error", undefined)
await globalSDK.client.auth.set({
await serverSDK.client.auth.set({
providerID: props.provider,
auth: {
type: "api",
@ -478,7 +478,7 @@ export function DialogConnectProvider(props: { provider: string }) {
}
setFormStore("error", undefined)
const result = await globalSDK.client.provider.oauth
const result = await serverSDK.client.provider.oauth
.callback({
providerID: props.provider,
method: store.methodIndex,
@ -531,7 +531,7 @@ export function DialogConnectProvider(props: { provider: string }) {
onMount(() => {
void (async () => {
const result = await globalSDK.client.provider.oauth
const result = await serverSDK.client.provider.oauth
.callback({
providerID: props.provider,
method: store.methodIndex,

View file

@ -9,8 +9,8 @@ import { showToast } from "@opencode-ai/ui/toast"
import { batch, For } from "solid-js"
import { createStore, produce } from "solid-js/store"
import { Link } from "@/components/link"
import { useGlobalSDK } from "@/context/global-sdk"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSDK } from "@/context/server-sdk"
import { useServerSync } from "@/context/server-sync"
import { useLanguage } from "@/context/language"
import { type FormState, headerRow, modelRow, validateCustomProvider } from "./dialog-custom-provider-form"
import { DialogSelectProvider } from "./dialog-select-provider"
@ -21,8 +21,8 @@ type Props = {
export function DialogCustomProvider(props: Props) {
const dialog = useDialog()
const globalSync = useGlobalSync()
const globalSDK = useGlobalSDK()
const serverSync = useServerSync()
const serverSDK = useServerSDK()
const language = useLanguage()
const [form, setForm] = createStore<FormState>({
@ -105,8 +105,8 @@ export function DialogCustomProvider(props: Props) {
const output = validateCustomProvider({
form,
t: language.t,
disabledProviders: globalSync.data.config.disabled_providers ?? [],
existingProviderIDs: new Set(globalSync.data.provider.all.keys()),
disabledProviders: serverSync.data.config.disabled_providers ?? [],
existingProviderIDs: new Set(serverSync.data.provider.all.keys()),
})
batch(() => {
setForm("err", output.err)
@ -118,11 +118,11 @@ export function DialogCustomProvider(props: Props) {
const saveMutation = useMutation(() => ({
mutationFn: async (result: NonNullable<ReturnType<typeof validate>>) => {
const disabledProviders = globalSync.data.config.disabled_providers ?? []
const disabledProviders = serverSync.data.config.disabled_providers ?? []
const nextDisabled = disabledProviders.filter((id) => id !== result.providerID)
if (result.key) {
await globalSDK.client.auth.set({
await serverSDK.client.auth.set({
providerID: result.providerID,
auth: {
type: "api",
@ -131,7 +131,7 @@ export function DialogCustomProvider(props: Props) {
})
}
await globalSync.updateConfig({
await serverSync.updateConfig({
provider: { [result.providerID]: result.config },
disabled_providers: nextDisabled,
})

View file

@ -6,8 +6,8 @@ import { useMutation } from "@tanstack/solid-query"
import { Icon } from "@opencode-ai/ui/icon"
import { createMemo, For, Show } from "solid-js"
import { createStore } from "solid-js/store"
import { useGlobalSDK } from "@/context/global-sdk"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSDK } from "@/context/server-sdk"
import { useServerSync } from "@/context/server-sync"
import { type LocalProject, getAvatarColors } from "@/context/layout"
import { getFilename } from "@opencode-ai/core/util/path"
import { Avatar } from "@opencode-ai/ui/avatar"
@ -18,8 +18,8 @@ const AVATAR_COLOR_KEYS = ["pink", "mint", "orange", "purple", "cyan", "lime"] a
export function DialogEditProject(props: { project: LocalProject }) {
const dialog = useDialog()
const globalSDK = useGlobalSDK()
const globalSync = useGlobalSync()
const serverSDK = useServerSDK()
const serverSync = useServerSync()
const language = useLanguage()
const folderName = createMemo(() => getFilename(props.project.worktree))
@ -78,19 +78,19 @@ export function DialogEditProject(props: { project: LocalProject }) {
const start = store.startup.trim()
if (props.project.id && props.project.id !== "global") {
await globalSDK.client.project.update({
await serverSDK.client.project.update({
projectID: props.project.id,
directory: props.project.worktree,
name,
icon: { color: store.color || "", override: store.iconOverride || "" },
commands: { start },
})
globalSync.project.icon(props.project.worktree, store.iconOverride || undefined)
serverSync.project.icon(props.project.worktree, store.iconOverride || undefined)
dialog.close()
return
}
globalSync.project.meta(props.project.worktree, {
serverSync.project.meta(props.project.worktree, {
name,
icon: { color: store.color || undefined, override: store.iconOverride || undefined },
commands: { start: start || undefined },

View file

@ -6,8 +6,8 @@ import type { ListRef } from "@opencode-ai/ui/list"
import { getDirectory, getFilename } from "@opencode-ai/core/util/path"
import fuzzysort from "fuzzysort"
import { createMemo, createResource, createSignal } from "solid-js"
import { useGlobalSDK } from "@/context/global-sdk"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSDK } from "@/context/server-sdk"
import { useServerSync } from "@/context/server-sync"
import { useLayout } from "@/context/layout"
import { useLanguage } from "@/context/language"
@ -128,7 +128,7 @@ function uniqueRows(rows: Row[]) {
}
function useDirectorySearch(args: {
sdk: ReturnType<typeof useGlobalSDK>
sdk: ReturnType<typeof useServerSDK>
start: () => string | undefined
home: () => string
}) {
@ -246,8 +246,8 @@ function useDirectorySearch(args: {
}
export function DialogSelectDirectory(props: DialogSelectDirectoryProps) {
const sync = useGlobalSync()
const sdk = useGlobalSDK()
const sync = useServerSync()
const sdk = useServerSDK()
const layout = useLayout()
const dialog = useDialog()
const language = useLanguage()

View file

@ -9,8 +9,8 @@ import { getDirectory, getFilename } from "@opencode-ai/core/util/path"
import { useNavigate } from "@solidjs/router"
import { createMemo, createSignal, Match, onCleanup, Show, Switch } from "solid-js"
import { formatKeybind, useCommand, type CommandOption } from "@/context/command"
import { useGlobalSDK } from "@/context/global-sdk"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSDK } from "@/context/server-sdk"
import { useServerSync } from "@/context/server-sync"
import { useLayout } from "@/context/layout"
import { useFile } from "@/context/file"
import { useLanguage } from "@/context/language"
@ -175,7 +175,7 @@ function createFileEntries(props: {
function createSessionEntries(props: {
workspaces: () => string[]
label: (directory: string) => string
globalSDK: ReturnType<typeof useGlobalSDK>
serverSDK: ReturnType<typeof useServerSDK>
language: ReturnType<typeof useLanguage>
}) {
const state: {
@ -207,7 +207,7 @@ function createSessionEntries(props: {
state.inflight = Promise.all(
dirs.map((directory) => {
const description = props.label(directory)
return props.globalSDK.client.session
return props.serverSDK.client.session
.list({ directory, roots: true })
.then((x) =>
(x.data ?? [])
@ -268,8 +268,8 @@ export function DialogSelectFile(props: { mode?: DialogSelectFileMode; onOpenFil
const file = useFile()
const dialog = useDialog()
const navigate = useNavigate()
const globalSDK = useGlobalSDK()
const globalSync = useGlobalSync()
const serverSDK = useServerSDK()
const serverSync = useServerSync()
const { params, tabs, view } = useSessionLayout()
const filesOnly = () => props.mode === "files"
const state = { cleanup: undefined as (() => void) | void, committed: false }
@ -292,21 +292,21 @@ export function DialogSelectFile(props: { mode?: DialogSelectFileMode; onOpenFil
if (directory && !dirs.includes(directory)) return [...dirs, directory]
return dirs
})
const homedir = createMemo(() => globalSync.data.path.home)
const homedir = createMemo(() => serverSync.data.path.home)
const label = (directory: string) => {
const current = project()
const kind =
current && directory === current.worktree
? language.t("workspace.type.local")
: language.t("workspace.type.sandbox")
const [store] = globalSync.child(directory, { bootstrap: false })
const [store] = serverSync.child(directory, { bootstrap: false })
const home = homedir()
const path = home ? directory.replace(home, "~") : directory
const name = store.vcs?.branch ?? getFilename(directory)
return `${kind} : ${name || path}`
}
const { sessions } = createSessionEntries({ workspaces, label, globalSDK, language })
const { sessions } = createSessionEntries({ workspaces, label, serverSDK, language })
const items = async (text: string) => {
const query = text.trim()

View file

@ -6,7 +6,7 @@ import { Dialog } from "@opencode-ai/ui/dialog"
import { List } from "@opencode-ai/ui/list"
import { Switch } from "@opencode-ai/ui/switch"
import { useLanguage } from "@/context/language"
import { useQueryOptions } from "@/context/global-sync"
import { useQueryOptions } from "@/context/server-sync"
import { pathKey } from "@/utils/path-key"
const statusLabels = {

View file

@ -66,7 +66,7 @@ import { PromptDragOverlay } from "./prompt-input/drag-overlay"
import { promptPlaceholder } from "./prompt-input/placeholder"
import { ImagePreview } from "@opencode-ai/ui/image-preview"
import { useQueries } from "@tanstack/solid-query"
import { useQueryOptions } from "@/context/global-sync"
import { useQueryOptions } from "@/context/server-sync"
import { pathKey } from "@/utils/path-key"
import { getFilename } from "@opencode-ai/core/util/path"

View file

@ -163,7 +163,7 @@ beforeAll(async () => {
}))
mock.module("@/context/global-sync", () => ({
useGlobalSync: () => ({
useServerSync: () => ({
child: (directory: string) => {
syncedDirectories.push(directory)
storedSessions[directory] ??= []

View file

@ -5,7 +5,7 @@ import { Binary } from "@opencode-ai/core/util/binary"
import { useNavigate, useParams } from "@solidjs/router"
import { batch, type Accessor } from "solid-js"
import type { FileSelection } from "@/context/file"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSync } from "@/context/server-sync"
import { useLanguage } from "@/context/language"
import { useLayout } from "@/context/layout"
import { useLocal } from "@/context/local"
@ -38,7 +38,7 @@ export type FollowupDraft = {
type FollowupSendInput = {
client: ReturnType<typeof useSDK>["client"]
globalSync: ReturnType<typeof useGlobalSync>
serverSync: ReturnType<typeof useServerSync>
sync: ReturnType<typeof useSync>
draft: FollowupDraft
messageID?: string
@ -53,7 +53,7 @@ const draftImages = (prompt: Prompt) => prompt.filter((part): part is ImageAttac
export async function sendFollowupDraft(input: FollowupSendInput) {
const text = draftText(input.draft.prompt)
const images = draftImages(input.draft.prompt)
const [, setStore] = input.globalSync.child(input.draft.sessionDirectory)
const [, setStore] = input.serverSync.child(input.draft.sessionDirectory)
const setBusy = () => {
if (!input.optimisticBusy) return
@ -205,7 +205,7 @@ export function createPromptSubmit(input: PromptSubmitInput) {
const navigate = useNavigate()
const sdk = useSDK()
const sync = useSync()
const globalSync = useGlobalSync()
const serverSync = useServerSync()
const local = useLocal()
const permission = usePermission()
const prompt = usePrompt()
@ -226,8 +226,8 @@ export function createPromptSubmit(input: PromptSubmitInput) {
const sessionID = params.id
if (!sessionID) return Promise.resolve()
globalSync.todo.set(sessionID, [])
const [, setStore] = globalSync.child(sdk.directory)
serverSync.todo.set(sessionID, [])
const [, setStore] = serverSync.child(sdk.directory)
setStore("todo", sessionID, [])
input.onAbort?.()
@ -273,7 +273,7 @@ export function createPromptSubmit(input: PromptSubmitInput) {
}
const seed = (dir: string, info: Session) => {
const [, setStore] = globalSync.child(dir)
const [, setStore] = serverSync.child(dir)
setStore("session", (list: Session[]) => {
const result = Binary.search(list, info.id, (item) => item.id)
const next = [...list]
@ -354,7 +354,7 @@ export function createPromptSubmit(input: PromptSubmitInput) {
directory: sessionDirectory,
throwOnError: true,
})
globalSync.child(sessionDirectory)
serverSync.child(sessionDirectory)
}
input.onNewSessionWorktreeReset?.()
@ -557,7 +557,7 @@ export function createPromptSubmit(input: PromptSubmitInput) {
void sendFollowupDraft({
client,
sync,
globalSync,
serverSync,
draft,
messageID,
optimisticBusy: sessionDirectory === projectDirectory,

View file

@ -1,7 +1,7 @@
import type { JSX } from "solid-js"
import { createMemo } from "solid-js"
import { useNavigate } from "@solidjs/router"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSync } from "@/context/server-sync"
import { useLayout } from "@/context/layout"
import { useSDK } from "@/context/sdk"
import { useServer } from "@/context/server"
@ -15,7 +15,7 @@ import { WordmarkV2 } from "@opencode-ai/ui/v2/components/wordmark-v2.jsx"
const MAIN_WORKTREE = "main"
export function NewSessionDesignView(props: { worktree: string; children: JSX.Element }) {
const globalSync = useGlobalSync()
const serverSync = useServerSync()
const layout = useLayout()
const navigate = useNavigate()
const sdk = useSDK()
@ -24,7 +24,7 @@ export function NewSessionDesignView(props: { worktree: string; children: JSX.El
const projectRoot = createMemo(() => sync.project?.worktree ?? sdk.directory)
const projects = createMemo(() => {
const roots = globalSync.data.project.map((project) => project.worktree)
const roots = serverSync.data.project.map((project) => project.worktree)
if (roots.includes(projectRoot())) return roots
return [projectRoot(), ...roots]
})

View file

@ -12,8 +12,8 @@ import { useParams } from "@solidjs/router"
import { useLanguage } from "@/context/language"
import { usePermission } from "@/context/permission"
import { usePlatform, type DisplayBackend } from "@/context/platform"
import { useGlobalSync } from "@/context/global-sync"
import { useGlobalSDK } from "@/context/global-sdk"
import { useServerSync } from "@/context/server-sync"
import { useServerSDK } from "@/context/server-sdk"
import {
monoDefault,
monoFontFamily,
@ -175,8 +175,8 @@ export const SettingsGeneral: Component = () => {
const themeOptions = createMemo<ThemeOption[]>(() => theme.ids().map((id) => ({ id, name: theme.name(id) })))
const globalSync = useGlobalSync()
const globalSdk = useGlobalSDK()
const serverSync = useServerSync()
const globalSdk = useServerSDK()
const [shells] = createResource(
() =>
@ -204,11 +204,11 @@ export const SettingsGeneral: Component = () => {
})
const autoOption = { id: "auto", value: "", label: language.t("settings.general.row.shell.autoDefault") }
const currentShell = createMemo(() => globalSync.data.config.shell ?? "")
const currentShell = createMemo(() => serverSync.data.config.shell ?? "")
const shellOptions = createMemo<ShellSelectOption[]>(() => {
const list = shells.latest
const current = globalSync.data.config.shell
const current = serverSync.data.config.shell
const nameCounts = new Map<string, number>()
for (const s of list) {
@ -343,7 +343,7 @@ export const SettingsGeneral: Component = () => {
onSelect={(option) => {
if (!option) return
if (option.value === currentShell()) return
globalSync.updateConfig({ shell: option.value })
serverSync.updateConfig({ shell: option.value })
}}
variant="secondary"
size="small"

View file

@ -6,8 +6,8 @@ import { showToast } from "@opencode-ai/ui/toast"
import { popularProviders, useProviders } from "@/hooks/use-providers"
import { createMemo, type Component, For, Show } from "solid-js"
import { useLanguage } from "@/context/language"
import { useGlobalSDK } from "@/context/global-sdk"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSDK } from "@/context/server-sdk"
import { useServerSync } from "@/context/server-sync"
import { DialogConnectProvider } from "./dialog-connect-provider"
import { DialogSelectProvider } from "./dialog-select-provider"
import { DialogCustomProvider } from "./dialog-custom-provider"
@ -30,8 +30,8 @@ const PROVIDER_NOTES = [
export const SettingsProviders: Component = () => {
const dialog = useDialog()
const language = useLanguage()
const globalSDK = useGlobalSDK()
const globalSync = useGlobalSync()
const serverSDK = useServerSDK()
const serverSync = useServerSync()
const providers = useProviders()
const connected = createMemo(() => {
@ -74,7 +74,7 @@ export const SettingsProviders: Component = () => {
const note = (id: string) => PROVIDER_NOTES.find((item) => item.match(id))?.key
const isConfigCustom = (providerID: string) => {
const provider = globalSync.data.config.provider?.[providerID]
const provider = serverSync.data.config.provider?.[providerID]
if (!provider) return false
if (provider.npm !== "@ai-sdk/openai-compatible") return false
if (!provider.models || Object.keys(provider.models).length === 0) return false
@ -82,11 +82,11 @@ export const SettingsProviders: Component = () => {
}
const disableProvider = async (providerID: string, name: string) => {
const before = globalSync.data.config.disabled_providers ?? []
const before = serverSync.data.config.disabled_providers ?? []
const next = before.includes(providerID) ? before : [...before, providerID]
globalSync.set("config", "disabled_providers", next)
serverSync.set("config", "disabled_providers", next)
await globalSync
await serverSync
.updateConfig({ disabled_providers: next })
.then(() => {
showToast({
@ -97,7 +97,7 @@ export const SettingsProviders: Component = () => {
})
})
.catch((err: unknown) => {
globalSync.set("config", "disabled_providers", before)
serverSync.set("config", "disabled_providers", before)
const message = err instanceof Error ? err.message : String(err)
showToast({ title: language.t("common.requestFailed"), description: message })
})
@ -105,14 +105,14 @@ export const SettingsProviders: Component = () => {
const disconnect = async (providerID: string, name: string) => {
if (isConfigCustom(providerID)) {
await globalSDK.client.auth.remove({ providerID }).catch(() => undefined)
await serverSDK.client.auth.remove({ providerID }).catch(() => undefined)
await disableProvider(providerID, name)
return
}
await globalSDK.client.auth
await serverSDK.client.auth
.remove({ providerID })
.then(async () => {
await globalSDK.client.global.dispose()
await serverSDK.client.global.dispose()
showToast({
variant: "success",
icon: "circle-check",

View file

@ -15,7 +15,7 @@ import { useSDK } from "@/context/sdk"
import { normalizeServerUrl, ServerConnection, useServer } from "@/context/server"
import { useSync } from "@/context/sync"
import { useCheckServerHealth, type ServerHealth } from "@/utils/server-health"
import { useQueryOptions } from "@/context/global-sync"
import { useQueryOptions } from "@/context/server-sync"
import { pathKey } from "@/utils/path-key"
const pollMs = 10_000

View file

@ -16,7 +16,7 @@ import { useLanguage } from "@/context/language"
import { useSettings } from "@/context/settings"
import { WindowsAppMenu } from "./windows-app-menu"
import { applyPath, backPath, forwardPath } from "./titlebar-history"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSync } from "@/context/server-sync"
import { decodeDirectory } from "@/pages/directory-layout"
import { iife } from "@opencode-ai/core/util/iife"
import { base64Encode } from "@opencode-ai/core/util/encode"
@ -221,7 +221,7 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
<Switch>
<Match when={USE_V2_TITLEBAR}>
{(_) => {
const globalSync = useGlobalSync()
const serverSync = useServerSync()
const navigate = useNavigate()
const homeMatch = useMatch(() => "/")
@ -391,7 +391,7 @@ export function Titlebar(props: { update?: TitlebarUpdate }) {
const base = mapArray(
() => tabsStore,
(tab) => {
const sync = globalSync.createDirSyncContext(tab.dir)
const sync = serverSync.createDirSyncContext(tab.dir)
const session = sync.session.get(tab.sessionId)
return session ? { ...tab, info: session } : null
},

View file

@ -8,7 +8,7 @@ import {
getSessionPrefetchPromise,
setSessionPrefetch,
} from "./global-sync/session-prefetch"
import { useGlobalSync } from "./global-sync"
import { useServerSync } from "./server-sync"
import type { Message, OpencodeClient, Part } from "@opencode-ai/sdk/v2/client"
import { SESSION_CACHE_LIMIT, dropSessionCaches, pickSessionCacheEvictions } from "./global-sync/session-cache"
import { diffs as list, message as clean } from "@/utils/diffs"
@ -165,15 +165,15 @@ function setOptimisticRemove(setStore: (...args: unknown[]) => void, input: Opti
}
export const createDirSyncContext = (client: OpencodeClient, directory: string) => {
const globalSync = useGlobalSync()
const serverSync = useServerSync()
type Child = ReturnType<(typeof globalSync)["child"]>
type Child = ReturnType<(typeof serverSync)["child"]>
type Setter = Child[1]
const current = createMemo(() => globalSync.child(directory))
const current = createMemo(() => serverSync.child(directory))
const target = (directory?: string) => {
if (!directory || directory === directory) return current()
return globalSync.child(directory)
return serverSync.child(directory)
}
const absolute = (path: string) => (current()[0].path.directory + "/" + path).replace("//", "/")
const initialMessagePageSize = 80
@ -239,7 +239,7 @@ export const createDirSyncContext = (client: OpencodeClient, directory: string)
if (!first) break
const stale = [...(seen.get(first) ?? [])]
seen.delete(first)
const [, setStore] = globalSync.child(first, { bootstrap: false })
const [, setStore] = serverSync.child(first, { bootstrap: false })
evict(first, setStore, stale)
}
return created
@ -267,7 +267,7 @@ export const createDirSyncContext = (client: OpencodeClient, directory: string)
if (sessionIDs.length === 0) return
clearSessionPrefetch(directory, sessionIDs)
for (const sessionID of sessionIDs) {
globalSync.todo.set(sessionID, undefined)
serverSync.todo.set(sessionID, undefined)
}
setStore(
produce((draft) => {
@ -324,7 +324,7 @@ export const createDirSyncContext = (client: OpencodeClient, directory: string)
for (const messageID of next.confirmed) {
clearOptimistic(input.directory, input.sessionID, messageID)
}
const [store] = globalSync.child(input.directory, { bootstrap: false })
const [store] = serverSync.child(input.directory, { bootstrap: false })
const cached = input.mode === "prepend" ? (store.message[input.sessionID] ?? []) : []
const message = input.mode === "prepend" ? merge(cached, next.session) : next.session
batch(() => {
@ -373,8 +373,8 @@ export const createDirSyncContext = (client: OpencodeClient, directory: string)
},
get project() {
const store = current()[0]
const match = Binary.search(globalSync.data.project, store.project, (p) => p.id)
if (match.found) return globalSync.data.project[match.index]
const match = Binary.search(serverSync.data.project, store.project, (p) => p.id)
if (match.found) return serverSync.data.project[match.index]
return undefined
},
session: {
@ -418,7 +418,7 @@ export const createDirSyncContext = (client: OpencodeClient, directory: string)
})
},
async sync(sessionID: string, opts?: { force?: boolean }) {
const [store, setStore] = globalSync.child(directory)
const [store, setStore] = serverSync.child(directory)
const key = keyFor(directory, sessionID)
touch(directory, setStore, sessionID)
@ -488,7 +488,7 @@ export const createDirSyncContext = (client: OpencodeClient, directory: string)
})
},
async diff(sessionID: string, opts?: { force?: boolean }) {
const [store, setStore] = globalSync.child(directory)
const [store, setStore] = serverSync.child(directory)
touch(directory, setStore, sessionID)
if (store.session_diff[sessionID] !== undefined && !opts?.force) return
@ -501,13 +501,13 @@ export const createDirSyncContext = (client: OpencodeClient, directory: string)
)
},
async todo(sessionID: string, opts?: { force?: boolean }) {
const [store, setStore] = globalSync.child(directory)
const [store, setStore] = serverSync.child(directory)
touch(directory, setStore, sessionID)
const existing = store.todo[sessionID]
const cached = globalSync.data.session_todo[sessionID]
const cached = serverSync.data.session_todo[sessionID]
if (existing !== undefined) {
if (cached === undefined) {
globalSync.todo.set(sessionID, existing)
serverSync.todo.set(sessionID, existing)
}
if (!opts?.force) return
}
@ -522,7 +522,7 @@ export const createDirSyncContext = (client: OpencodeClient, directory: string)
if (!tracked(directory, sessionID)) return
const list = todo.data ?? []
setStore("todo", sessionID, reconcile(list, { key: "id" }))
globalSync.todo.set(sessionID, list)
serverSync.todo.set(sessionID, list)
}),
)
},
@ -540,7 +540,7 @@ export const createDirSyncContext = (client: OpencodeClient, directory: string)
return meta.loading[key] ?? false
},
async loadMore(sessionID: string, count?: number) {
const [, setStore] = globalSync.child(directory)
const [, setStore] = serverSync.child(directory)
touch(directory, setStore, sessionID)
const key = keyFor(directory, sessionID)
const step = count ?? historyMessagePageSize
@ -561,12 +561,12 @@ export const createDirSyncContext = (client: OpencodeClient, directory: string)
},
},
evict(sessionID: string, _directory = directory) {
const [, setStore] = globalSync.child(_directory)
const [, setStore] = serverSync.child(_directory)
seenFor(_directory).delete(sessionID)
evict(_directory, setStore, [sessionID])
},
fetch: async (count = 10) => {
const [store, setStore] = globalSync.child(directory)
const [store, setStore] = serverSync.child(directory)
setStore("limit", (x) => x + count)
await client.session.list().then((x) => {
const sessions = (x.data ?? [])
@ -578,7 +578,7 @@ export const createDirSyncContext = (client: OpencodeClient, directory: string)
},
more: createMemo(() => current()[0].session.length >= current()[0].limit),
archive: async (sessionID: string) => {
const [, setStore] = globalSync.child(directory)
const [, setStore] = serverSync.child(directory)
await client.session.update({ sessionID, time: { archived: Date.now() } })
setStore(
produce((draft) => {

View file

@ -18,7 +18,7 @@ import type { State, VcsCache } from "./types"
import { cmp, normalizeAgentList, normalizeProviderList } from "./utils"
import { formatServerError } from "@/utils/server-errors"
import { QueryClient, queryOptions } from "@tanstack/solid-query"
import { loadMcpQuery } from "../global-sync"
import { loadMcpQuery } from "../server-sync"
import { NormalizedProviderListResponse } from "@opencode-ai/ui/context"
type GlobalStore = {
@ -105,7 +105,7 @@ export const loadProjectsQuery = (sdk: OpencodeClient) =>
})
export async function bootstrapGlobal(input: {
globalSDK: OpencodeClient
serverSDK: OpencodeClient
requestFailedTitle: string
translate: (key: string, vars?: Record<string, string | number>) => string
formatMoreCount: (count: number) => string
@ -113,12 +113,12 @@ export async function bootstrapGlobal(input: {
queryClient: QueryClient
}) {
const slow = [
() => input.queryClient.fetchQuery(loadGlobalConfigQuery(input.globalSDK)),
() => input.queryClient.fetchQuery(loadProvidersQuery(null, input.globalSDK)),
() => input.queryClient.fetchQuery(loadPathQuery(null, input.globalSDK)),
() => input.queryClient.fetchQuery(loadGlobalConfigQuery(input.serverSDK)),
() => input.queryClient.fetchQuery(loadProvidersQuery(null, input.serverSDK)),
() => input.queryClient.fetchQuery(loadPathQuery(null, input.serverSDK)),
() =>
input.queryClient
.fetchQuery(loadProjectsQuery(input.globalSDK))
.fetchQuery(loadProjectsQuery(input.serverSDK))
.then((data) => input.setGlobalStore("project", data)),
]
await runAll(slow)

View file

@ -15,7 +15,7 @@ import {
} from "./types"
import { canDisposeDirectory, pickDirectoriesToEvict } from "./eviction"
import { useQueries } from "@tanstack/solid-query"
import { QueryOptionsApi } from "../global-sync"
import { QueryOptionsApi } from "../server-sync"
import { directoryKey, type DirectoryKey } from "./utils"
import { NormalizedProviderListResponse } from "@opencode-ai/ui/context"

View file

@ -2,8 +2,8 @@ import { createStore, produce } from "solid-js/store"
import { batch, createEffect, createMemo, onCleanup, onMount, type Accessor } from "solid-js"
import { createSimpleContext } from "@opencode-ai/ui/context"
import { makeEventListener } from "@solid-primitives/event-listener"
import { useGlobalSync } from "./global-sync"
import { useGlobalSDK } from "./global-sdk"
import { useServerSync } from "./server-sync"
import { useServerSDK } from "./server-sdk"
import { useServer } from "./server"
import { usePlatform } from "./platform"
import { Project } from "@opencode-ai/sdk/v2"
@ -136,8 +136,8 @@ const normalizeStoredSessionTabs = (key: string, tabs: SessionTabs) => {
export const { use: useLayout, provider: LayoutProvider } = createSimpleContext({
name: "Layout",
init: () => {
const globalSdk = useGlobalSDK()
const globalSync = useGlobalSync()
const globalSdk = useServerSDK()
const serverSync = useServerSync()
const server = useServer()
const platform = usePlatform()
@ -386,11 +386,11 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
}
function enrich(project: { worktree: string; expanded: boolean }) {
const [childStore] = globalSync.child(project.worktree, { bootstrap: false })
const [childStore] = serverSync.child(project.worktree, { bootstrap: false })
const projectID = childStore.project
const metadata = projectID
? globalSync.data.project.find((x) => x.id === projectID)
: globalSync.data.project.find((x) => x.worktree === project.worktree)
? serverSync.data.project.find((x) => x.id === projectID)
: serverSync.data.project.find((x) => x.worktree === project.worktree)
// Preserve local icon override from per-workspace localStorage cache (childStore.icon).
// Without this, different subdirectories of the same git repo would share the same
@ -404,7 +404,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
const roots = createMemo(() => {
const map = new Map<string, string>()
for (const project of globalSync.data.project) {
for (const project of serverSync.data.project) {
const sandboxes = project.sandboxes ?? []
for (const sandbox of sandboxes) {
map.set(sandbox, project.worktree)
@ -470,12 +470,12 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
createEffect(() => {
const projects = enriched()
if (projects.length === 0) return
if (!globalSync.ready) return
if (!serverSync.ready) return
for (const project of projects) {
if (!project.id) continue
if (project.id === "global") continue
globalSync.project.icon(project.worktree, project.icon?.override)
serverSync.project.icon(project.worktree, project.icon?.override)
}
})
@ -509,7 +509,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
colorRequested.set(worktree, color)
if (project.id === "global") {
globalSync.project.meta(worktree, { icon: { color } })
serverSync.project.meta(worktree, { icon: { color } })
continue
}
@ -531,7 +531,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
sessionTimer = undefined
void Promise.all(
server.projects.list().map((project) => {
return globalSync.project.loadSessions(project.worktree)
return serverSync.project.loadSessions(project.worktree)
}),
)
}, 0)
@ -560,7 +560,7 @@ export const { use: useLayout, provider: LayoutProvider } = createSimpleContext(
open(directory: string) {
const root = rootFor(directory)
if (server.projects.list().find((x) => x.worktree === root)) return
void globalSync.project.loadSessions(root)
void serverSync.project.loadSessions(root)
server.projects.open(root)
},
close(directory: string) {

View file

@ -2,8 +2,8 @@ import { createStore, reconcile } from "solid-js/store"
import { batch, createEffect, createMemo, onCleanup } from "solid-js"
import { useParams } from "@solidjs/router"
import { createSimpleContext } from "@opencode-ai/ui/context"
import { useGlobalSDK } from "./global-sdk"
import { useGlobalSync } from "./global-sync"
import { useServerSDK } from "./server-sdk"
import { useServerSync } from "./server-sync"
import { usePlatform } from "@/context/platform"
import { useLanguage } from "@/context/language"
import { useSettings } from "@/context/settings"
@ -109,8 +109,8 @@ export const { use: useNotification, provider: NotificationProvider } = createSi
name: "Notification",
init: () => {
const params = useParams()
const globalSDK = useGlobalSDK()
const globalSync = useGlobalSync()
const serverSDK = useServerSDK()
const serverSync = useServerSync()
const platform = usePlatform()
const settings = useSettings()
const language = useLanguage()
@ -207,10 +207,10 @@ export const { use: useNotification, provider: NotificationProvider } = createSi
const lookup = async (directory: string, sessionID?: string) => {
if (!sessionID) return undefined
const [syncStore] = globalSync.child(directory, { bootstrap: false })
const [syncStore] = serverSync.child(directory, { bootstrap: false })
const match = Binary.search(syncStore.session, sessionID, (s) => s.id)
if (match.found) return syncStore.session[match.index]
return globalSDK.client.session
return serverSDK.client.session
.get({ directory, sessionID })
.then((x) => x.data)
.catch(() => undefined)
@ -285,7 +285,7 @@ export const { use: useNotification, provider: NotificationProvider } = createSi
})
}
const unsub = globalSDK.event.listen((e) => {
const unsub = serverSDK.event.listen((e) => {
const event = e.details
if (event.type !== "session.idle" && event.type !== "session.error") return

View file

@ -3,8 +3,8 @@ import { createStore, produce } from "solid-js/store"
import { createSimpleContext } from "@opencode-ai/ui/context"
import type { PermissionRequest } from "@opencode-ai/sdk/v2/client"
import { Persist, persisted } from "@/utils/persist"
import { useGlobalSDK } from "@/context/global-sdk"
import { useGlobalSync } from "./global-sync"
import { useServerSDK } from "@/context/server-sdk"
import { useServerSync } from "./server-sync"
import { useParams } from "@solidjs/router"
import { decode64 } from "@/utils/base64"
import {
@ -48,13 +48,13 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple
name: "Permission",
init: () => {
const params = useParams()
const globalSDK = useGlobalSDK()
const globalSync = useGlobalSync()
const serverSDK = useServerSDK()
const serverSync = useServerSync()
const permissionsEnabled = createMemo(() => {
const directory = decode64(params.dir)
if (!directory) return false
const [store] = globalSync.child(directory)
const [store] = serverSync.child(directory)
return hasPermissionPromptRules(store.config.permission)
})
@ -86,7 +86,7 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple
if (!ready()) return
const directory = decode64(params.dir)
if (!directory) return
const [childStore] = globalSync.child(directory)
const [childStore] = serverSync.child(directory)
const perm = childStore.config.permission
if (typeof perm === "string" && perm === "allow") {
const key = directoryAcceptKey(directory)
@ -118,7 +118,7 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple
}
const respond: PermissionRespondFn = (input) => {
globalSDK.client.permission.respond(input).catch(() => {
serverSDK.client.permission.respond(input).catch(() => {
responded.delete(input.permissionID)
})
}
@ -139,7 +139,7 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple
}
function isAutoAccepting(sessionID: string, directory?: string) {
const session = directory ? globalSync.child(directory, { bootstrap: false })[0].session : []
const session = directory ? serverSync.child(directory, { bootstrap: false })[0].session : []
return autoRespondsPermission(store.autoAccept, session, { sessionID }, directory)
}
@ -148,7 +148,7 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple
}
function shouldAutoRespond(permission: PermissionRequest, directory?: string) {
const session = directory ? globalSync.child(directory, { bootstrap: false })[0].session : []
const session = directory ? serverSync.child(directory, { bootstrap: false })[0].session : []
return autoRespondsPermission(store.autoAccept, session, permission, directory)
}
@ -159,7 +159,7 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple
return next
}
const unsubscribe = globalSDK.event.listen((e) => {
const unsubscribe = serverSDK.event.listen((e) => {
const event = e.details
if (event?.type !== "permission.asked") return
@ -178,7 +178,7 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple
}),
)
globalSDK.client.permission
serverSDK.client.permission
.list({ directory })
.then((x) => {
if (!isAutoAcceptingDirectory(directory)) return
@ -210,7 +210,7 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple
}),
)
globalSDK.client.permission
serverSDK.client.permission
.list({ directory })
.then((x) => {
if (enableVersion.get(key) !== version) return
@ -268,7 +268,7 @@ export const { use: usePermission, provider: PermissionProvider } = createSimple
},
permissionsEnabled,
isPermissionAllowAll(directory: string) {
const [childStore] = globalSync.child(directory)
const [childStore] = serverSync.child(directory)
const perm = childStore.config.permission
return typeof perm === "string" && perm === "allow"
},

View file

@ -1,11 +1,11 @@
import { createSimpleContext } from "@opencode-ai/ui/context"
import { useGlobalSDK } from "./global-sdk"
import { useServerSDK } from "./server-sdk"
export const { use: useSDK, provider: SDKProvider } = createSimpleContext({
name: "SDK",
init: (props: { directory: string }) => {
const globalSDK = useGlobalSDK()
const serverSDK = useServerSDK()
return globalSDK.createDirSyncContext(props.directory)
return serverSDK.createDirSyncContext(props.directory)
},
})

View file

@ -11,7 +11,7 @@ import { useServer } from "./server"
const isAbortError = (error: unknown) =>
error !== null && typeof error === "object" && "name" in error && error.name === "AbortError"
export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleContext({
export const { use: useServerSDK, provider: ServerSDKProvider } = createSimpleContext({
name: "GlobalSDK",
init: () => {
const language = useLanguage()
@ -31,7 +31,7 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
})()
const currentServer = server.current
if (!currentServer) throw new Error(language.t("error.globalSDK.noServerAvailable"))
if (!currentServer) throw new Error(language.t("error.serverSDK.noServerAvailable"))
const eventSdk = createSdkForServer({
signal: abort.signal,
@ -245,7 +245,7 @@ export const { use: useGlobalSDK, provider: GlobalSDKProvider } = createSimpleCo
},
createClient(opts: Omit<Parameters<typeof createSdkForServer>[0], "server" | "fetch">) {
const s = server.current
if (!s) throw new Error(language.t("error.globalSDK.serverNotAvailable"))
if (!s) throw new Error(language.t("error.serverSDK.serverNotAvailable"))
return createSdkForServer({
server: s.http,
fetch: platform.fetch,
@ -281,16 +281,16 @@ type SDKEventMap = {
}
function createDirSdkContext(directory: string) {
const globalSDK = useGlobalSDK()
const serverSDK = useServerSDK()
const client = globalSDK.createClient({
const client = serverSDK.createClient({
directory,
throwOnError: true,
})
const emitter = createGlobalEmitter<SDKEventMap>()
const unsub = globalSDK.event.on(directory, (event) => {
const unsub = serverSDK.event.on(directory, (event) => {
emitter.emit(event.type, event)
})
onCleanup(unsub)
@ -300,10 +300,10 @@ function createDirSdkContext(directory: string) {
client,
event: emitter,
get url() {
return globalSDK.url
return serverSDK.url
},
createClient(opts: Parameters<typeof globalSDK.createClient>[0]) {
return globalSDK.createClient(opts)
createClient(opts: Parameters<typeof serverSDK.createClient>[0]) {
return serverSDK.createClient(opts)
},
}
}

View file

@ -5,7 +5,7 @@ import { batch, createContext, getOwner, onCleanup, onMount, type ParentProps, u
import { createStore, produce, reconcile } from "solid-js/store"
import { useLanguage } from "@/context/language"
import type { InitError } from "../pages/error"
import { useGlobalSDK } from "./global-sdk"
import { useServerSDK } from "./server-sdk"
import {
bootstrapDirectory,
bootstrapGlobal,
@ -57,13 +57,13 @@ export const loadLspQuery = (directory: string, sdk: OpencodeClient) =>
queryFn: () => sdk.lsp.status().then((r) => r.data ?? []),
})
function makeQueryOptionsApi(globalSDK: () => OpencodeClient, sdkFor: (dir: PathKey) => OpencodeClient) {
function makeQueryOptionsApi(serverSDK: () => OpencodeClient, sdkFor: (dir: PathKey) => OpencodeClient) {
return {
globalConfig: () => loadGlobalConfigQuery(globalSDK()),
projects: () => loadProjectsQuery(globalSDK()),
globalConfig: () => loadGlobalConfigQuery(serverSDK()),
projects: () => loadProjectsQuery(serverSDK()),
providers: (directory: PathKey | null) =>
loadProvidersQuery(directory, directory === null ? globalSDK() : sdkFor(directory)),
path: (directory: PathKey | null) => loadPathQuery(directory, directory === null ? globalSDK() : sdkFor(directory)),
loadProvidersQuery(directory, directory === null ? serverSDK() : sdkFor(directory)),
path: (directory: PathKey | null) => loadPathQuery(directory, directory === null ? serverSDK() : sdkFor(directory)),
agents: (directory: PathKey) => loadAgentsQuery(directory, sdkFor(directory)),
mcp: (directory: PathKey) => loadMcpQuery(directory, sdkFor(directory)),
lsp: (directory: PathKey) => loadLspQuery(directory, sdkFor(directory)),
@ -72,8 +72,8 @@ function makeQueryOptionsApi(globalSDK: () => OpencodeClient, sdkFor: (dir: Path
}
export type QueryOptionsApi = ReturnType<typeof makeQueryOptionsApi>
function createGlobalSync() {
const globalSDK = useGlobalSDK()
function createServerSyncContext() {
const serverSDK = useServerSDK()
const language = useLanguage()
const owner = getOwner()
if (!owner) throw new Error("GlobalSync must be created within owner")
@ -87,7 +87,7 @@ function createGlobalSync() {
const key = directoryKey(directory)
const cached = sdkCache.get(key)
if (cached) return cached
const sdk = globalSDK.createClient({
const sdk = serverSDK.createClient({
directory,
throwOnError: true,
})
@ -95,7 +95,7 @@ function createGlobalSync() {
return sdk
}
const queryOptionsApi = makeQueryOptionsApi(() => globalSDK.client, sdkFor)
const queryOptionsApi = makeQueryOptionsApi(() => serverSDK.client, sdkFor)
const [configQuery, providerQuery, pathQuery] = useQueries(() => ({
queries: [queryOptionsApi.globalConfig(), queryOptionsApi.providers(null), queryOptionsApi.path(null)],
@ -154,7 +154,7 @@ function createGlobalSync() {
queryKey: ["bootstrap"],
queryFn: async () => {
await bootstrapGlobal({
globalSDK: globalSDK.client,
serverSDK: serverSDK.client,
requestFailedTitle: language.t("common.requestFailed"),
translate: language.t,
formatMoreCount: (count) => language.t("common.moreCountSuffix", { count }),
@ -248,7 +248,7 @@ function createGlobalSync() {
loadRootSessionsWithFallback({
directory,
limit,
list: (query) => globalSDK.client.session.list(query),
list: (query) => serverSDK.client.session.list(query),
})
.then((x) => {
const nonArchived = (x.data ?? [])
@ -334,7 +334,7 @@ function createGlobalSync() {
return promise
}
const unsub = globalSDK.event.listen((e) => {
const unsub = serverSDK.event.listen((e) => {
const directory = e.name
const key = directoryKey(directory)
const event = e.details
@ -393,13 +393,13 @@ function createGlobalSync() {
eventFrame = undefined
eventTimer = setTimeout(() => {
eventTimer = undefined
void globalSDK.event.start()
void serverSDK.event.start()
}, 0)
})
} else {
eventTimer = setTimeout(() => {
eventTimer = undefined
void globalSDK.event.start()
void serverSDK.event.start()
}, 0)
}
})
@ -415,7 +415,7 @@ function createGlobalSync() {
}
const updateConfigMutation = useMutation(() => ({
mutationFn: (config: Config) => globalSDK.client.global.config.update({ config }),
mutationFn: (config: Config) => serverSDK.client.global.config.update({ config }),
onSuccess: () => {
bootstrap.refetch()
// Invalidate all provider queries so newly configured custom providers
@ -460,7 +460,7 @@ function createGlobalSync() {
dirSyncContextRefCounts.set(directory, (dirSyncContextRefCounts.get(directory) ?? 0) + 1)
return cached
}
const ctx = createDirSyncContext(globalSDK.createClient({ directory, throwOnError: true }), directory)
const ctx = createDirSyncContext(serverSDK.createClient({ directory, throwOnError: true }), directory)
dirSyncContexts.set(directory, ctx)
dirSyncContextRefCounts.set(directory, 1)
@ -469,19 +469,19 @@ function createGlobalSync() {
}
}
const GlobalSyncContext = createContext<ReturnType<typeof createGlobalSync>>()
const ServerSyncContext = createContext<ReturnType<typeof createServerSyncContext>>()
export function GlobalSyncProvider(props: ParentProps) {
const value = createGlobalSync()
return <GlobalSyncContext.Provider value={value}>{props.children}</GlobalSyncContext.Provider>
export function ServerSyncProvider(props: ParentProps) {
const value = createServerSyncContext()
return <ServerSyncContext.Provider value={value}>{props.children}</ServerSyncContext.Provider>
}
export function useGlobalSync() {
const context = useContext(GlobalSyncContext)
if (!context) throw new Error("useGlobalSync must be used within GlobalSyncProvider")
export function useServerSync() {
const context = useContext(ServerSyncContext)
if (!context) throw new Error("useServerSync must be used within ServerSyncProvider")
return context
}
export function useQueryOptions() {
return useGlobalSync().queryOptions
return useServerSync().queryOptions
}

View file

@ -1,5 +1,5 @@
import { Binary } from "@opencode-ai/core/util/binary"
import { useGlobalSync } from "./global-sync"
import { useServerSync } from "./server-sync"
import { useSDK } from "./sdk"
import type { Message, Part } from "@opencode-ai/sdk/v2/client"
@ -109,8 +109,8 @@ export function applyOptimisticRemove(draft: OptimisticStore, input: OptimisticR
}
export const useSync = () => {
const globalSync = useGlobalSync()
const serverSync = useServerSync()
const sdk = useSDK()
return globalSync.createDirSyncContext(sdk.directory)
return serverSync.createDirSyncContext(sdk.directory)
}

View file

@ -1,4 +1,4 @@
import { useGlobalSync } from "@/context/global-sync"
import { useServerSync } from "@/context/server-sync"
import { decode64 } from "@/utils/base64"
import { useParams } from "@solidjs/router"
import { Iterable, pipe } from "effect"
@ -17,15 +17,15 @@ export const popularProviders = [
const popularProviderSet = new Set(popularProviders)
export function useProviders() {
const globalSync = useGlobalSync()
const serverSync = useServerSync()
const params = useParams()
const dir = createMemo(() => decode64(params.dir) ?? "")
const providers = () => {
if (dir()) {
const [projectStore] = globalSync.child(dir())
const [projectStore] = serverSync.child(dir())
if (projectStore.provider_ready) return projectStore.provider
}
return globalSync.data.provider
return serverSync.data.provider
}
return {
all: () => providers().all,

View file

@ -413,7 +413,7 @@ export const dict = {
"error.page.version": "الإصدار: {{version}}",
"error.dev.rootNotFound":
"لم يتم العثور على العنصر الجذري. هل نسيت إضافته إلى index.html؟ أو ربما تمت كتابة سمة id بشكل خاطئ؟",
"error.globalSync.connectFailed": "تعذر الاتصال بالخادم. هل هناك خادم يعمل في `{{url}}`؟",
"error.serverSync.connectFailed": "تعذر الاتصال بالخادم. هل هناك خادم يعمل في `{{url}}`؟",
"directory.error.invalidUrl": "دليل غير صالح في عنوان URL.",
"error.chain.unknown": "خطأ غير معروف",
"error.chain.causedBy": "بسبب:",
@ -837,8 +837,8 @@ export const dict = {
"common.key.insert": "Insert",
"common.unknown": "غير معروف",
"error.page.circular": "[دائري]",
"error.globalSDK.noServerAvailable": "لا يوجد خادم متاح",
"error.globalSDK.serverNotAvailable": "الخادم غير متاح",
"error.serverSDK.noServerAvailable": "لا يوجد خادم متاح",
"error.serverSDK.serverNotAvailable": "الخادم غير متاح",
"error.childStore.persistedCacheCreateFailed": "فشل إنشاء ذاكرة التخزين المؤقت الدائمة",
"error.childStore.persistedProjectMetadataCreateFailed": "فشل إنشاء بيانات تعريف المشروع الدائمة",
"error.childStore.persistedProjectIconCreateFailed": "فشل إنشاء أيقونة المشروع الدائمة",

View file

@ -414,7 +414,7 @@ export const dict = {
"error.page.version": "Versão: {{version}}",
"error.dev.rootNotFound":
"Elemento raiz não encontrado. Você esqueceu de adicioná-lo ao seu index.html? Ou talvez o atributo id foi escrito incorretamente?",
"error.globalSync.connectFailed": "Não foi possível conectar ao servidor. Há um servidor executando em `{{url}}`?",
"error.serverSync.connectFailed": "Não foi possível conectar ao servidor. Há um servidor executando em `{{url}}`?",
"directory.error.invalidUrl": "Diretório inválido na URL.",
"error.chain.unknown": "Erro desconhecido",
"error.chain.causedBy": "Causado por:",
@ -850,8 +850,8 @@ export const dict = {
"common.key.insert": "Insert",
"common.unknown": "desconhecido",
"error.page.circular": "[Circular]",
"error.globalSDK.noServerAvailable": "Nenhum servidor disponível",
"error.globalSDK.serverNotAvailable": "Servidor indisponível",
"error.serverSDK.noServerAvailable": "Nenhum servidor disponível",
"error.serverSDK.serverNotAvailable": "Servidor indisponível",
"error.childStore.persistedCacheCreateFailed": "Falha ao criar cache persistente",
"error.childStore.persistedProjectMetadataCreateFailed": "Falha ao criar metadados de projeto persistentes",
"error.childStore.persistedProjectIconCreateFailed": "Falha ao criar ícone de projeto persistente",

View file

@ -462,7 +462,7 @@ export const dict = {
"error.dev.rootNotFound":
"Korijenski element nije pronađen. Da li si zaboravio da ga dodaš u index.html? Ili je možda id atribut pogrešno napisan?",
"error.globalSync.connectFailed": "Nije moguće povezati se na server. Da li server radi na `{{url}}`?",
"error.serverSync.connectFailed": "Nije moguće povezati se na server. Da li server radi na `{{url}}`?",
"directory.error.invalidUrl": "Nevažeći direktorij u URL-u.",
"error.chain.unknown": "Nepoznata greška",
@ -926,8 +926,8 @@ export const dict = {
"common.key.insert": "Insert",
"common.unknown": "nepoznato",
"error.page.circular": "[Kružno]",
"error.globalSDK.noServerAvailable": "Nema dostupnog servera",
"error.globalSDK.serverNotAvailable": "Server nije dostupan",
"error.serverSDK.noServerAvailable": "Nema dostupnog servera",
"error.serverSDK.serverNotAvailable": "Server nije dostupan",
"error.childStore.persistedCacheCreateFailed": "Nije uspjelo kreiranje trajnog keša",
"error.childStore.persistedProjectMetadataCreateFailed": "Nije uspjelo kreiranje trajnih metapodataka projekta",
"error.childStore.persistedProjectIconCreateFailed": "Nije uspjelo kreiranje trajne ikone projekta",

View file

@ -459,7 +459,7 @@ export const dict = {
"error.dev.rootNotFound":
"Rodelement ikke fundet. Har du glemt at tilføje det til din index.html? Eller måske er id-attributten stavet forkert?",
"error.globalSync.connectFailed": "Kunne ikke forbinde til server. Kører der en server på `{{url}}`?",
"error.serverSync.connectFailed": "Kunne ikke forbinde til server. Kører der en server på `{{url}}`?",
"directory.error.invalidUrl": "Ugyldig mappe i URL.",
"error.chain.unknown": "Ukendt fejl",
@ -920,8 +920,8 @@ export const dict = {
"common.key.insert": "Insert",
"common.unknown": "ukendt",
"error.page.circular": "[Cirkulær]",
"error.globalSDK.noServerAvailable": "Ingen server tilgængelig",
"error.globalSDK.serverNotAvailable": "Server ikke tilgængelig",
"error.serverSDK.noServerAvailable": "Ingen server tilgængelig",
"error.serverSDK.serverNotAvailable": "Server ikke tilgængelig",
"error.childStore.persistedCacheCreateFailed": "Kunne ikke oprette vedvarende cache",
"error.childStore.persistedProjectMetadataCreateFailed": "Kunne ikke oprette vedvarende projektmetadata",
"error.childStore.persistedProjectIconCreateFailed": "Kunne ikke oprette vedvarende projektikon",

View file

@ -421,7 +421,7 @@ export const dict = {
"error.page.version": "Version: {{version}}",
"error.dev.rootNotFound":
"Wurzelelement nicht gefunden. Haben Sie vergessen, es in Ihre index.html aufzunehmen? Oder wurde das id-Attribut falsch geschrieben?",
"error.globalSync.connectFailed": "Verbindung zum Server fehlgeschlagen. Läuft ein Server unter `{{url}}`?",
"error.serverSync.connectFailed": "Verbindung zum Server fehlgeschlagen. Läuft ein Server unter `{{url}}`?",
"directory.error.invalidUrl": "Ungültiges Verzeichnis in der URL.",
"error.chain.unknown": "Unbekannter Fehler",
"error.chain.causedBy": "Verursacht durch:",
@ -862,8 +862,8 @@ export const dict = {
"common.key.insert": "Einfg",
"common.unknown": "unbekannt",
"error.page.circular": "[Zirkulär]",
"error.globalSDK.noServerAvailable": "Kein Server verfügbar",
"error.globalSDK.serverNotAvailable": "Server nicht verfügbar",
"error.serverSDK.noServerAvailable": "Kein Server verfügbar",
"error.serverSDK.serverNotAvailable": "Server nicht verfügbar",
"error.childStore.persistedCacheCreateFailed": "Dauerhafter Cache konnte nicht erstellt werden",
"error.childStore.persistedProjectMetadataCreateFailed": "Dauerhafte Projektmetadaten konnten nicht erstellt werden",
"error.childStore.persistedProjectIconCreateFailed": "Dauerhaftes Projekticon konnte nicht erstellt werden",

View file

@ -482,9 +482,9 @@ export const dict = {
"error.dev.rootNotFound":
"Root element not found. Did you forget to add it to your index.html? Or maybe the id attribute got misspelled?",
"error.globalSync.connectFailed": "Could not connect to server. Is there a server running at `{{url}}`?",
"error.globalSDK.noServerAvailable": "No server available",
"error.globalSDK.serverNotAvailable": "Server not available",
"error.serverSync.connectFailed": "Could not connect to server. Is there a server running at `{{url}}`?",
"error.serverSDK.noServerAvailable": "No server available",
"error.serverSDK.serverNotAvailable": "Server not available",
"error.childStore.persistedCacheCreateFailed": "Failed to create persisted cache",
"error.childStore.persistedProjectMetadataCreateFailed": "Failed to create persisted project metadata",
"error.childStore.persistedProjectIconCreateFailed": "Failed to create persisted project icon",

View file

@ -462,7 +462,7 @@ export const dict = {
"error.dev.rootNotFound":
"Elemento raíz no encontrado. ¿Olvidaste añadirlo a tu index.html? ¿O tal vez el atributo id está mal escrito?",
"error.globalSync.connectFailed": "No se pudo conectar al servidor. ¿Hay un servidor ejecutándose en `{{url}}`?",
"error.serverSync.connectFailed": "No se pudo conectar al servidor. ¿Hay un servidor ejecutándose en `{{url}}`?",
"directory.error.invalidUrl": "URL de directorio inválida.",
"error.chain.unknown": "Error desconocido",
@ -933,8 +933,8 @@ export const dict = {
"common.key.insert": "Insert",
"common.unknown": "desconocido",
"error.page.circular": "[Circular]",
"error.globalSDK.noServerAvailable": "Ningún servidor disponible",
"error.globalSDK.serverNotAvailable": "Servidor no disponible",
"error.serverSDK.noServerAvailable": "Ningún servidor disponible",
"error.serverSDK.serverNotAvailable": "Servidor no disponible",
"error.childStore.persistedCacheCreateFailed": "Error al crear caché persistente",
"error.childStore.persistedProjectMetadataCreateFailed": "Error al crear metadatos de proyecto persistentes",
"error.childStore.persistedProjectIconCreateFailed": "Error al crear icono de proyecto persistente",

View file

@ -417,7 +417,7 @@ export const dict = {
"error.page.version": "Version : {{version}}",
"error.dev.rootNotFound":
"Élément racine introuvable. Avez-vous oublié de l'ajouter à votre index.html ? Ou peut-être que l'attribut id est mal orthographié ?",
"error.globalSync.connectFailed":
"error.serverSync.connectFailed":
"Impossible de se connecter au serveur. Y a-t-il un serveur en cours d'exécution à `{{url}}` ?",
"directory.error.invalidUrl": "Répertoire invalide dans l'URL.",
"error.chain.unknown": "Erreur inconnue",
@ -860,8 +860,8 @@ export const dict = {
"common.key.insert": "Inser",
"common.unknown": "inconnu",
"error.page.circular": "[Circulaire]",
"error.globalSDK.noServerAvailable": "Aucun serveur disponible",
"error.globalSDK.serverNotAvailable": "Serveur non disponible",
"error.serverSDK.noServerAvailable": "Aucun serveur disponible",
"error.serverSDK.serverNotAvailable": "Serveur non disponible",
"error.childStore.persistedCacheCreateFailed": "Échec de la création du cache persistant",
"error.childStore.persistedProjectMetadataCreateFailed":
"Échec de la création des métadonnées de projet persistantes",

View file

@ -413,7 +413,7 @@ export const dict = {
"error.page.version": "バージョン: {{version}}",
"error.dev.rootNotFound":
"ルート要素が見つかりません。index.htmlに追加するのを忘れていませんかまたはid属性のスペルが間違っていませんか",
"error.globalSync.connectFailed": "サーバーに接続できませんでした。`{{url}}`でサーバーが実行されていますか?",
"error.serverSync.connectFailed": "サーバーに接続できませんでした。`{{url}}`でサーバーが実行されていますか?",
"directory.error.invalidUrl": "URL内のディレクトリが無効です。",
"error.chain.unknown": "不明なエラー",
"error.chain.causedBy": "原因:",
@ -844,8 +844,8 @@ export const dict = {
"common.key.insert": "Insert",
"common.unknown": "不明",
"error.page.circular": "[循環]",
"error.globalSDK.noServerAvailable": "利用可能なサーバーがありません",
"error.globalSDK.serverNotAvailable": "サーバーが利用できません",
"error.serverSDK.noServerAvailable": "利用可能なサーバーがありません",
"error.serverSDK.serverNotAvailable": "サーバーが利用できません",
"error.childStore.persistedCacheCreateFailed": "永続キャッシュの作成に失敗しました",
"error.childStore.persistedProjectMetadataCreateFailed": "永続プロジェクトメタデータの作成に失敗しました",
"error.childStore.persistedProjectIconCreateFailed": "永続プロジェクトアイコンの作成に失敗しました",

View file

@ -412,7 +412,7 @@ export const dict = {
"error.page.version": "버전: {{version}}",
"error.dev.rootNotFound":
"루트 요소를 찾을 수 없습니다. index.html에 추가하는 것을 잊으셨나요? 또는 id 속성의 철자가 틀렸을 수 있습니다.",
"error.globalSync.connectFailed": "서버에 연결할 수 없습니다. `{{url}}`에서 서버가 실행 중인가요?",
"error.serverSync.connectFailed": "서버에 연결할 수 없습니다. `{{url}}`에서 서버가 실행 중인가요?",
"directory.error.invalidUrl": "URL에 유효하지 않은 디렉터리가 있습니다.",
"error.chain.unknown": "알 수 없는 오류",
"error.chain.causedBy": "원인:",
@ -839,8 +839,8 @@ export const dict = {
"common.key.insert": "Insert",
"common.unknown": "알 수 없음",
"error.page.circular": "[순환]",
"error.globalSDK.noServerAvailable": "사용 가능한 서버 없음",
"error.globalSDK.serverNotAvailable": "서버를 사용할 수 없음",
"error.serverSDK.noServerAvailable": "사용 가능한 서버 없음",
"error.serverSDK.serverNotAvailable": "서버를 사용할 수 없음",
"error.childStore.persistedCacheCreateFailed": "영구 캐시 생성 실패",
"error.childStore.persistedProjectMetadataCreateFailed": "영구 프로젝트 메타데이터 생성 실패",
"error.childStore.persistedProjectIconCreateFailed": "영구 프로젝트 아이콘 생성 실패",

View file

@ -463,7 +463,7 @@ export const dict = {
"error.dev.rootNotFound":
"Rotelement ikke funnet. Glemte du å legge det til i index.html? Eller kanskje id-attributten er feilstavet?",
"error.globalSync.connectFailed": "Kunne ikke koble til server. Kjører det en server på `{{url}}`?",
"error.serverSync.connectFailed": "Kunne ikke koble til server. Kjører det en server på `{{url}}`?",
"directory.error.invalidUrl": "Invalid directory in URL.",
"error.chain.unknown": "Ukjent feil",
@ -927,8 +927,8 @@ export const dict = {
"common.key.insert": "Insert",
"common.unknown": "ukjent",
"error.page.circular": "[Sirkulær]",
"error.globalSDK.noServerAvailable": "Ingen server tilgjengelig",
"error.globalSDK.serverNotAvailable": "Server ikke tilgjengelig",
"error.serverSDK.noServerAvailable": "Ingen server tilgjengelig",
"error.serverSDK.serverNotAvailable": "Server ikke tilgjengelig",
"error.childStore.persistedCacheCreateFailed": "Kunne ikke opprette vedvarende hurtigbuffer",
"error.childStore.persistedProjectMetadataCreateFailed": "Kunne ikke opprette vedvarende prosjektmetadata",
"error.childStore.persistedProjectIconCreateFailed": "Kunne ikke opprette vedvarende prosjektikon",

View file

@ -414,7 +414,7 @@ export const dict = {
"error.page.version": "Wersja: {{version}}",
"error.dev.rootNotFound":
"Nie znaleziono elementu głównego. Czy zapomniałeś dodać go do swojego index.html? A może atrybut id został błędnie wpisany?",
"error.globalSync.connectFailed": "Nie można połączyć się z serwerem. Czy serwer działa pod adresem `{{url}}`?",
"error.serverSync.connectFailed": "Nie można połączyć się z serwerem. Czy serwer działa pod adresem `{{url}}`?",
"directory.error.invalidUrl": "Nieprawidłowy katalog w URL.",
"error.chain.unknown": "Nieznany błąd",
"error.chain.causedBy": "Spowodowany przez:",
@ -848,8 +848,8 @@ export const dict = {
"common.key.insert": "Insert",
"common.unknown": "nieznany",
"error.page.circular": "[Cykliczne]",
"error.globalSDK.noServerAvailable": "Brak dostępnego serwera",
"error.globalSDK.serverNotAvailable": "Serwer niedostępny",
"error.serverSDK.noServerAvailable": "Brak dostępnego serwera",
"error.serverSDK.serverNotAvailable": "Serwer niedostępny",
"error.childStore.persistedCacheCreateFailed": "Nie udało się utworzyć trwałej pamięci podręcznej",
"error.childStore.persistedProjectMetadataCreateFailed": "Nie udało się utworzyć trwałych metadanych projektu",
"error.childStore.persistedProjectIconCreateFailed": "Nie udało się utworzyć trwałej ikony projektu",

View file

@ -461,7 +461,7 @@ export const dict = {
"error.dev.rootNotFound":
"Корневой элемент не найден. Вы забыли добавить его в index.html? Или, может быть, атрибут id был написан неправильно?",
"error.globalSync.connectFailed": "Не удалось подключиться к серверу. Запущен ли сервер по адресу `{{url}}`?",
"error.serverSync.connectFailed": "Не удалось подключиться к серверу. Запущен ли сервер по адресу `{{url}}`?",
"directory.error.invalidUrl": "Недопустимая директория в URL.",
"error.chain.unknown": "Неизвестная ошибка",
@ -929,8 +929,8 @@ export const dict = {
"common.key.insert": "Insert",
"common.unknown": "неизвестно",
"error.page.circular": "[Циклично]",
"error.globalSDK.noServerAvailable": "Нет доступного сервера",
"error.globalSDK.serverNotAvailable": "Сервер недоступен",
"error.serverSDK.noServerAvailable": "Нет доступного сервера",
"error.serverSDK.serverNotAvailable": "Сервер недоступен",
"error.childStore.persistedCacheCreateFailed": "Не удалось создать постоянный кэш",
"error.childStore.persistedProjectMetadataCreateFailed": "Не удалось создать постоянные метаданные проекта",
"error.childStore.persistedProjectIconCreateFailed": "Не удалось создать постоянный значок проекта",

View file

@ -459,7 +459,7 @@ export const dict = {
"error.dev.rootNotFound": "ไม่พบองค์ประกอบรูท คุณลืมเพิ่มใน index.html หรือบางทีแอตทริบิวต์ id อาจสะกดผิด?",
"error.globalSync.connectFailed": "ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ มีเซิร์ฟเวอร์ทำงานอยู่ที่ `{{url}}` หรือไม่?",
"error.serverSync.connectFailed": "ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ มีเซิร์ฟเวอร์ทำงานอยู่ที่ `{{url}}` หรือไม่?",
"directory.error.invalidUrl": "ไดเรกทอรีใน URL ไม่ถูกต้อง",
"error.chain.unknown": "ข้อผิดพลาดที่ไม่รู้จัก",
@ -916,8 +916,8 @@ export const dict = {
"common.key.insert": "Insert",
"common.unknown": "ไม่ทราบ",
"error.page.circular": "[วงกลม]",
"error.globalSDK.noServerAvailable": "ไม่มีเซิร์ฟเวอร์",
"error.globalSDK.serverNotAvailable": "เซิร์ฟเวอร์ไม่พร้อมใช้งาน",
"error.serverSDK.noServerAvailable": "ไม่มีเซิร์ฟเวอร์",
"error.serverSDK.serverNotAvailable": "เซิร์ฟเวอร์ไม่พร้อมใช้งาน",
"error.childStore.persistedCacheCreateFailed": "ไม่สามารถสร้างแคชถาวร",
"error.childStore.persistedProjectMetadataCreateFailed": "ไม่สามารถสร้างเมตาดาต้าโปรเจกต์ถาวร",
"error.childStore.persistedProjectIconCreateFailed": "ไม่สามารถสร้างไอคอนโปรเจกต์ถาวร",

View file

@ -465,7 +465,7 @@ export const dict = {
"error.dev.rootNotFound":
"Kök eleman bulunamadı. index.html dosyanıza eklemeyi unuttunuz mu? Ya da id özelliği yanlış mı yazıldı?",
"error.globalSync.connectFailed": "Sunucuya bağlanılamadı. `{{url}}` adresinde çalışan bir sunucu var mı?",
"error.serverSync.connectFailed": "Sunucuya bağlanılamadı. `{{url}}` adresinde çalışan bir sunucu var mı?",
"directory.error.invalidUrl": "URL'de geçersiz dizin.",
"error.chain.unknown": "Bilinmeyen hata",
@ -935,8 +935,8 @@ export const dict = {
"common.key.insert": "Insert",
"common.unknown": "bilinmiyor",
"error.page.circular": "[Döngüsel]",
"error.globalSDK.noServerAvailable": "Sunucu yok",
"error.globalSDK.serverNotAvailable": "Sunucu mevcut değil",
"error.serverSDK.noServerAvailable": "Sunucu yok",
"error.serverSDK.serverNotAvailable": "Sunucu mevcut değil",
"error.childStore.persistedCacheCreateFailed": "Kalıcı önbellek oluşturulamadı",
"error.childStore.persistedProjectMetadataCreateFailed": "Kalıcı proje meta verileri oluşturulamadı",
"error.childStore.persistedProjectIconCreateFailed": "Kalıcı proje simgesi oluşturulamadı",

View file

@ -483,9 +483,9 @@ export const dict = {
"error.dev.rootNotFound":
"Кореневий елемент не знайдено. Ви забули додати його до index.html? Або, можливо, атрибут id було написано з помилкою?",
"error.globalSync.connectFailed": "Не вдалося підключитися до сервера. Чи працює сервер за адресою `{{url}}`?",
"error.globalSDK.noServerAvailable": "Сервер недоступний",
"error.globalSDK.serverNotAvailable": "Сервер недоступний",
"error.serverSync.connectFailed": "Не вдалося підключитися до сервера. Чи працює сервер за адресою `{{url}}`?",
"error.serverSDK.noServerAvailable": "Сервер недоступний",
"error.serverSDK.serverNotAvailable": "Сервер недоступний",
"error.childStore.persistedCacheCreateFailed": "Не вдалося створити постійний кеш",
"error.childStore.persistedProjectMetadataCreateFailed": "Не вдалося створити постійні метадані проєкту",
"error.childStore.persistedProjectIconCreateFailed": "Не вдалося створити постійну іконку проєкту",

View file

@ -462,7 +462,7 @@ export const dict = {
"error.page.report.discord": "在 Discord 上",
"error.page.version": "版本:{{version}}",
"error.dev.rootNotFound": "未找到根元素。你是不是忘了把它添加到 index.html或者 id 属性拼写错了?",
"error.globalSync.connectFailed": "无法连接到服务器。是否有服务器正在 `{{url}}` 运行?",
"error.serverSync.connectFailed": "无法连接到服务器。是否有服务器正在 `{{url}}` 运行?",
"directory.error.invalidUrl": "URL 中的目录无效。",
@ -919,8 +919,8 @@ export const dict = {
"common.key.insert": "Insert",
"common.unknown": "未知",
"error.page.circular": "[循环]",
"error.globalSDK.noServerAvailable": "无可用服务器",
"error.globalSDK.serverNotAvailable": "服务器不可用",
"error.serverSDK.noServerAvailable": "无可用服务器",
"error.serverSDK.serverNotAvailable": "服务器不可用",
"error.childStore.persistedCacheCreateFailed": "创建持久化缓存失败",
"error.childStore.persistedProjectMetadataCreateFailed": "创建持久化项目元数据失败",
"error.childStore.persistedProjectIconCreateFailed": "创建持久化项目图标失败",

View file

@ -457,7 +457,7 @@ export const dict = {
"error.dev.rootNotFound": "找不到根元素。你是不是忘了把它新增到 index.html? 或者 id 屬性拼錯了?",
"error.globalSync.connectFailed": "無法連線到伺服器。是否有伺服器正在 `{{url}}` 執行?",
"error.serverSync.connectFailed": "無法連線到伺服器。是否有伺服器正在 `{{url}}` 執行?",
"directory.error.invalidUrl": "URL 中的目錄無效。",
"error.chain.unknown": "未知錯誤",
@ -907,8 +907,8 @@ export const dict = {
"common.key.insert": "Insert",
"common.unknown": "未知",
"error.page.circular": "[循環]",
"error.globalSDK.noServerAvailable": "無可用的伺服器",
"error.globalSDK.serverNotAvailable": "伺服器無法使用",
"error.serverSDK.noServerAvailable": "無可用的伺服器",
"error.serverSDK.serverNotAvailable": "伺服器無法使用",
"error.childStore.persistedCacheCreateFailed": "建立持續性快取失敗",
"error.childStore.persistedProjectMetadataCreateFailed": "建立持續性專案中繼資料失敗",
"error.childStore.persistedProjectIconCreateFailed": "建立持續性專案圖示失敗",

View file

@ -20,7 +20,7 @@ import { DialogSelectDirectory } from "@/components/dialog-select-directory"
import { DialogSelectServer } from "@/components/dialog-select-server"
import { DialogSelectModel } from "@/components/dialog-select-model"
import { useServer } from "@/context/server"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSync } from "@/context/server-sync"
import { useLanguage } from "@/context/language"
import { useNotification } from "@/context/notification"
import { usePermission } from "@/context/permission"
@ -56,7 +56,7 @@ export default function Home() {
}
function HomeDesign() {
const sync = useGlobalSync()
const sync = useServerSync()
const layout = useLayout()
const platform = usePlatform()
const dialog = useDialog()
@ -359,10 +359,10 @@ function HomeSessionGroupHeader(props: { title: string; onNewSession?: () => voi
}
function HomeSessionRow(props: { record: HomeSessionRecord; openSession: (session: Session) => void }) {
const globalSync = useGlobalSync()
const serverSync = useServerSync()
const notification = useNotification()
const permission = usePermission()
const [sessionStore] = globalSync.child(props.record.session.directory, { bootstrap: false })
const [sessionStore] = serverSync.child(props.record.session.directory, { bootstrap: false })
const title = createMemo(() => sessionTitle(props.record.session.title) || props.record.session.id)
const unseenCount = createMemo(() => notification.session.unseenCount(props.record.session.id))
const hasError = createMemo(() => notification.session.unseenHasError(props.record.session.id))
@ -460,7 +460,7 @@ function groupSessions(records: HomeSessionRecord[], language: ReturnType<typeof
}
function LegacyHome() {
const sync = useGlobalSync()
const sync = useServerSync()
const layout = useLayout()
const platform = usePlatform()
const dialog = useDialog()

View file

@ -16,7 +16,7 @@ import { makeEventListener } from "@solid-primitives/event-listener"
import { useLocation, useNavigate, useParams } from "@solidjs/router"
import { useQuery } from "@tanstack/solid-query"
import { useLayout, LocalProject } from "@/context/layout"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSync } from "@/context/server-sync"
import { Persist, persisted } from "@/utils/persist"
import { base64Encode } from "@opencode-ai/core/util/encode"
import { decode64 } from "@/utils/base64"
@ -35,7 +35,7 @@ import { DragDropProvider, DragDropSensors, DragOverlay, SortableProvider, close
import type { DragEvent } from "@thisbeyond/solid-dnd"
import { useProviders } from "@/hooks/use-providers"
import { showToast, Toast, toaster } from "@opencode-ai/ui/toast"
import { useGlobalSDK } from "@/context/global-sdk"
import { useServerSDK } from "@/context/server-sdk"
import { clearWorkspaceTerminals, getTerminalServerScope } from "@/context/terminal"
import { dropSessionCaches, pickSessionCacheEvictions } from "@/context/global-sync/session-cache"
import {
@ -113,8 +113,8 @@ export default function Layout(props: ParentProps) {
let dialogDead = false
const params = useParams()
const globalSDK = useGlobalSDK()
const globalSync = useGlobalSync()
const serverSDK = useServerSDK()
const serverSync = useServerSync()
const layout = useLayout()
const layoutReady = createMemo(() => layout.ready())
const platform = usePlatform()
@ -136,7 +136,7 @@ export default function Layout(props: ParentProps) {
if (!slug) return { slug, dir: "" }
const dir = decode64(slug)
if (!dir) return { slug, dir: "" }
const store = globalSync.peek(dir, { bootstrap: false })
const store = serverSync.peek(dir, { bootstrap: false })
return {
slug,
store,
@ -226,7 +226,7 @@ export default function Layout(props: ParentProps) {
active: () => state.hoverProject,
el: () => state.nav?.querySelector<HTMLElement>("[data-component='sidebar-rail']") ?? state.nav,
onActivate: (directory) => {
globalSync.child(directory)
serverSync.child(directory)
setState("hoverProject", directory)
},
})
@ -410,7 +410,7 @@ export default function Layout(props: ParentProps) {
alertedAtBySession.delete(sessionKey)
}
const unsub = globalSDK.event.listen((e) => {
const unsub = serverSDK.event.listen((e) => {
if (e.details?.type === "worktree.ready") {
setBusy(e.name, false)
WorktreeState.ready(e.name)
@ -444,7 +444,7 @@ export default function Layout(props: ParentProps) {
const props = e.details.properties
if (e.details.type === "permission.asked" && permission.autoResponds(e.details.properties, directory)) return
const [store] = globalSync.child(directory, { bootstrap: false })
const [store] = serverSync.child(directory, { bootstrap: false })
const session = store.session.find((s) => s.id === props.sessionID)
const sessionKey = `${directory}:${props.sessionID}`
@ -507,7 +507,7 @@ export default function Layout(props: ParentProps) {
if (!currentDir() || !currentSession) return
const sessionKey = `${currentDir()}:${currentSession}`
dismissSessionAlert(sessionKey)
const [store] = globalSync.child(currentDir(), { bootstrap: false })
const [store] = serverSync.child(currentDir(), { bootstrap: false })
const childSessions = store.session.filter((s) => s.parentID === currentSession)
for (const child of childSessions) {
dismissSessionAlert(`${currentDir()}:${child.id}`)
@ -545,11 +545,11 @@ export default function Layout(props: ParentProps) {
const direct = projects.find((p) => pathKey(p.worktree) === key)
if (direct) return direct
const [child] = globalSync.child(directory, { bootstrap: false })
const [child] = serverSync.child(directory, { bootstrap: false })
const id = child.project
if (!id) return
const meta = globalSync.data.project.find((p) => p.id === id)
const meta = serverSync.data.project.find((p) => p.id === id)
const root = meta?.worktree
if (!root) return
@ -640,7 +640,7 @@ export default function Layout(props: ParentProps) {
const result: Session[] = []
for (const dir of dirs) {
const [dirStore] = globalSync.child(dir, { bootstrap: true })
const [dirStore] = serverSync.child(dir, { bootstrap: true })
const dirSessions = sortedRootSessions(dirStore, now)
result.push(...dirSessions)
}
@ -692,7 +692,7 @@ export default function Layout(props: ParentProps) {
createEffect(() => {
route()
globalSDK.url
serverSDK.url
prefetchToken.value += 1
clearSessionPrefetchInflight()
@ -739,13 +739,13 @@ export default function Layout(props: ParentProps) {
}
async function prefetchMessages(directory: string, sessionID: string, token: number) {
const [store, setStore] = globalSync.child(directory, { bootstrap: false })
const [store, setStore] = serverSync.child(directory, { bootstrap: false })
return runSessionPrefetch({
directory,
sessionID,
task: (rev) =>
retry(() => globalSDK.client.session.messages({ directory, sessionID, limit: prefetchChunk }))
retry(() => serverSDK.client.session.messages({ directory, sessionID, limit: prefetchChunk }))
.then((messages) => {
if (prefetchToken.value !== token) return
if (!isSessionPrefetchCurrent(directory, sessionID, rev)) return
@ -765,7 +765,7 @@ export default function Layout(props: ParentProps) {
if (stale.length > 0) {
clearSessionPrefetch(directory, stale)
for (const id of stale) {
globalSync.todo.set(id, undefined)
serverSync.todo.set(id, undefined)
}
}
@ -830,7 +830,7 @@ export default function Layout(props: ParentProps) {
const directory = session.directory
if (!directory) return
const [store] = globalSync.child(directory, { bootstrap: false })
const [store] = serverSync.child(directory, { bootstrap: false })
const cached = untrack(() => {
const info = getSessionPrefetch(directory, session.id)
return shouldSkipSessionPrefetch({
@ -935,7 +935,7 @@ export default function Layout(props: ParentProps) {
if (!target) return
// warm up child store to prevent flicker
globalSync.child(target.worktree)
serverSync.child(target.worktree)
void openProject(target.worktree)
}
@ -944,7 +944,7 @@ export default function Layout(props: ParentProps) {
const target = projects[index]
if (!target) return
globalSync.child(target.worktree)
serverSync.child(target.worktree)
void openProject(target.worktree)
}
@ -973,12 +973,12 @@ export default function Layout(props: ParentProps) {
}
async function archiveSession(session: Session) {
const [store, setStore] = globalSync.child(session.directory)
const [store, setStore] = serverSync.child(session.directory)
const sessions = store.session ?? []
const index = sessions.findIndex((s) => s.id === session.id)
const nextSession = sessions[index + 1] ?? sessions[index - 1]
await globalSDK.client.session.update({
await serverSDK.client.session.update({
directory: session.directory,
sessionID: session.id,
time: { archived: Date.now() },
@ -1246,11 +1246,11 @@ export default function Layout(props: ParentProps) {
)
if (known) return known[0]
const [child] = globalSync.child(directory, { bootstrap: false })
const [child] = serverSync.child(directory, { bootstrap: false })
const id = child.project
if (!id) return directory
const meta = globalSync.data.project.find((item) => item.id === id)
const meta = serverSync.data.project.find((item) => item.id === id)
return meta?.worktree ?? directory
}
@ -1298,7 +1298,7 @@ export default function Layout(props: ParentProps) {
}
const refreshDirs = async (target?: string) => {
if (!target || target === root || canOpen(target)) return canOpen(target)
const listed = await globalSDK.client.worktree
const listed = await serverSDK.client.worktree
.list({ directory: root })
.then((x) => x.data ?? [])
.catch(() => [] as string[])
@ -1307,13 +1307,13 @@ export default function Layout(props: ParentProps) {
}
const openSession = async (target: { directory: string; id: string }) => {
if (!canOpen(target.directory)) return false
const [data] = globalSync.child(target.directory, { bootstrap: false })
const [data] = serverSync.child(target.directory, { bootstrap: false })
if (data.session.some((item) => item.id === target.id)) {
setStore("lastProjectSession", root, { directory: target.directory, id: target.id, at: Date.now() })
navigateWithSidebarReset(`/${base64Encode(target.directory)}/session/${target.id}`)
return true
}
const resolved = await globalSDK.client.session
const resolved = await serverSDK.client.session
.get({ sessionID: target.id })
.then((x) => x.data)
.catch(() => undefined)
@ -1333,7 +1333,7 @@ export default function Layout(props: ParentProps) {
}
const latest = latestRootSession(
dirs.map((item) => globalSync.child(item, { bootstrap: false })[0]),
dirs.map((item) => serverSync.child(item, { bootstrap: false })[0]),
Date.now(),
)
if (latest && (await openSession(latest))) {
@ -1344,7 +1344,7 @@ export default function Layout(props: ParentProps) {
await Promise.all(
dirs.map(async (item) => ({
path: { directory: item },
session: await globalSDK.client.session
session: await serverSDK.client.session
.list({ directory: item })
.then((x) => x.data ?? [])
.catch(() => []),
@ -1405,11 +1405,11 @@ export default function Layout(props: ParentProps) {
const name = next === getFilename(project.worktree) ? "" : next
if (project.id && project.id !== "global") {
await globalSDK.client.project.update({ projectID: project.id, directory: project.worktree, name })
await serverSDK.client.project.update({ projectID: project.id, directory: project.worktree, name })
return
}
globalSync.project.meta(project.worktree, { name })
serverSync.project.meta(project.worktree, { name })
}
const renameWorkspace = (directory: string, next: string, projectId?: string, branch?: string) => {
@ -1506,7 +1506,7 @@ export default function Layout(props: ParentProps) {
setBusy(directory, true)
const result = await globalSDK.client.worktree
const result = await serverSDK.client.worktree
.remove({ directory: root, worktreeRemoveInput: { directory } })
.then((x) => x.data)
.catch((err) => {
@ -1525,7 +1525,7 @@ export default function Layout(props: ParentProps) {
clearLastProjectSession(root)
}
globalSync.set(
serverSync.set(
"project",
produce((draft) => {
const project = draft.find((item) => item.worktree === root)
@ -1564,7 +1564,7 @@ export default function Layout(props: ParentProps) {
})
const dismiss = () => toaster.dismiss(progress)
const sessions: Session[] = await globalSDK.client.session
const sessions: Session[] = await serverSDK.client.session
.list({ directory })
.then((x) => x.data ?? [])
.catch(() => [])
@ -1575,9 +1575,9 @@ export default function Layout(props: ParentProps) {
platform,
getTerminalServerScope(server.current, server.key),
)
await globalSDK.client.instance.dispose({ directory }).catch(() => undefined)
await serverSDK.client.instance.dispose({ directory }).catch(() => undefined)
const result = await globalSDK.client.worktree
const result = await serverSDK.client.worktree
.reset({ directory: root, worktreeResetInput: { directory } })
.then((x) => x.data)
.catch((err) => {
@ -1599,7 +1599,7 @@ export default function Layout(props: ParentProps) {
sessions
.filter((session) => session.time.archived === undefined)
.map((session) =>
globalSDK.client.session
serverSDK.client.session
.update({
sessionID: session.id,
directory: session.directory,
@ -1640,7 +1640,7 @@ export default function Layout(props: ParentProps) {
})
onMount(() => {
globalSDK.client.file
serverSDK.client.file
.status({ directory: props.directory })
.then((x) => {
const files = x.data ?? []
@ -1699,7 +1699,7 @@ export default function Layout(props: ParentProps) {
})
const refresh = async () => {
const sessions = await globalSDK.client.session
const sessions = await serverSDK.client.session
.list({ directory: props.directory })
.then((x) => x.data ?? [])
.catch(() => [])
@ -1708,7 +1708,7 @@ export default function Layout(props: ParentProps) {
}
onMount(() => {
globalSDK.client.file
serverSDK.client.file
.status({ directory: props.directory })
.then((x) => {
const files = x.data ?? []
@ -1842,7 +1842,7 @@ export default function Layout(props: ParentProps) {
const next = new Set(dirs)
for (const directory of next) {
if (loadedSessionDirs.has(directory)) continue
void globalSync.project.loadSessions(directory)
void serverSync.project.loadSessions(directory)
}
loadedSessionDirs.clear()
@ -1939,7 +1939,7 @@ export default function Layout(props: ParentProps) {
const createWorkspace = async (project: LocalProject) => {
clearSidebarHoverState()
const created = await globalSDK.client.worktree
const created = await serverSDK.client.worktree
.create({ directory: project.worktree })
.then((x) => x.data)
.catch((err) => {
@ -1973,7 +1973,7 @@ export default function Layout(props: ParentProps) {
return [created.directory, ...next]
})
globalSync.child(created.directory)
serverSync.child(created.directory)
navigateWithSidebarReset(`/${base64Encode(created.directory)}/session`)
}
@ -2078,7 +2078,7 @@ export default function Layout(props: ParentProps) {
if (!item) return false
return item.vcs === "git" || layout.sidebar.workspaces(item.worktree)()
})
const homedir = createMemo(() => globalSync.data.path.home)
const homedir = createMemo(() => serverSync.data.path.home)
return (
<div

View file

@ -7,7 +7,7 @@ import { Tooltip } from "@opencode-ai/ui/tooltip"
import { getFilename } from "@opencode-ai/core/util/path"
import { A, useParams } from "@solidjs/router"
import { type Accessor, createMemo, For, type JSX, Match, Show, Switch } from "solid-js"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSync } from "@/context/server-sync"
import { useLanguage } from "@/context/language"
import { getAvatarColors, type LocalProject, useLayout } from "@/context/layout"
import { useNotification } from "@/context/notification"
@ -23,7 +23,7 @@ export const ProjectIcon = (props: {
notify?: boolean
working?: boolean
}): JSX.Element => {
const globalSync = useGlobalSync()
const serverSync = useServerSync()
const notification = useNotification()
const permission = usePermission()
const dirs = createMemo(() => [props.project.worktree, ...(props.project.sandboxes ?? [])])
@ -33,7 +33,7 @@ export const ProjectIcon = (props: {
const hasError = createMemo(() => dirs().some((directory) => notification.project.unseenHasError(directory)))
const hasPermissions = createMemo(() =>
dirs().some((directory) => {
const [store] = globalSync.child(directory, { bootstrap: false })
const [store] = serverSync.child(directory, { bootstrap: false })
return hasProjectPermissions(store.permission, (item) => !permission.autoResponds(item, directory))
}),
)
@ -146,10 +146,10 @@ export const SessionItem = (props: SessionItemProps): JSX.Element => {
const language = useLanguage()
const notification = useNotification()
const permission = usePermission()
const globalSync = useGlobalSync()
const serverSync = useServerSync()
const unseenCount = createMemo(() => notification.session.unseenCount(props.session.id))
const hasError = createMemo(() => notification.session.unseenHasError(props.session.id))
const [sessionStore] = globalSync.child(props.session.directory)
const [sessionStore] = serverSync.child(props.session.directory)
const hasPermissions = createMemo(() => {
return !!sessionPermissionRequest(sessionStore.session, sessionStore.permission, props.session.id, (item) => {
return !permission.autoResponds(item, props.session.directory)

View file

@ -7,7 +7,7 @@ import { HoverCard } from "@opencode-ai/ui/hover-card"
import { Icon } from "@opencode-ai/ui/icon"
import { createSortable } from "@thisbeyond/solid-dnd"
import { useLayout, type LocalProject } from "@/context/layout"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSync } from "@/context/server-sync"
import { useLanguage } from "@/context/language"
import { useNotification } from "@/context/notification"
import { ProjectIcon, SessionItem, type SessionItemProps } from "./sidebar-items"
@ -274,7 +274,7 @@ export const SortableProject = (props: {
ctx: ProjectSidebarContext
sortNow: Accessor<number>
}): JSX.Element => {
const globalSync = useGlobalSync()
const serverSync = useServerSync()
const language = useLanguage()
const sortable = createSortable(props.project.worktree)
const selected = createMemo(() => props.ctx.currentProject()?.worktree === props.project.worktree)
@ -294,23 +294,23 @@ export const SortableProject = (props: {
const hoverOpen = () => isHoverProject() && preview() && !selected() && !state.menu
const label = (directory: string) => {
const [data] = globalSync.child(directory, { bootstrap: false })
const [data] = serverSync.child(directory, { bootstrap: false })
const kind =
directory === props.project.worktree ? language.t("workspace.type.local") : language.t("workspace.type.sandbox")
const name = props.ctx.workspaceLabel(directory, data.vcs?.branch, props.project.id)
return `${kind} : ${name}`
}
const projectStore = createMemo(() => globalSync.child(props.project.worktree, { bootstrap: false })[0])
const projectStore = createMemo(() => serverSync.child(props.project.worktree, { bootstrap: false })[0])
const isWorking = createMemo(() =>
dirs().some((directory) => {
const [store] = globalSync.child(directory, { bootstrap: false })
const [store] = serverSync.child(directory, { bootstrap: false })
return Object.keys(store.session_status).some((id) => store.session_working(id))
}),
)
const projectSessions = createMemo(() => sortedRootSessions(projectStore(), props.sortNow()))
const workspaceSessions = (directory: string) => {
const [data] = globalSync.child(directory, { bootstrap: false })
const [data] = serverSync.child(directory, { bootstrap: false })
return sortedRootSessions(data, props.sortNow())
}
const tile = () => (

View file

@ -14,7 +14,7 @@ import { Spinner } from "@opencode-ai/ui/spinner"
import { Tooltip } from "@opencode-ai/ui/tooltip"
import { type Session } from "@opencode-ai/sdk/v2/client"
import { type LocalProject } from "@/context/layout"
import { useGlobalSync, useQueryOptions } from "@/context/global-sync"
import { useServerSync, useQueryOptions } from "@/context/server-sync"
import { useLanguage } from "@/context/language"
import { pathKey } from "@/utils/path-key"
import { NewSessionItem, SessionItem, SessionSkeleton } from "./sidebar-items"
@ -60,7 +60,7 @@ export const WorkspaceDragOverlay = (props: {
activeWorkspace: Accessor<string | undefined>
workspaceLabel: (directory: string, branch?: string, projectId?: string) => string
}): JSX.Element => {
const globalSync = useGlobalSync()
const serverSync = useServerSync()
const language = useLanguage()
const label = createMemo(() => {
const project = props.sidebarProject()
@ -68,7 +68,7 @@ export const WorkspaceDragOverlay = (props: {
const directory = props.activeWorkspace()
if (!directory) return
const [workspaceStore] = globalSync.child(directory, { bootstrap: false })
const [workspaceStore] = serverSync.child(directory, { bootstrap: false })
const kind =
directory === project.worktree ? language.t("workspace.type.local") : language.t("workspace.type.sandbox")
const name = props.workspaceLabel(directory, workspaceStore.vcs?.branch, project.id)
@ -299,11 +299,11 @@ export const SortableWorkspace = (props: {
}): JSX.Element => {
const navigate = useNavigate()
const params = useParams()
const globalSync = useGlobalSync()
const serverSync = useServerSync()
const queryOptions = useQueryOptions()
const language = useLanguage()
const sortable = createSortable(props.directory)
const [workspaceStore, setWorkspaceStore] = globalSync.child(props.directory, { bootstrap: false })
const [workspaceStore, setWorkspaceStore] = serverSync.child(props.directory, { bootstrap: false })
const [menu, setMenu] = createStore({
open: false,
pendingRename: false,
@ -328,7 +328,7 @@ export const SortableWorkspace = (props: {
const showNew = createMemo(() => !loading() && (touch() || count() === 0 || (active() && !params.id)))
const loadMore = async () => {
setWorkspaceStore("limit", (limit) => (limit ?? 0) + 5)
await globalSync.project.loadSessions(props.directory)
await serverSync.project.loadSessions(props.directory)
}
const workspaceEditActive = createMemo(() => props.ctx.editorOpen(`workspace:${props.directory}`))
@ -357,7 +357,7 @@ export const SortableWorkspace = (props: {
createEffect(() => {
if (!boot()) return
globalSync.child(props.directory, { bootstrap: true })
serverSync.child(props.directory, { bootstrap: true })
})
return (
@ -446,11 +446,11 @@ export const LocalWorkspace = (props: {
sortNow: Accessor<number>
mobile?: boolean
}): JSX.Element => {
const globalSync = useGlobalSync()
const serverSync = useServerSync()
const queryOptions = useQueryOptions()
const language = useLanguage()
const workspace = createMemo(() => {
const [store, setStore] = globalSync.child(props.project.worktree)
const [store, setStore] = serverSync.child(props.project.worktree)
return { store, setStore }
})
const slug = createMemo(() => base64Encode(props.project.worktree))
@ -461,7 +461,7 @@ export const LocalWorkspace = (props: {
const loading = () => fetching() > 0 && count() === 0
const loadMore = async () => {
workspace().setStore("limit", (limit) => (limit ?? 0) + 5)
await globalSync.project.loadSessions(props.project.worktree)
await serverSync.project.loadSessions(props.project.worktree)
}
return (

View file

@ -34,7 +34,7 @@ import { useLocation, useSearchParams } from "@solidjs/router"
import { NewSessionDesignView, NewSessionView, SessionHeader } from "@/components/session"
import { useComments } from "@/context/comments"
import { getSessionPrefetch, SESSION_PREFETCH_TTL } from "@/context/global-sync/session-prefetch"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSync } from "@/context/server-sync"
import { useLanguage } from "@/context/language"
import { useLayout } from "@/context/layout"
import { usePrompt } from "@/context/prompt"
@ -181,7 +181,7 @@ function createSessionHistoryLoader(input: SessionHistoryWindowInput) {
}
export default function Page() {
const globalSync = useGlobalSync()
const serverSync = useServerSync()
const layout = useLayout()
const local = useLocal()
const file = useFile()
@ -558,11 +558,11 @@ export default function Page() {
}
function upsert(next: Project) {
const list = globalSync.data.project
const list = serverSync.data.project
sync.set("project", next.id)
const idx = list.findIndex((item) => item.id === next.id)
if (idx >= 0) {
globalSync.set(
serverSync.set(
"project",
list.map((item, i) => (i === idx ? { ...item, ...next } : item)),
)
@ -570,10 +570,10 @@ export default function Page() {
}
const at = list.findIndex((item) => item.id > next.id)
if (at >= 0) {
globalSync.set("project", [...list.slice(0, at), next, ...list.slice(at)])
serverSync.set("project", [...list.slice(0, at), next, ...list.slice(at)])
return
}
globalSync.set("project", [...list, next])
serverSync.set("project", [...list, next])
}
const gitMutation = useMutation(() => ({
@ -671,7 +671,7 @@ export default function Page() {
todoTimer = undefined
if (!id) return
if (status === "idle" && !blocked) return
const cached = untrack(() => sync.data.todo[id] !== undefined || globalSync.data.session_todo[id] !== undefined)
const cached = untrack(() => sync.data.todo[id] !== undefined || serverSync.data.session_todo[id] !== undefined)
todoFrame = requestAnimationFrame(() => {
todoFrame = undefined
@ -1384,7 +1384,7 @@ export default function Page() {
const ok = await sendFollowupDraft({
client: sdk.client,
sync,
globalSync,
serverSync,
draft: item,
optimisticBusy: item.sessionDirectory === sdk.directory,
}).catch((err) => {

View file

@ -3,7 +3,7 @@ import { createStore } from "solid-js/store"
import type { PermissionRequest, QuestionRequest, Todo } from "@opencode-ai/sdk/v2"
import { useParams } from "@solidjs/router"
import { showToast } from "@opencode-ai/ui/toast"
import { useGlobalSync } from "@/context/global-sync"
import { useServerSync } from "@/context/server-sync"
import { useLanguage } from "@/context/language"
import { usePermission } from "@/context/permission"
import { useSDK } from "@/context/sdk"
@ -27,7 +27,7 @@ export function createSessionComposerState(options?: { closeMs?: number | (() =>
const params = useParams()
const sdk = useSDK()
const sync = useSync()
const globalSync = useGlobalSync()
const serverSync = useServerSync()
const language = useLanguage()
const permission = usePermission()
@ -50,7 +50,7 @@ export function createSessionComposerState(options?: { closeMs?: number | (() =>
const todos = createMemo((): Todo[] => {
const id = params.id
if (!id) return []
return globalSync.data.session_todo[id] ?? []
return serverSync.data.session_todo[id] ?? []
})
const done = createMemo(
@ -111,7 +111,7 @@ export function createSessionComposerState(options?: { closeMs?: number | (() =>
const clear = () => {
const id = params.id
if (!id) return
globalSync.todo.set(id, [])
serverSync.todo.set(id, [])
sync.set("todo", id, [])
}

View file

@ -48,7 +48,7 @@ import { useDialog } from "@opencode-ai/ui/context/dialog"
import { createResizeObserver } from "@solid-primitives/resize-observer"
import { useLanguage } from "@/context/language"
import { useSessionKey } from "@/pages/session/session-layout"
import { useGlobalSDK } from "@/context/global-sdk"
import { useServerSDK } from "@/context/server-sdk"
import { usePlatform } from "@/context/platform"
import { useSettings } from "@/context/settings"
import { useSDK } from "@/context/sdk"
@ -273,7 +273,7 @@ export function MessageTimeline(props: {
let touchGesture: number | undefined
const navigate = useNavigate()
const globalSDK = useGlobalSDK()
const serverSDK = useServerSDK()
const sdk = useSDK()
const sync = useSync()
const settings = useSettings()
@ -704,14 +704,14 @@ export function MessageTimeline(props: {
}
const shareMutation = useMutation(() => ({
mutationFn: (id: string) => globalSDK.client.session.share({ sessionID: id, directory: sdk.directory }),
mutationFn: (id: string) => serverSDK.client.session.share({ sessionID: id, directory: sdk.directory }),
onError: (err) => {
console.error("Failed to share session", err)
},
}))
const unshareMutation = useMutation(() => ({
mutationFn: (id: string) => globalSDK.client.session.unshare({ sessionID: id, directory: sdk.directory }),
mutationFn: (id: string) => serverSDK.client.session.unshare({ sessionID: id, directory: sdk.directory }),
onError: (err) => {
console.error("Failed to unshare session", err)
},