@@ -455,10 +455,18 @@ async function closeExistingCompose(conn: SuperhumanConnection): Promise<void> {
455455 */
456456async function openComposeWithCommand (
457457 conn : SuperhumanConnection ,
458- commandId : string
458+ commandId : string ,
459+ threadId ?: string
459460) : Promise < string | null > {
460461 await closeExistingCompose ( conn ) ;
461- await syncThreadId ( conn ) ;
462+
463+ // If a specific threadId is provided, set it before invoking the command
464+ if ( threadId ) {
465+ await setThreadForReply ( conn , threadId ) ;
466+ await new Promise ( ( r ) => setTimeout ( r , 300 ) ) ; // Give UI time to update
467+ } else {
468+ await syncThreadId ( conn ) ;
469+ }
462470
463471 const invoked = await invokeCommand ( conn , commandId ) ;
464472 if ( ! invoked ) {
@@ -469,6 +477,40 @@ async function openComposeWithCommand(
469477 return getDraftKey ( conn ) ;
470478}
471479
480+ /**
481+ * Set a specific thread ID in the ViewState for reply operations
482+ *
483+ * This sets both threadPane.threadId and threadListView.threadId to ensure
484+ * the reply commands work correctly regardless of what's currently visible.
485+ */
486+ export async function setThreadForReply ( conn : SuperhumanConnection , threadId : string ) : Promise < boolean > {
487+ const { Runtime } = conn ;
488+
489+ const result = await Runtime . evaluate ( {
490+ expression : `
491+ (() => {
492+ try {
493+ const tree = window.ViewState?.tree;
494+ if (!tree?.set) return false;
495+
496+ const targetThreadId = ${ JSON . stringify ( threadId ) } ;
497+
498+ // Set both threadPane and threadListView to the target thread
499+ tree.set(['threadPane', 'threadId'], targetThreadId);
500+ tree.set(['threadListView', 'threadId'], targetThreadId);
501+
502+ return true;
503+ } catch (e) {
504+ return false;
505+ }
506+ })()
507+ ` ,
508+ returnByValue : true ,
509+ } ) ;
510+
511+ return result . result . value === true ;
512+ }
513+
472514/**
473515 * Sync threadListView.threadId with threadPane.threadId
474516 *
@@ -507,27 +549,36 @@ export async function syncThreadId(conn: SuperhumanConnection): Promise<boolean>
507549 *
508550 * This uses the REPLY_ALL_POP_OUT command which properly sets up threading,
509551 * recipients, and subject automatically.
552+ *
553+ * @param conn - The Superhuman connection
554+ * @param threadId - Optional thread ID to reply to (if not provided, uses current thread)
510555 */
511- export async function openReplyAllCompose ( conn : SuperhumanConnection ) : Promise < string | null > {
512- return openComposeWithCommand ( conn , "REPLY_ALL_POP_OUT" ) ;
556+ export async function openReplyAllCompose ( conn : SuperhumanConnection , threadId ?: string ) : Promise < string | null > {
557+ return openComposeWithCommand ( conn , "REPLY_ALL_POP_OUT" , threadId ) ;
513558}
514559
515560/**
516561 * Open a reply compose using Superhuman's native command.
517562 *
518563 * This uses the REPLY_POP_OUT command which properly sets up threading,
519564 * recipient (original sender only), and subject automatically.
565+ *
566+ * @param conn - The Superhuman connection
567+ * @param threadId - Optional thread ID to reply to (if not provided, uses current thread)
520568 */
521- export async function openReplyCompose ( conn : SuperhumanConnection ) : Promise < string | null > {
522- return openComposeWithCommand ( conn , "REPLY_POP_OUT" ) ;
569+ export async function openReplyCompose ( conn : SuperhumanConnection , threadId ?: string ) : Promise < string | null > {
570+ return openComposeWithCommand ( conn , "REPLY_POP_OUT" , threadId ) ;
523571}
524572
525573/**
526574 * Open a forward compose using Superhuman's native command.
527575 *
528576 * This uses the FORWARD_POP_OUT command which properly sets up the
529577 * forwarded message content and subject automatically.
578+ *
579+ * @param conn - The Superhuman connection
580+ * @param threadId - Optional thread ID to forward (if not provided, uses current thread)
530581 */
531- export async function openForwardCompose ( conn : SuperhumanConnection ) : Promise < string | null > {
532- return openComposeWithCommand ( conn , "FORWARD_POP_OUT" ) ;
582+ export async function openForwardCompose ( conn : SuperhumanConnection , threadId ?: string ) : Promise < string | null > {
583+ return openComposeWithCommand ( conn , "FORWARD_POP_OUT" , threadId ) ;
533584}
0 commit comments