TL;DR — Clicking a desktop notification never navigates to the conversation that produced it: the notification carries no conversation identity, and nothing in the app consumes the click. Everything codeg has for "jump to a conversation" is bound to the local main window and the local database, so a conversation living in a remote-workspace window cannot be reached by notifications — or by codeg:// deep links — at all.
现状
codeg 0.31.2,macOS 15.7.8(Build 24G824)。
代理在后台跑完一轮(或需要权限确认、提问、报错、后台任务结束)时,系统通知正常弹出;但点它只是把 codeg 激活到原来那个标签页,不会切到产生这条通知的会话。多会话并行时几乎没法靠通知定位。
用了「打开远端工作区」之后更彻底:那种会话在另一个窗口里,点通知无论落在哪个窗口都到不了,也没有别的入口能直达。
复现
开两个会话 A、B,停在 A,把 codeg 切到后台,等 B 跑完 → 收到通知。
点通知 → codeg 被前置,但仍停在 A,不会切到 B。
「打开远端工作区」开一个远端窗口,在其中的会话跑完 → 通知照常弹出;点它 → 仍停在原窗口原标签,那个远端会话没有任何入口能直达。
代码层面:通知没有会话定位,点击也没有接收方
src-tauri/src/commands/notification.rs:157 send_notification(app, title, body);macOS 分支(:162-181)是
mac_notification_sys::Notification::default().title(&title).message(&body).send() —— 即发即忘,没有 wait_for_click,也没有按钮/动作,所以这次点击 codeg 根本收不到。该 crate 自身支持 wait_for_click(true) 并在 send() 返回 NotificationResponse(ActivationType、按钮名等),只是没有使用。
各调用点传的都是固定文案:src/contexts/acp-connections-context.tsx:4648(turn_complete)、:4352(permission_request)、:4161(question_request)、:4276(background_task)、:4801(error),以及 src/contexts/tasks-view-context.tsx:185(work_task)。统一走 notifyDesktop(eventId, {title, body, redactedBody}),没有任何 folderId / conversationId / external session id 。
全仓没有「通知被点击」的处理。macOS 侧唯一与「App 被激活」有关的是 src-tauri/src/lib.rs:2056 的 RunEvent::Reopen(点 Dock 图标),它只调 windows::show_main_window(commands/windows.rs:2341)→ 显示 label 为 main 的窗口。
代码层面:现有「跳到会话」的通道只认本地 main 窗口
即使把点击接上,下面这些通道也到不了远端工作区窗口里的会话:
focus_conversation(src-tauri/src/commands/windows.rs:1791):show_main_window()(:1797)+ emit_to("main", "workspace://focus-conversation", …)(:1803)——只投递给 main。
codeg://session/<id>(src-tauri/src/deep_link.rs:170、:256):用本地 AppDatabase(:265)解析,然后同样 show_main_window + emit_to("main", …)(:290-291)。
远端工作区窗口是另一个 label remote-workspace-<id>(src-tauri/src/commands/remote_workspace.rs:186-215),并且在这种窗口里深链被主动关掉:src/lib/deep-link.ts:24-25(isRemoteDesktopMode() → return null,因为 codeg-server 没注册该命令)。docs/url-scheme.md 也写明 server/浏览器模式不提供 scheme,只能用 /workspace?folderId=&conversationId=&agent= 查询串。
由此还有一个小副作用:在远端工作区窗口里点一条 codeg://session/<id>,会拿本地 库按同一个数字 id 去解析,可能命中另一个本地会话(或什么都不发生)。
浏览器 / 网页模式同样不会跳转:src/lib/notification.ts:122 是 new ctor(title, { body }),没有 onclick。
期望
通知携带会话定位(folderId / conversationId / agent,或 agent 的 external session id),点击后切到该会话;
跳转投递到发出这条通知的那个窗口 (main 或 remote-workspace-<id>),而不是写死 main;
平台差异:macOS 用 mac_notification_sys 的 wait_for_click + NotificationResponse(注意别阻塞主线程,放在 spawn_blocking 里,每条通知一个等待);Windows 走 toast 激活(feat: add native task status notifications #445 已有方案);Linux 视后端能力,拿不到就明确降级并在文档里写清楚;
浏览器模式用 Notification.onclick,配合已有的 /workspace?folderId=&conversationId=&agent=(DeepLinkBootstrap 已经有这条路径)。
相关
(说明:macOS 点击通知后具体把哪个窗口带到前台由系统决定,这一点无法从 codeg 代码里断言;可以确定的是 codeg 没有消费这次点击,也没有按窗口投递过定位信息。)
TL;DR — Clicking a desktop notification never navigates to the conversation that produced it: the notification carries no conversation identity, and nothing in the app consumes the click. Everything codeg has for "jump to a conversation" is bound to the local
mainwindow and the local database, so a conversation living in a remote-workspace window cannot be reached by notifications — or bycodeg://deep links — at all.现状
codeg 0.31.2,macOS 15.7.8(Build 24G824)。
代理在后台跑完一轮(或需要权限确认、提问、报错、后台任务结束)时,系统通知正常弹出;但点它只是把 codeg 激活到原来那个标签页,不会切到产生这条通知的会话。多会话并行时几乎没法靠通知定位。
用了「打开远端工作区」之后更彻底:那种会话在另一个窗口里,点通知无论落在哪个窗口都到不了,也没有别的入口能直达。
复现
代码层面:通知没有会话定位,点击也没有接收方
src-tauri/src/commands/notification.rs:157send_notification(app, title, body);macOS 分支(:162-181)是mac_notification_sys::Notification::default().title(&title).message(&body).send()—— 即发即忘,没有wait_for_click,也没有按钮/动作,所以这次点击 codeg 根本收不到。该 crate 自身支持wait_for_click(true)并在send()返回NotificationResponse(ActivationType、按钮名等),只是没有使用。src/contexts/acp-connections-context.tsx:4648(turn_complete)、:4352(permission_request)、:4161(question_request)、:4276(background_task)、:4801(error),以及src/contexts/tasks-view-context.tsx:185(work_task)。统一走notifyDesktop(eventId, {title, body, redactedBody}),没有任何 folderId / conversationId / external session id。src-tauri/src/lib.rs:2056的RunEvent::Reopen(点 Dock 图标),它只调windows::show_main_window(commands/windows.rs:2341)→ 显示 label 为main的窗口。代码层面:现有「跳到会话」的通道只认本地 main 窗口
即使把点击接上,下面这些通道也到不了远端工作区窗口里的会话:
focus_conversation(src-tauri/src/commands/windows.rs:1791):show_main_window()(:1797)+emit_to("main", "workspace://focus-conversation", …)(:1803)——只投递给main。codeg://session/<id>(src-tauri/src/deep_link.rs:170、:256):用本地AppDatabase(:265)解析,然后同样show_main_window+emit_to("main", …)(:290-291)。remote-workspace-<id>(src-tauri/src/commands/remote_workspace.rs:186-215),并且在这种窗口里深链被主动关掉:src/lib/deep-link.ts:24-25(isRemoteDesktopMode()→return null,因为codeg-server没注册该命令)。docs/url-scheme.md也写明 server/浏览器模式不提供 scheme,只能用/workspace?folderId=&conversationId=&agent=查询串。codeg://session/<id>,会拿本地库按同一个数字 id 去解析,可能命中另一个本地会话(或什么都不发生)。浏览器 / 网页模式同样不会跳转:
src/lib/notification.ts:122是new ctor(title, { body }),没有onclick。期望
main或remote-workspace-<id>),而不是写死main;mac_notification_sys的wait_for_click+NotificationResponse(注意别阻塞主线程,放在spawn_blocking里,每条通知一个等待);Windows 走 toast 激活(feat: add native task status notifications #445 已有方案);Linux 视后端能力,拿不到就明确降级并在文档里写清楚;Notification.onclick,配合已有的/workspace?folderId=&conversationId=&agent=(DeepLinkBootstrap已经有这条路径)。相关
(说明:macOS 点击通知后具体把哪个窗口带到前台由系统决定,这一点无法从 codeg 代码里断言;可以确定的是 codeg 没有消费这次点击,也没有按窗口投递过定位信息。)