fix(tui): open sessions by exact ID (#41180)

This commit is contained in:
Kit Langton
2026-08-07 22:29:09 -04:00
committed by GitHub
Unverified
parent 3a4772abb4
commit fd09760903
2 changed files with 48 additions and 1 deletions
+14 -1
View File
@@ -51,6 +51,17 @@ export function DialogOpen() {
.catch(() => [] as SessionInfo[]),
{ initialValue: [] },
)
const [matched] = createResource(
() => {
const value = filter().trim()
return /^ses_[0-9A-Za-z]{26}$/.test(value) ? value : undefined
},
(sessionID) =>
client.api.session
.get({ sessionID })
.then((session) => (session.id === sessionID ? session : undefined))
.catch(() => undefined),
)
const openTabs = createMemo(
() => new Set(sessionTabs.enabled() ? sessionTabs.tabs().map((tab) => tab.sessionID) : []),
@@ -60,7 +71,8 @@ export function DialogOpen() {
)
const sessions = createMemo(() => {
const seen = new Set<string>()
return [...data.session.list(), ...fetched()]
const match = matched()
return [...data.session.list(), ...fetched(), ...(match ? [match] : [])]
.filter((session) => {
if (session.parentID || seen.has(session.id)) return false
seen.add(session.id)
@@ -87,6 +99,7 @@ export function DialogOpen() {
data.session.family(session.id).some((id) => data.session.status(id) === "running")
return {
title: withTimestampedFallback(session),
searchText: session.id,
value: { type: "session", sessionID: session.id } as OpenTarget,
category: "Sessions",
footer: `${name ? `${Locale.truncate(name, 20)} · ` : ""}${timeAgo(session.time.updated)}`,
@@ -54,6 +54,40 @@ test("selecting an unhydrated session preserves its location", async () => {
}
})
test("finds and opens an exact session ID outside the recent list", async () => {
const sessionID = "ses_04a7a3d82ffeIphUJgd3SnEqiv"
const remote = { directory: "/tmp/opencode/archive", workspaceID: "ws_archive" }
const fixture = await renderOpen((url) => {
if (url.pathname === "/api/session") return json({ data: [], cursor: {} })
if (url.pathname !== `/api/session/${sessionID}`) return undefined
return json({
data: {
id: sessionID,
projectID: "proj_archive",
cost: 0,
tokens: { input: 0, output: 0, reasoning: 0, cache: { read: 0, write: 0 } },
time: { created: 1, updated: 2 },
title: "TUI plugin slot API v2",
location: remote,
},
})
})
try {
await fixture.app.waitForFrame((frame) => frame.includes("Search sessions and projects"))
await fixture.app.mockInput.typeText(sessionID)
await fixture.app.waitForFrame((frame) => frame.includes("TUI plugin slot API v2"))
fixture.app.mockInput.pressEnter()
await fixture.app.waitFor(() => fixture.route.data.type === "session")
expect(fixture.route.data).toEqual({ type: "session", sessionID })
expect(fixture.location.ref).toEqual(remote)
} finally {
fixture.dispose()
}
})
test("shows the current project and opens its root", async () => {
const root = "/tmp/opencode/project"
const subfolder = `${root}/packages/tui`