fix(tui): tui resiliency when workspace is dead, disable directory filter in session list (#23013)
This commit is contained in:
@@ -10,18 +10,21 @@ export const { use: useProject, provider: ProjectProvider } = createSimpleContex
|
||||
name: "Project",
|
||||
init: () => {
|
||||
const sdk = useSDK()
|
||||
|
||||
const defaultPath = {
|
||||
home: "",
|
||||
state: "",
|
||||
config: "",
|
||||
worktree: "",
|
||||
directory: sdk.directory ?? "",
|
||||
} satisfies Path
|
||||
|
||||
const [store, setStore] = createStore({
|
||||
project: {
|
||||
id: undefined as string | undefined,
|
||||
},
|
||||
instance: {
|
||||
path: {
|
||||
home: "",
|
||||
state: "",
|
||||
config: "",
|
||||
worktree: "",
|
||||
directory: sdk.directory ?? "",
|
||||
} satisfies Path,
|
||||
path: defaultPath,
|
||||
},
|
||||
workspace: {
|
||||
current: undefined as string | undefined,
|
||||
@@ -38,7 +41,7 @@ export const { use: useProject, provider: ProjectProvider } = createSimpleContex
|
||||
])
|
||||
|
||||
batch(() => {
|
||||
setStore("instance", "path", reconcile(path.data!))
|
||||
setStore("instance", "path", reconcile(path.data || defaultPath))
|
||||
setStore("project", "id", project.data?.id)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import { createSimpleContext } from "./helper"
|
||||
import type { Snapshot } from "@/snapshot"
|
||||
import { useExit } from "./exit"
|
||||
import { useArgs } from "./args"
|
||||
import { batch, createEffect, on } from "solid-js"
|
||||
import { batch, onMount } from "solid-js"
|
||||
import { Log } from "@/util"
|
||||
import { emptyConsoleState, type ConsoleState } from "@/config/console-state"
|
||||
|
||||
@@ -108,6 +108,9 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
||||
const project = useProject()
|
||||
const sdk = useSDK()
|
||||
|
||||
const fullSyncedSessions = new Set<string>()
|
||||
let syncedWorkspace = project.workspace.current()
|
||||
|
||||
event.subscribe((event) => {
|
||||
switch (event.type) {
|
||||
case "server.instance.disposed":
|
||||
@@ -350,9 +353,13 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
||||
const exit = useExit()
|
||||
const args = useArgs()
|
||||
|
||||
async function bootstrap() {
|
||||
console.log("bootstrapping")
|
||||
async function bootstrap(input: { fatal?: boolean } = {}) {
|
||||
const fatal = input.fatal ?? true
|
||||
const workspace = project.workspace.current()
|
||||
if (workspace !== syncedWorkspace) {
|
||||
fullSyncedSessions.clear()
|
||||
syncedWorkspace = workspace
|
||||
}
|
||||
const start = Date.now() - 30 * 24 * 60 * 60 * 1000
|
||||
const sessionListPromise = sdk.client.session
|
||||
.list({ start: start })
|
||||
@@ -441,20 +448,17 @@ export const { use: useSync, provider: SyncProvider } = createSimpleContext({
|
||||
name: e instanceof Error ? e.name : undefined,
|
||||
stack: e instanceof Error ? e.stack : undefined,
|
||||
})
|
||||
await exit(e)
|
||||
if (fatal) {
|
||||
await exit(e)
|
||||
} else {
|
||||
throw e
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const fullSyncedSessions = new Set<string>()
|
||||
createEffect(
|
||||
on(
|
||||
() => project.workspace.current(),
|
||||
() => {
|
||||
fullSyncedSessions.clear()
|
||||
void bootstrap()
|
||||
},
|
||||
),
|
||||
)
|
||||
onMount(() => {
|
||||
void bootstrap()
|
||||
})
|
||||
|
||||
const result = {
|
||||
data: store,
|
||||
|
||||
@@ -181,23 +181,30 @@ export function Session() {
|
||||
const sdk = useSDK()
|
||||
|
||||
createEffect(async () => {
|
||||
await sdk.client.session
|
||||
.get({ sessionID: route.sessionID }, { throwOnError: true })
|
||||
.then((x) => {
|
||||
project.workspace.set(x.data?.workspaceID)
|
||||
})
|
||||
.then(() => sync.session.sync(route.sessionID))
|
||||
.then(() => {
|
||||
if (scroll) scroll.scrollBy(100_000)
|
||||
})
|
||||
.catch((e) => {
|
||||
console.error(e)
|
||||
toast.show({
|
||||
message: `Session not found: ${route.sessionID}`,
|
||||
variant: "error",
|
||||
})
|
||||
return navigate({ type: "home" })
|
||||
const previousWorkspace = project.workspace.current()
|
||||
const result = await sdk.client.session.get({ sessionID: route.sessionID }, { throwOnError: true })
|
||||
if (!result.data) {
|
||||
toast.show({
|
||||
message: `Session not found: ${route.sessionID}`,
|
||||
variant: "error",
|
||||
})
|
||||
navigate({ type: "home" })
|
||||
return
|
||||
}
|
||||
|
||||
if (result.data.workspaceID !== previousWorkspace) {
|
||||
project.workspace.set(result.data.workspaceID)
|
||||
|
||||
// Sync all the data for this workspace. Note that this
|
||||
// workspace may not exist anymore which is why this is not
|
||||
// fatal. If it doesn't we still want to show the session
|
||||
// (which will be non-interactive)
|
||||
try {
|
||||
await sync.bootstrap({ fatal: false })
|
||||
} catch (e) {}
|
||||
}
|
||||
await sync.session.sync(route.sessionID)
|
||||
if (scroll) scroll.scrollBy(100_000)
|
||||
})
|
||||
|
||||
// Handle initial prompt from fork
|
||||
|
||||
Reference in New Issue
Block a user