Compare commits

...

5 Commits

Author SHA1 Message Date
James Long a221a11a2a fix warping from workspace to local project 2026-05-05 16:49:50 -04:00
James Long c1b05c95a7 fix type 2026-05-05 16:43:25 -04:00
James Long 181f6c5e4b fix test 2026-05-05 16:41:30 -04:00
James Long e55c52aa7f hide more if there are no more 2026-05-05 16:40:41 -04:00
James Long fa1dd21579 fix(core): filter only connected workspaces in dialog 2026-05-05 16:40:39 -04:00
3 changed files with 80 additions and 17 deletions
@@ -33,6 +33,24 @@ export type WorkspaceSelection =
type WorkspaceSelectValue = WorkspaceSelection | { type: "existing-list" }
type ExistingWorkspaceSelectValue = { workspace: Workspace }
export function recentConnectedWorkspaces<WorkspaceInfo extends { id: string }>(input: {
sessions: readonly { workspaceID?: string; time: { updated: number } }[]
get: (workspaceID: string) => WorkspaceInfo | undefined
status: (workspaceID: string) => string | undefined
limit?: number
}) {
const workspaces = input.sessions
.toSorted((a, b) => b.time.updated - a.time.updated)
.flatMap((session) => {
const workspace = session.workspaceID ? input.get(session.workspaceID) : undefined
return workspace && input.status(workspace.id) === "connected" ? [workspace] : []
})
.filter((workspace, index, list) => list.findIndex((item) => item.id === workspace.id) === index)
const recent = workspaces.slice(0, input.limit ?? 3)
return { recent, hasMore: recent.length < workspaces.length }
}
async function loadWorkspaceAdapters(input: {
sdk: ReturnType<typeof useSDK>
sync: ReturnType<typeof useSync>
@@ -77,7 +95,7 @@ export async function warpWorkspaceSession(input: {
}): Promise<boolean> {
const result = await input.sdk.client.experimental.workspace
.warp({
id: input.workspaceID ?? undefined,
id: input.workspaceID,
sessionID: input.sessionID,
})
.catch(() => undefined)
@@ -125,15 +143,11 @@ export function DialogWorkspaceSelect(props: {
const options = createMemo<DialogSelectOption<WorkspaceSelectValue>[]>(() => {
const list = adapters()
if (!list) return []
const recent = sync.data.session
.toSorted((a, b) => b.time.updated - a.time.updated)
.flatMap((session) => (session.workspaceID ? [session.workspaceID] : []))
.filter((workspaceID, index, list) => list.indexOf(workspaceID) === index)
.flatMap((workspaceID) => {
const workspace = project.workspace.get(workspaceID)
return workspace && project.workspace.status(workspace.id) === "connected" ? [workspace] : []
})
.slice(0, 3)
const { recent, hasMore } = recentConnectedWorkspaces({
sessions: sync.data.session,
get: project.workspace.get,
status: project.workspace.status,
})
return [
...list.map((adapter) => ({
title: adapter.name,
@@ -158,12 +172,16 @@ export function DialogWorkspaceSelect(props: {
},
category: "Choose workspace",
})),
{
title: "View all workspaces",
value: { type: "existing-list" as const },
description: "Choose from all workspaces",
category: "Choose workspace",
},
...(hasMore
? [
{
title: "View all workspaces",
value: { type: "existing-list" as const },
description: "Choose from all workspaces",
category: "Choose workspace",
},
]
: []),
]
})
@@ -0,0 +1,38 @@
import { describe, expect, test } from "bun:test"
import { recentConnectedWorkspaces } from "../../../../src/cli/cmd/tui/component/dialog-workspace-create"
describe("recentConnectedWorkspaces", () => {
test("returns unique connected workspaces after filtering missing and inactive entries", () => {
const workspaces = [
{ id: "wrk_a", name: "alpha" },
{ id: "wrk_b", name: "beta" },
{ id: "wrk_c", name: "gamma" },
{ id: "wrk_d", name: "delta" },
{ id: "wrk_e", name: "epsilon" },
]
const status = {
wrk_a: "connected",
wrk_b: "disconnected",
wrk_c: "error",
wrk_d: "connected",
wrk_e: "connected",
} as const
const { recent } = recentConnectedWorkspaces({
sessions: [
{ time: { updated: 900 } },
{ workspaceID: "wrk_b", time: { updated: 800 } },
{ workspaceID: "wrk_a", time: { updated: 700 } },
{ workspaceID: "wrk_a", time: { updated: 600 } },
{ workspaceID: "wrk_missing", time: { updated: 500 } },
{ workspaceID: "wrk_c", time: { updated: 400 } },
{ workspaceID: "wrk_d", time: { updated: 300 } },
{ workspaceID: "wrk_e", time: { updated: 200 } },
],
get: (workspaceID) => workspaces.find((workspace) => workspace.id === workspaceID),
status: (workspaceID) => status[workspaceID as keyof typeof status],
})
expect(recent.map((workspace) => workspace.id)).toEqual(["wrk_a", "wrk_d", "wrk_e"])
})
})
+8 -1
View File
@@ -8405,7 +8405,14 @@
"type": "object",
"properties": {
"id": {
"type": "string"
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
]
},
"sessionID": {
"type": "string"