| ... | @@ -368,6 +368,7 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -368,6 +368,7 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 368 | const textareaRef = useRef<HTMLTextAreaElement>(null); | 368 | const textareaRef = useRef<HTMLTextAreaElement>(null); |
| 369 | const composerCommandInputRef = useRef<HTMLInputElement>(null); | 369 | const composerCommandInputRef = useRef<HTMLInputElement>(null); |
| 370 | const composerImagesRef = useRef<ComposerImageAttachment[]>([]); | 370 | const composerImagesRef = useRef<ComposerImageAttachment[]>([]); |
| | 371 | const sendInFlightRef = useRef(false); |
| 371 | const dragDepthRef = useRef(0); | 372 | const dragDepthRef = useRef(0); |
| 372 | const terminalOpenByThreadRef = useRef<Record<string, boolean>>({}); | 373 | const terminalOpenByThreadRef = useRef<Record<string, boolean>>({}); |
| 373 | | 374 | |
| ... | @@ -1391,7 +1392,7 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -1391,7 +1392,7 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 1391 | const onSend = async (e: React.SubmitEvent | React.KeyboardEvent) => { | 1392 | const onSend = async (e: React.SubmitEvent | React.KeyboardEvent) => { |
| 1392 | e.preventDefault(); | 1393 | e.preventDefault(); |
| 1393 | const api = readNativeApi(); | 1394 | const api = readNativeApi(); |
| 1394 | if (!api || !activeThread || isSendBusy || isConnecting) return; | 1395 | if (!api || !activeThread || isSendBusy || isConnecting || sendInFlightRef.current) return; |
| 1395 | const trimmed = prompt.trim(); | 1396 | const trimmed = prompt.trim(); |
| 1396 | if (!trimmed && composerImages.length === 0) return; | 1397 | if (!trimmed && composerImages.length === 0) return; |
| 1397 | if (!activeProject) return; | 1398 | if (!activeProject) return; |
| ... | @@ -1415,6 +1416,9 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -1415,6 +1416,9 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 1415 | return; | 1416 | return; |
| 1416 | } | 1417 | } |
| 1417 | | 1418 | |
| | 1419 | sendInFlightRef.current = true; |
| | 1420 | setSendPhase(baseBranchForWorktree ? "preparing-worktree" : "sending-turn"); |
| | 1421 | |
| 1418 | const composerImagesSnapshot = [...composerImages]; | 1422 | const composerImagesSnapshot = [...composerImages]; |
| 1419 | const messageIdForSend = newMessageId(); | 1423 | const messageIdForSend = newMessageId(); |
| 1420 | const messageCreatedAt = new Date().toISOString(); | 1424 | const messageCreatedAt = new Date().toISOString(); |
| ... | @@ -1463,9 +1467,17 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -1463,9 +1467,17 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 1463 | branch: result.worktree.branch, | 1467 | branch: result.worktree.branch, |
| 1464 | worktreePath: result.worktree.path, | 1468 | worktreePath: result.worktree.path, |
| 1465 | }); | 1469 | }); |
| | 1470 | // Keep local thread state in sync immediately so terminal drawer opens |
| | 1471 | // with the worktree cwd/env instead of briefly using the project root. |
| | 1472 | dispatch({ |
| | 1473 | type: "SET_THREAD_BRANCH", |
| | 1474 | threadId: threadIdForSend, |
| | 1475 | branch: result.worktree.branch, |
| | 1476 | worktreePath: result.worktree.path, |
| | 1477 | }); |
| 1466 | const setupScript = setupProjectScript(activeProject.scripts); | 1478 | const setupScript = setupProjectScript(activeProject.scripts); |
| 1467 | if (setupScript) { | 1479 | if (setupScript) { |
| 1468 | void runProjectScript(setupScript, { | 1480 | await runProjectScript(setupScript, { |
| 1469 | cwd: result.worktree.path, | 1481 | cwd: result.worktree.path, |
| 1470 | worktreePath: result.worktree.path, | 1482 | worktreePath: result.worktree.path, |
| 1471 | rememberAsLastInvoked: false, | 1483 | rememberAsLastInvoked: false, |
| ... | @@ -1544,6 +1556,7 @@ export default function ChatView({ threadId }: ChatViewProps) { | ... | @@ -1544,6 +1556,7 @@ export default function ChatView({ threadId }: ChatViewProps) { |
| 1544 | err instanceof Error ? err.message : "Failed to send message.", | 1556 | err instanceof Error ? err.message : "Failed to send message.", |
| 1545 | ); | 1557 | ); |
| 1546 | } finally { | 1558 | } finally { |
| | 1559 | sendInFlightRef.current = false; |
| 1547 | setSendPhase("idle"); | 1560 | setSendPhase("idle"); |
| 1548 | } | 1561 | } |
| 1549 | }; | 1562 | }; |