From 22ea7c3e2f41ecc92287ae306ab714f63c1b9e36 Mon Sep 17 00:00:00 2001 From: Vojta Bartos Date: Wed, 8 Apr 2026 15:47:56 +0200 Subject: [PATCH 1/2] chore(code): disable terminal tabs for cloud run --- .../panels/components/LeafNodeRenderer.tsx | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/apps/code/src/renderer/features/panels/components/LeafNodeRenderer.tsx b/apps/code/src/renderer/features/panels/components/LeafNodeRenderer.tsx index f556ed232..e27b529e1 100644 --- a/apps/code/src/renderer/features/panels/components/LeafNodeRenderer.tsx +++ b/apps/code/src/renderer/features/panels/components/LeafNodeRenderer.tsx @@ -40,16 +40,19 @@ export const LeafNodeRenderer: React.FC = ({ onAddTerminal, onSplitPanel, }) => { - const tabs = useTabInjection( - node.content.tabs, - node.id, - taskId, - task, - closeTab, - ); - const workspace = useWorkspace(taskId); const isCloud = workspace?.mode === "cloud"; + const inputTabs = useMemo( + () => + isCloud + ? node.content.tabs.filter((t) => t.data.type !== "terminal") + : node.content.tabs, + [node.content.tabs, isCloud], + ); + const tabs = useTabInjection(inputTabs, node.id, taskId, task, closeTab); + const activeTabId = tabs.some((t) => t.id === node.content.activeTabId) + ? node.content.activeTabId + : (tabs[0]?.id ?? node.content.activeTabId); const cloudEmptyState = useMemo( () => @@ -74,6 +77,7 @@ export const LeafNodeRenderer: React.FC = ({ const contentWithComponents = { ...node.content, tabs, + activeTabId, }; return ( @@ -87,7 +91,7 @@ export const LeafNodeRenderer: React.FC = ({ onPanelFocus={onPanelFocus} draggingTabId={draggingTabId} draggingTabPanelId={draggingTabPanelId} - onAddTerminal={() => onAddTerminal(node.id)} + onAddTerminal={isCloud ? undefined : () => onAddTerminal(node.id)} onSplitPanel={(direction) => onSplitPanel(node.id, direction)} emptyState={cloudEmptyState} /> From cc1980229ab84b75e7e7207945154c11f3bc5107 Mon Sep 17 00:00:00 2001 From: Vojta Bartos Date: Wed, 8 Apr 2026 16:00:36 +0200 Subject: [PATCH 2/2] chore(code): disable bash mode for cloud --- .../features/message-editor/components/MessageEditor.tsx | 3 +++ .../features/message-editor/tiptap/useTiptapEditor.ts | 3 ++- .../renderer/features/panels/components/LeafNodeRenderer.tsx | 5 ++--- .../src/renderer/features/workspace/hooks/useWorkspace.ts | 5 +++++ 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/code/src/renderer/features/message-editor/components/MessageEditor.tsx b/apps/code/src/renderer/features/message-editor/components/MessageEditor.tsx index 4e91c2f16..acf980213 100644 --- a/apps/code/src/renderer/features/message-editor/components/MessageEditor.tsx +++ b/apps/code/src/renderer/features/message-editor/components/MessageEditor.tsx @@ -3,6 +3,7 @@ import type { SessionConfigOption } from "@agentclientprotocol/sdk"; import { BranchSelector } from "@features/git-interaction/components/BranchSelector"; import { useGitQueries } from "@features/git-interaction/hooks/useGitQueries"; import { getUserPromptsForTask } from "@features/sessions/stores/sessionStore"; +import { useIsWorkspaceCloudRun } from "@features/workspace/hooks/useWorkspace"; import { useConnectivity } from "@hooks/useConnectivity"; import { ArrowUp, Circle, Stop } from "@phosphor-icons/react"; import { Flex, IconButton, Text, Tooltip } from "@radix-ui/themes"; @@ -169,6 +170,7 @@ export const MessageEditor = forwardRef( const clearFocusRequest = useDraftStore((s) => s.actions.clearFocusRequest); const { isOnline } = useConnectivity(); const taskId = context?.taskId; + const isCloud = useIsWorkspaceCloudRun(taskId); const disabled = context?.disabled ?? false; const isLoading = context?.isLoading ?? false; const repoPath = context?.repoPath; @@ -207,6 +209,7 @@ export const MessageEditor = forwardRef( autoFocus, context: { taskId, repoPath }, getPromptHistory, + capabilities: { bashMode: !isCloud }, onSubmit, onBashCommand, onBashModeChange, diff --git a/apps/code/src/renderer/features/message-editor/tiptap/useTiptapEditor.ts b/apps/code/src/renderer/features/message-editor/tiptap/useTiptapEditor.ts index 85165613e..ae101b0d2 100644 --- a/apps/code/src/renderer/features/message-editor/tiptap/useTiptapEditor.ts +++ b/apps/code/src/renderer/features/message-editor/tiptap/useTiptapEditor.ts @@ -464,7 +464,7 @@ export function useTiptapEditor(options: UseTiptapEditorOptions) { const text = editor.getText().trim(); - if (text.startsWith("!")) { + if (enableBashMode && text.startsWith("!")) { // Bash mode requires immediate execution, can't be queued if (isLoading) { toast.error("Cannot run shell commands while agent is generating"); @@ -492,6 +492,7 @@ export function useTiptapEditor(options: UseTiptapEditorOptions) { draft, clearOnSubmit, attachments, + enableBashMode, ]); submitRef.current = submit; diff --git a/apps/code/src/renderer/features/panels/components/LeafNodeRenderer.tsx b/apps/code/src/renderer/features/panels/components/LeafNodeRenderer.tsx index e27b529e1..3048b3f60 100644 --- a/apps/code/src/renderer/features/panels/components/LeafNodeRenderer.tsx +++ b/apps/code/src/renderer/features/panels/components/LeafNodeRenderer.tsx @@ -1,6 +1,6 @@ import { Cloud as CloudIcon } from "@phosphor-icons/react"; import { Flex, Text } from "@radix-ui/themes"; -import { useWorkspace } from "@renderer/features/workspace/hooks/useWorkspace"; +import { useIsWorkspaceCloudRun } from "@renderer/features/workspace/hooks/useWorkspace"; import type { Task } from "@shared/types"; import type React from "react"; import { useMemo } from "react"; @@ -40,8 +40,7 @@ export const LeafNodeRenderer: React.FC = ({ onAddTerminal, onSplitPanel, }) => { - const workspace = useWorkspace(taskId); - const isCloud = workspace?.mode === "cloud"; + const isCloud = useIsWorkspaceCloudRun(taskId); const inputTabs = useMemo( () => isCloud diff --git a/apps/code/src/renderer/features/workspace/hooks/useWorkspace.ts b/apps/code/src/renderer/features/workspace/hooks/useWorkspace.ts index d4f52225f..99c73e8e8 100644 --- a/apps/code/src/renderer/features/workspace/hooks/useWorkspace.ts +++ b/apps/code/src/renderer/features/workspace/hooks/useWorkspace.ts @@ -52,6 +52,11 @@ export function useWorkspace(taskId: string | undefined): Workspace | null { ); } +export function useIsWorkspaceCloudRun(taskId: string | undefined): boolean { + const workspace = useWorkspace(taskId); + return workspace?.mode === "cloud"; +} + export function useWorkspaceLoaded(): boolean { const { isFetched } = useWorkspacesQuery(); return isFetched;