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:
1 parent
e53ac36176
commit
0a40c55b3c
6 files changed
+30
-3
No files matched your search
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
IPC_CHANNELS,
|
||||
listThreadEventsSchema,
|
||||
listThreadParticipantsSchema,
|
||||
listThreadWaitStatesSchema,
|
||||
threadGetterSchema,
|
||||
} from "@shared/contracts";
|
||||
@@ -35,4 +36,14 @@ export function registerThreadHandlers({ registerHandle, db, ensureCompanyExists
|
||||
const waitStates = db.listThreadWaitStates(input.companyId, { resolvedOnly: input.resolvedOnly });
|
||||
return ok(waitStates);
|
||||
});
|
||||
|
||||
registerHandle(IPC_CHANNELS.listThreadParticipants, async (_event, payload) => {
|
||||
const input = listThreadParticipantsSchema.parse(payload);
|
||||
const companyError = ensureCompanyExists(input.companyId);
|
||||
if (companyError) return companyError;
|
||||
const thread = db.getThread(input.threadId, input.companyId);
|
||||
if (!thread) return fail("THREAD_NOT_FOUND", "Thread not found");
|
||||
const participants = db.listParticipants(input.threadId);
|
||||
return ok(participants);
|
||||
});
|
||||
}
|
||||
Reference in new issue
Block a user