Route work-product clicks through a resolver IPC

Filesystem work products store `external_id` as a workspace-relative
path so artifacts survive a workspace-root move, but the renderer was
handing that relative fragment straight to `shell.openPath`, which
needs an absolute managed path. Clicks flickered into a failed open.

Add a dedicated `openWorkProduct({ companyId, id })` IPC backed by
`resolveWorkProductTarget` on the DB layer. The resolver joins the
work-product row back to its originating task → workspace (or run →
workspace for taskless runs), composes an absolute path, and rejects
any relative fragment that would escape the workspace root. The
renderer now passes the work product's id — path resolution stays on
the main process where the managed-path policy already lives.
This commit is contained in:
ZacharyZhang-NY committed 2026-04-19 15:05:21 -04:00
1 parent 1a0fdc6f31
commit ff9a52324e
7 files changed
+113 -8

No files matched your search

+1
View File
@@ -9,6 +9,7 @@ const api: DesktopApi = {
loadSnapshot: () => ipcRenderer.invoke(IPC_CHANNELS.loadSnapshot),
pickDirectory: () => ipcRenderer.invoke(IPC_CHANNELS.pickDirectory),
openPath: (targetPath) => ipcRenderer.invoke(IPC_CHANNELS.openPath, targetPath),
openWorkProduct: (input) => ipcRenderer.invoke(IPC_CHANNELS.openWorkProduct, input),
saveCompany: (input) => ipcRenderer.invoke(IPC_CHANNELS.saveCompany, input),
setCurrentCompany: (companyId) => ipcRenderer.invoke(IPC_CHANNELS.setCurrentCompany, companyId),
saveConnector: (input) => ipcRenderer.invoke(IPC_CHANNELS.saveConnector, input),