From e338f76c001e5bcace4f05bf0775ecd471631a2c Mon Sep 17 00:00:00 2001 From: Theo Browne Date: Tue, 21 Jul 2026 13:58:40 -0700 Subject: [PATCH 1/2] fix(web): keep composer editable while disconnected Co-Authored-By: Claude Fable 5 --- apps/web/src/components/chat/ChatComposer.tsx | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/apps/web/src/components/chat/ChatComposer.tsx b/apps/web/src/components/chat/ChatComposer.tsx index f3346b4100a..4cb737a27fd 100644 --- a/apps/web/src/components/chat/ChatComposer.tsx +++ b/apps/web/src/components/chat/ChatComposer.tsx @@ -1892,8 +1892,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) isConnecting || isComposerApprovalState || pendingUserInputs.length > 0 || - projectSelectionRequired || - (environmentUnavailable !== null && activePendingProgress === null) + projectSelectionRequired ) { return false; } @@ -2101,8 +2100,6 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) isComposerApprovalState, pendingUserInputs.length, projectSelectionRequired, - environmentUnavailable, - activePendingProgress, applyPromptReplacement, isComposerModelPickerOpen, readComposerSnapshot, @@ -2144,7 +2141,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) className={cn( "chat-composer-glass rounded-[20px] border transition-[background-color] duration-200 has-focus-visible:border-ring/45", isDragOverComposer ? "border-primary/70 bg-accent/45" : "border-border", - environmentUnavailable || projectSelectionRequired ? "opacity-75" : null, + projectSelectionRequired ? "opacity-75" : null, composerProviderState.composerSurfaceClassName, )} onFocusCapture={(event) => { @@ -2502,12 +2499,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) ? "Ask for follow-up changes or attach images" : "Ask anything, @tag files/folders, $use skills, or / for commands" } - disabled={ - isConnecting || - isComposerApprovalState || - projectSelectionRequired || - (environmentUnavailable !== null && activePendingProgress === null) - } + disabled={isConnecting || isComposerApprovalState || projectSelectionRequired} /> {showMobilePendingAnswerActions ? (
Date: Tue, 21 Jul 2026 14:03:57 -0700 Subject: [PATCH 2/2] fix(web): block send paths while environment is disconnected Co-Authored-By: Claude Fable 5 --- apps/web/src/components/chat/ChatComposer.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/apps/web/src/components/chat/ChatComposer.tsx b/apps/web/src/components/chat/ChatComposer.tsx index 4cb737a27fd..f35bff081e1 100644 --- a/apps/web/src/components/chat/ChatComposer.tsx +++ b/apps/web/src/components/chat/ChatComposer.tsx @@ -1159,6 +1159,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) isSendBusy || isConnecting || projectSelectionRequired || + environmentUnavailable !== null || !composerSendState.hasSendableContent; const collapsedComposerPrimaryActionLabel = "Send message"; const showMobilePendingAnswerActions = @@ -1697,7 +1698,9 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) const shouldBlurMobileComposerOnSubmit = useCallback(() => { if (!isMobileViewport) return false; - if (isSendBusy || isConnecting || phase === "running") return false; + if (isSendBusy || isConnecting || environmentUnavailable !== null || phase === "running") { + return false; + } if (activePendingProgress) { return activePendingProgress.isLastQuestion && Boolean(activePendingResolvedAnswers); } @@ -1706,6 +1709,7 @@ export const ChatComposer = memo(function ChatComposer(props: ChatComposerProps) activePendingProgress, activePendingResolvedAnswers, composerSendState.hasSendableContent, + environmentUnavailable, isConnecting, isMobileViewport, isSendBusy,