fix(thread-panel): wire the scoped reply composer to real participants

The thread-panel composer was pinned to `channel="direct"` with no
`directParticipantIds` and no `replyTo`. Clicking reply in a human
review thread sent a message with no recipient and the send button
stayed disabled — a silent dead-end for the entire Co-Founder
review UX.

The fix exposes the thread's participant list to the renderer:

  - `listThreadParticipantsSchema` and the matching IPC channel
    (`agent-company:list-thread-participants`) return the rows from
    `conversation_participants` for a given thread.
  - `threadIntegration.onTaskCreated` / `onApprovalCreated` already
    enrol the owning agent and the virtual user on thread creation,
    so the list is populated without any backfill.
  - `ThreadPanel` loads participants alongside events and forwards
    the agent ids to `MessageComposer.directParticipantIds`. The
    composer's existing `directRecipientId` memo picks the first
    non-board agent, so replies now target the correct agent — or
    surface the "no recipient" notice when the thread has none.

The Board/user member is deliberately excluded from the list the
composer consumes: the composer wants an agent to route to. All
other wiring (wait-state precision, threadId) stays untouched.
This commit is contained in:
ZacharyZhang-NY committed 2026-04-19 01:19:23 -04:00
1 parent e53ac36176
commit 0a40c55b3c
6 files changed
+30 -3

No files matched your search

+1
View File
@@ -109,6 +109,7 @@ const api: DesktopApi = {
getThread: (input) => ipcRenderer.invoke(IPC_CHANNELS.getThread, input),
listThreadEvents: (input) => ipcRenderer.invoke(IPC_CHANNELS.listThreadEvents, input),
listThreadWaitStates: (input) => ipcRenderer.invoke(IPC_CHANNELS.listThreadWaitStates, input),
listThreadParticipants: (input) => ipcRenderer.invoke(IPC_CHANNELS.listThreadParticipants, input),
subscribe: (callback: (event: DesktopEvent) => void) => {
const listener = (_event: Electron.IpcRendererEvent, payload: DesktopEvent) => callback(payload);
ipcRenderer.on(IPC_CHANNELS.rendererEvent, listener);