fix(app): route notification clicks through tabs (#44897)
deploy-posts / deploy (push) Waiting to run
deploy-www / deploy (push) Waiting to run
nix-hashes / compute-hash (blacksmith-4vcpu-ubuntu-2404, x86_64-linux) (push) Waiting to run
nix-hashes / compute-hash (blacksmith-4vcpu-ubuntu-2404-arm, aarch64-linux) (push) Waiting to run
nix-hashes / compute-hash (macos-15-intel, x86_64-darwin) (push) Waiting to run
nix-hashes / compute-hash (macos-latest, aarch64-darwin) (push) Waiting to run
nix-hashes / update-hashes (push) Blocked by required conditions
publish / version (push) Waiting to run
publish / build-cli (push) Blocked by required conditions
publish / sign-cli-macos (push) Blocked by required conditions
publish / build-node-app-archive (push) Blocked by required conditions
publish / build-node-cli (map[bun_install_flags:--cpu=* host:blacksmith-4vcpu-windows-2025 target:windows-arm64]) (push) Blocked by required conditions
publish / build-node-cli (map[host:blacksmith-4vcpu-ubuntu-2404 target:linux-x64]) (push) Blocked by required conditions
publish / build-node-cli (map[host:blacksmith-4vcpu-ubuntu-2404-arm target:linux-arm64]) (push) Blocked by required conditions
publish / build-node-cli (map[host:blacksmith-4vcpu-windows-2025 target:windows-x64]) (push) Blocked by required conditions
publish / build-node-cli (map[host:macos-26 target:darwin-arm64]) (push) Blocked by required conditions
publish / sign-cli-windows (push) Blocked by required conditions
publish / build-electron (map[bun_install_flags:--os=darwin --cpu=arm64 host:macos-26 platform_flag:--mac --arm64 target:aarch64-apple-darwin]) (push) Blocked by required conditions
publish / build-electron (map[bun_install_flags:--os=darwin --cpu=x64 host:macos-26-intel platform_flag:--mac --x64 target:x86_64-apple-darwin]) (push) Blocked by required conditions
publish / build-electron (map[host:blacksmith-4vcpu-ubuntu-2404 platform_flag:--linux target:x86_64-unknown-linux-gnu]) (push) Blocked by required conditions
publish / build-electron (map[host:blacksmith-4vcpu-ubuntu-2404-arm platform_flag:--linux --arm64 target:aarch64-unknown-linux-gnu]) (push) Blocked by required conditions
publish / build-electron (map[host:blacksmith-4vcpu-windows-2025 platform_flag:--win target:x86_64-pc-windows-msvc]) (push) Blocked by required conditions
publish / build-electron (map[host:windows-2025 platform_flag:--win --arm64 target:aarch64-pc-windows-msvc]) (push) Blocked by required conditions
publish / publish (push) Blocked by required conditions
typecheck / typecheck (push) Waiting to run

Co-authored-by: Brendonovich <14191578+Brendonovich@users.noreply.github.com>
This commit is contained in:
opencode-agent[bot]
2026-08-25 14:11:59 +08:00
committed by GitHub
parent 8c126e98da
commit 190f189fbe
2 changed files with 43 additions and 9 deletions
@@ -0,0 +1,26 @@
import { expect, test } from "bun:test"
import type { ServerConnection } from "@/runtime/server/registry"
import type { Tab } from "@/shell/tabs/tabs"
import { openNotificationSession } from "./notification"
test("opens notification sessions through the tab router", () => {
const server = "local\nhttp://localhost:4096" as ServerConnection.Key
const tab = { type: "session" as const, server, sessionId: "session-1" }
const calls: string[] = []
const tabs = {
addSessionTab: (input: Omit<typeof tab, "type">) => {
calls.push(`add:${input.sessionId}`)
return tab
},
rememberSessionRoute: (_tab: typeof tab, sessionID: string) => {
calls.push(`route:${sessionID}`)
},
select: (input: Tab) => {
calls.push(`select:${input.type === "session" ? input.sessionId : input.draftID}`)
},
}
openNotificationSession(tabs, server, "session-1")
expect(calls).toEqual(["add:session-1", "route:session-1", "select:session-1"])
})
@@ -51,6 +51,19 @@ type NotificationIndex = {
}
}
type NotificationTabs = Pick<ReturnType<typeof useTabs>, "addSessionTab" | "rememberSessionRoute" | "select">
export function openNotificationSession(
tabs: NotificationTabs,
server: ServerConnection.Key,
sessionID: string,
) {
const tab = tabs.addSessionTab({ server, sessionId: sessionID })
if (tab.type !== "session") return
tabs.rememberSessionRoute(tab, sessionID)
tabs.select(tab)
}
const MAX_NOTIFICATIONS = 500
const NOTIFICATION_TTL_MS = 1000 * 60 * 60 * 24 * 30
@@ -211,11 +224,6 @@ export function createServerNotificationState(input: { sdk: ServerSDK; data: Dat
return typeof location !== "undefined" && location.pathname === sessionHref(input.key, sessionID)
}
const navigate = (href: string) => {
history.pushState(null, "", href)
dispatchEvent(new PopStateEvent("popstate"))
}
const handleSessionIdle = (sessionID: string, eventID: string, time: number) => {
void lookup(sessionID).then((session) => {
if (meta.disposed) return
@@ -237,10 +245,9 @@ export function createServerNotificationState(input: { sdk: ServerSDK; data: Dat
session: sessionID,
})
const href = sessionHref(input.key, sessionID)
if (settings.notifications.agent()) {
void platform.notify(language.t("notification.session.responseReady.title"), session.title ?? sessionID, () =>
navigate(href),
openNotificationSession(tabs, input.key, sessionID),
)
}
})
@@ -274,9 +281,10 @@ export function createServerNotificationState(input: { sdk: ServerSDK; data: Dat
const description =
session?.title ??
(typeof error === "string" ? error : language.t("notification.session.error.fallbackDescription"))
const href = sessionHref(input.key, sessionID)
if (settings.notifications.errors()) {
void platform.notify(language.t("notification.session.error.title"), description, () => navigate(href))
void platform.notify(language.t("notification.session.error.title"), description, () =>
openNotificationSession(tabs, input.key, sessionID),
)
}
})
}