|
|
@@ -17,18 +17,19 @@ import type {
|
|
|
ProviderListResponse,
|
|
|
ProviderAuthMethod,
|
|
|
VcsInfo,
|
|
|
+ Workspace,
|
|
|
} from "@opencode-ai/sdk/v2"
|
|
|
import { createStore, produce, reconcile } from "solid-js/store"
|
|
|
+import { useProject } from "@tui/context/project"
|
|
|
+import { useEvent } from "@tui/context/event"
|
|
|
import { useSDK } from "@tui/context/sdk"
|
|
|
import { Binary } from "@opencode-ai/util/binary"
|
|
|
import { createSimpleContext } from "./helper"
|
|
|
import type { Snapshot } from "@/snapshot"
|
|
|
import { useExit } from "./exit"
|
|
|
import { useArgs } from "./args"
|
|
|
-import { batch, onMount } from "solid-js"
|
|
|
+import { batch, createEffect, on } from "solid-js"
|
|
|
import { Log } from "@/util/log"
|
|
|
-import type { Path } from "@opencode-ai/sdk"
|
|
|
-import type { Workspace } from "@opencode-ai/sdk/v2"
|
|
|
import { ConsoleState, emptyConsoleState, type ConsoleState as ConsoleStateType } from "@/config/console-state"
|
|
|
|
|
|
export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|
|
@@ -74,9 +75,8 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|
|
[key: string]: McpResource
|
|
|
}
|
|
|
formatter: FormatterStatus[]
|
|
|
- vcs: VcsInfo | undefined
|
|
|
- path: Path
|
|
|
workspaceList: Workspace[]
|
|
|
+ vcs: VcsInfo | undefined
|
|
|
}>({
|
|
|
provider_next: {
|
|
|
all: [],
|
|
|
@@ -103,21 +103,25 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|
|
mcp: {},
|
|
|
mcp_resource: {},
|
|
|
formatter: [],
|
|
|
- vcs: undefined,
|
|
|
- path: { state: "", config: "", worktree: "", directory: "" },
|
|
|
workspaceList: [],
|
|
|
+ vcs: undefined,
|
|
|
})
|
|
|
|
|
|
+ const event = useEvent()
|
|
|
+ const project = useProject()
|
|
|
const sdk = useSDK()
|
|
|
|
|
|
async function syncWorkspaces() {
|
|
|
+ const workspace = project.workspace.current()
|
|
|
const result = await sdk.client.experimental.workspace.list().catch(() => undefined)
|
|
|
if (!result?.data) return
|
|
|
setStore("workspaceList", reconcile(result.data))
|
|
|
+ if (!result.data.some((item) => item.id === workspace)) {
|
|
|
+ project.workspace.set(undefined)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- sdk.event.listen((e) => {
|
|
|
- const event = e.details
|
|
|
+ event.subscribe((event) => {
|
|
|
switch (event.type) {
|
|
|
case "server.instance.disposed":
|
|
|
bootstrap()
|
|
|
@@ -344,7 +348,8 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|
|
}
|
|
|
|
|
|
case "lsp.updated": {
|
|
|
- sdk.client.lsp.status().then((x) => setStore("lsp", x.data!))
|
|
|
+ const workspace = project.workspace.current()
|
|
|
+ sdk.client.lsp.status({ workspace }).then((x) => setStore("lsp", x.data!))
|
|
|
break
|
|
|
}
|
|
|
|
|
|
@@ -360,25 +365,28 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|
|
|
|
|
async function bootstrap() {
|
|
|
console.log("bootstrapping")
|
|
|
+ const workspace = project.workspace.current()
|
|
|
const start = Date.now() - 30 * 24 * 60 * 60 * 1000
|
|
|
const sessionListPromise = sdk.client.session
|
|
|
- .list({ start: start })
|
|
|
+ .list({ start: start, workspace })
|
|
|
.then((x) => (x.data ?? []).toSorted((a, b) => a.id.localeCompare(b.id)))
|
|
|
|
|
|
// blocking - include session.list when continuing a session
|
|
|
- const providersPromise = sdk.client.config.providers({}, { throwOnError: true })
|
|
|
- const providerListPromise = sdk.client.provider.list({}, { throwOnError: true })
|
|
|
+ const providersPromise = sdk.client.config.providers({ workspace }, { throwOnError: true })
|
|
|
+ const providerListPromise = sdk.client.provider.list({ workspace }, { throwOnError: true })
|
|
|
const consoleStatePromise = sdk.client.experimental.console
|
|
|
- .get({}, { throwOnError: true })
|
|
|
+ .get({ workspace }, { throwOnError: true })
|
|
|
.then((x) => ConsoleState.parse(x.data))
|
|
|
.catch(() => emptyConsoleState)
|
|
|
- const agentsPromise = sdk.client.app.agents({}, { throwOnError: true })
|
|
|
- const configPromise = sdk.client.config.get({}, { throwOnError: true })
|
|
|
+ const agentsPromise = sdk.client.app.agents({ workspace }, { throwOnError: true })
|
|
|
+ const configPromise = sdk.client.config.get({ workspace }, { throwOnError: true })
|
|
|
+ const projectPromise = project.sync()
|
|
|
const blockingRequests: Promise<unknown>[] = [
|
|
|
providersPromise,
|
|
|
providerListPromise,
|
|
|
agentsPromise,
|
|
|
configPromise,
|
|
|
+ projectPromise,
|
|
|
...(args.continue ? [sessionListPromise] : []),
|
|
|
]
|
|
|
|
|
|
@@ -423,17 +431,18 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|
|
Promise.all([
|
|
|
...(args.continue ? [] : [sessionListPromise.then((sessions) => setStore("session", reconcile(sessions)))]),
|
|
|
consoleStatePromise.then((consoleState) => setStore("console_state", reconcile(consoleState))),
|
|
|
- sdk.client.command.list().then((x) => setStore("command", reconcile(x.data ?? []))),
|
|
|
- sdk.client.lsp.status().then((x) => setStore("lsp", reconcile(x.data!))),
|
|
|
- sdk.client.mcp.status().then((x) => setStore("mcp", reconcile(x.data!))),
|
|
|
- sdk.client.experimental.resource.list().then((x) => setStore("mcp_resource", reconcile(x.data ?? {}))),
|
|
|
- sdk.client.formatter.status().then((x) => setStore("formatter", reconcile(x.data!))),
|
|
|
- sdk.client.session.status().then((x) => {
|
|
|
+ sdk.client.command.list({ workspace }).then((x) => setStore("command", reconcile(x.data ?? []))),
|
|
|
+ sdk.client.lsp.status({ workspace }).then((x) => setStore("lsp", reconcile(x.data!))),
|
|
|
+ sdk.client.mcp.status({ workspace }).then((x) => setStore("mcp", reconcile(x.data!))),
|
|
|
+ sdk.client.experimental.resource
|
|
|
+ .list({ workspace })
|
|
|
+ .then((x) => setStore("mcp_resource", reconcile(x.data ?? {}))),
|
|
|
+ sdk.client.formatter.status({ workspace }).then((x) => setStore("formatter", reconcile(x.data!))),
|
|
|
+ sdk.client.session.status({ workspace }).then((x) => {
|
|
|
setStore("session_status", reconcile(x.data!))
|
|
|
}),
|
|
|
- sdk.client.provider.auth().then((x) => setStore("provider_auth", reconcile(x.data ?? {}))),
|
|
|
- sdk.client.vcs.get().then((x) => setStore("vcs", reconcile(x.data))),
|
|
|
- sdk.client.path.get().then((x) => setStore("path", reconcile(x.data!))),
|
|
|
+ sdk.client.provider.auth({ workspace }).then((x) => setStore("provider_auth", reconcile(x.data ?? {}))),
|
|
|
+ sdk.client.vcs.get({ workspace }).then((x) => setStore("vcs", reconcile(x.data))),
|
|
|
syncWorkspaces(),
|
|
|
]).then(() => {
|
|
|
setStore("status", "complete")
|
|
|
@@ -449,11 +458,17 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|
|
})
|
|
|
}
|
|
|
|
|
|
- onMount(() => {
|
|
|
- bootstrap()
|
|
|
- })
|
|
|
-
|
|
|
const fullSyncedSessions = new Set<string>()
|
|
|
+ createEffect(
|
|
|
+ on(
|
|
|
+ () => project.workspace.current(),
|
|
|
+ () => {
|
|
|
+ fullSyncedSessions.clear()
|
|
|
+ void bootstrap()
|
|
|
+ },
|
|
|
+ ),
|
|
|
+ )
|
|
|
+
|
|
|
const result = {
|
|
|
data: store,
|
|
|
set: setStore,
|
|
|
@@ -463,6 +478,9 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|
|
get ready() {
|
|
|
return store.status !== "loading"
|
|
|
},
|
|
|
+ get path() {
|
|
|
+ return project.instance.path()
|
|
|
+ },
|
|
|
session: {
|
|
|
get(sessionID: string) {
|
|
|
const match = Binary.search(store.session, sessionID, (s) => s.id)
|
|
|
@@ -481,11 +499,12 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|
|
},
|
|
|
async sync(sessionID: string) {
|
|
|
if (fullSyncedSessions.has(sessionID)) return
|
|
|
+ const workspace = project.workspace.current()
|
|
|
const [session, messages, todo, diff] = await Promise.all([
|
|
|
- sdk.client.session.get({ sessionID }, { throwOnError: true }),
|
|
|
- sdk.client.session.messages({ sessionID, limit: 100 }),
|
|
|
- sdk.client.session.todo({ sessionID }),
|
|
|
- sdk.client.session.diff({ sessionID }),
|
|
|
+ sdk.client.session.get({ sessionID, workspace }, { throwOnError: true }),
|
|
|
+ sdk.client.session.messages({ sessionID, limit: 100, workspace }),
|
|
|
+ sdk.client.session.todo({ sessionID, workspace }),
|
|
|
+ sdk.client.session.diff({ sessionID, workspace }),
|
|
|
])
|
|
|
setStore(
|
|
|
produce((draft) => {
|
|
|
@@ -504,8 +523,11 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
|
|
},
|
|
|
},
|
|
|
workspace: {
|
|
|
+ list() {
|
|
|
+ return store.workspaceList
|
|
|
+ },
|
|
|
get(workspaceID: string) {
|
|
|
- return store.workspaceList.find((workspace) => workspace.id === workspaceID)
|
|
|
+ return store.workspaceList.find((item) => item.id === workspaceID)
|
|
|
},
|
|
|
sync: syncWorkspaces,
|
|
|
},
|