From 29c3562910343459e471407099a98105e20fd0b6 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Tue, 14 Apr 2026 14:21:38 -0700 Subject: [PATCH 01/16] Polish session UI --- .../components/GeneratingIndicator.tsx | 6 +- .../sessions/components/SessionFooter.tsx | 50 +++--- .../components/session-update/UserMessage.tsx | 165 ++++++++++-------- 3 files changed, 113 insertions(+), 108 deletions(-) diff --git a/apps/code/src/renderer/features/sessions/components/GeneratingIndicator.tsx b/apps/code/src/renderer/features/sessions/components/GeneratingIndicator.tsx index 8fea0ef1d..e4a0c307a 100644 --- a/apps/code/src/renderer/features/sessions/components/GeneratingIndicator.tsx +++ b/apps/code/src/renderer/features/sessions/components/GeneratingIndicator.tsx @@ -152,11 +152,13 @@ export function GeneratingIndicator({ - {activity}... + + {activity}... + (Esc to stop diff --git a/apps/code/src/renderer/features/sessions/components/SessionFooter.tsx b/apps/code/src/renderer/features/sessions/components/SessionFooter.tsx index f32068d56..a60704c2c 100644 --- a/apps/code/src/renderer/features/sessions/components/SessionFooter.tsx +++ b/apps/code/src/renderer/features/sessions/components/SessionFooter.tsx @@ -1,5 +1,5 @@ import type { ContextUsage } from "@features/sessions/hooks/useContextUsage"; -import { Pause } from "@phosphor-icons/react"; +import { Brain, Pause } from "@phosphor-icons/react"; import { Box, Flex, Text } from "@radix-ui/themes"; import { ContextUsageIndicator } from "./ContextUsageIndicator"; @@ -71,36 +71,28 @@ export function SessionFooter({ const wasCancelled = lastStopReason === "cancelled" || lastStopReason === "refusal"; - if ( + const showDuration = lastGenerationDuration !== null && lastGenerationDuration > 0 && - !wasCancelled - ) { - return ( - - - - Generated in {formatDuration(lastGenerationDuration)} - - - - - ); - } + !wasCancelled; - if (usage) { - return ( - - - + return ( + + + + + {showDuration && ( + + Generated in {formatDuration(lastGenerationDuration)} + + )} - - ); - } - - return null; + + + + ); } diff --git a/apps/code/src/renderer/features/sessions/components/session-update/UserMessage.tsx b/apps/code/src/renderer/features/sessions/components/session-update/UserMessage.tsx index 403cdbc8e..1ae0b122f 100644 --- a/apps/code/src/renderer/features/sessions/components/session-update/UserMessage.tsx +++ b/apps/code/src/renderer/features/sessions/components/session-update/UserMessage.tsx @@ -9,6 +9,7 @@ import { SlackLogo, } from "@phosphor-icons/react"; import { Box, Flex, IconButton } from "@radix-ui/themes"; +import { motion } from "framer-motion"; import { useCallback, useEffect, useRef, useState } from "react"; import { hasFileMentions, @@ -68,91 +69,101 @@ export function UserMessage({ }, [content]); return ( - - {containsFileMentions ? ( - parseFileMentions(content) - ) : ( - - )} - {showAttachmentChips && ( - - {attachments.map((attachment) => ( - } - label={attachment.label} - /> - ))} - - )} - {!isExpanded && isOverflowing && ( - - )} - - {isOverflowing && ( - - )} - {sourceUrl && ( - - - View Slack thread - - )} - - {timestamp != null && ( - - {formatTimestamp(timestamp)} - + {showAttachmentChips && ( + + {attachments.map((attachment) => ( + } + label={attachment.label} + /> + ))} + + )} + {!isExpanded && isOverflowing && ( + + )} + + {isOverflowing && ( + )} - - - {copied ? : } - - + + View Slack thread + + )} + + {timestamp != null && ( + + {formatTimestamp(timestamp)} + + )} + + + {copied ? : } + + + - + ); } From 62847500815fe0cd41ef1561e8454cf0f8801c26 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Tue, 14 Apr 2026 14:27:39 -0700 Subject: [PATCH 02/16] Disable text selection on command center empty state --- .../features/command-center/components/CommandCenterPanel.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/code/src/renderer/features/command-center/components/CommandCenterPanel.tsx b/apps/code/src/renderer/features/command-center/components/CommandCenterPanel.tsx index 1f773a78c..2e24a8862 100644 --- a/apps/code/src/renderer/features/command-center/components/CommandCenterPanel.tsx +++ b/apps/code/src/renderer/features/command-center/components/CommandCenterPanel.tsx @@ -87,7 +87,7 @@ function EmptyCell({ cellIndex }: { cellIndex: number }) { return ( - + Date: Tue, 14 Apr 2026 14:35:36 -0700 Subject: [PATCH 03/16] Fix skills detail panel close button not working --- .../src/renderer/features/skills/components/SkillsView.tsx | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/code/src/renderer/features/skills/components/SkillsView.tsx b/apps/code/src/renderer/features/skills/components/SkillsView.tsx index 34d1a7bef..3dd88b242 100644 --- a/apps/code/src/renderer/features/skills/components/SkillsView.tsx +++ b/apps/code/src/renderer/features/skills/components/SkillsView.tsx @@ -29,11 +29,8 @@ export function SkillsView() { } = useSkillsSidebarStore(); const selectedSkill = useMemo(() => { - if (skills.length === 0) return null; - if (selectedPath !== null) { - return skills.find((s) => s.path === selectedPath) ?? skills[0]; - } - return skills[0]; + if (selectedPath === null || skills.length === 0) return null; + return skills.find((s) => s.path === selectedPath) ?? null; }, [skills, selectedPath]); const handleSelect = useCallback((path: string) => { From 893bcfc89c1bbcbe705c872b53f2ee45587a340f Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Tue, 14 Apr 2026 14:51:18 -0700 Subject: [PATCH 04/16] Remove diff stats from message editor --- .../components/MessageEditor.tsx | 35 ++----------------- 1 file changed, 2 insertions(+), 33 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 19973c11a..a6a9a7634 100644 --- a/apps/code/src/renderer/features/message-editor/components/MessageEditor.tsx +++ b/apps/code/src/renderer/features/message-editor/components/MessageEditor.tsx @@ -5,7 +5,7 @@ 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 { ArrowUp, Stop } from "@phosphor-icons/react"; import { Flex, IconButton, Text, Tooltip } from "@radix-ui/themes"; import { EditorContent } from "@tiptap/react"; import { hasOpenOverlay } from "@utils/overlay"; @@ -15,7 +15,6 @@ import { useDraftStore } from "../stores/draftStore"; import { useTiptapEditor } from "../tiptap/useTiptapEditor"; import type { EditorHandle } from "../types"; import { AttachmentsBar } from "./AttachmentsBar"; -import { DiffStatsIndicator } from "./DiffStatsIndicator"; import { EditorToolbar } from "./EditorToolbar"; import { ModeIndicatorInput } from "./ModeIndicatorInput"; @@ -26,11 +25,6 @@ interface ModeAndBranchRowProps { onModeChange?: () => void; repoPath?: string | null; cloudBranch?: string | null; - cloudDiffStats?: { - filesChanged: number; - linesAdded: number; - linesRemoved: number; - } | null; disabled?: boolean; isBashMode?: boolean; isCloud?: boolean; @@ -42,25 +36,16 @@ function ModeAndBranchRow({ onModeChange, repoPath, cloudBranch, - cloudDiffStats, disabled, isBashMode, isCloud, taskId, }: ModeAndBranchRowProps) { - const { currentBranch: gitBranch, diffStats } = useGitQueries( - repoPath ?? undefined, - ); + const { currentBranch: gitBranch } = useGitQueries(repoPath ?? undefined); const currentBranch = cloudBranch ?? gitBranch; const showModeIndicator = !!onModeChange; const showBranchSelector = !!currentBranch; - const effectiveDiffStats = cloudDiffStats ?? diffStats; - const showDiffStats = - effectiveDiffStats && - (effectiveDiffStats.filesChanged > 0 || - effectiveDiffStats.linesAdded > 0 || - effectiveDiffStats.linesRemoved > 0); if (!showModeIndicator && !showBranchSelector && !isBashMode) { return null; @@ -103,20 +88,6 @@ function ModeAndBranchRow({ wrap="nowrap" style={{ minWidth: 0, overflow: "hidden" }} > - - {showBranchSelector && showDiffStats && ( - - - - )} {showBranchSelector && ( ( const isLoading = context?.isLoading ?? false; const repoPath = context?.repoPath; const cloudBranch = context?.cloudBranch; - const cloudDiffStats = context?.cloudDiffStats; const isSubmitDisabled = disabled || !isOnline; const getPromptHistory = useCallback( @@ -361,7 +331,6 @@ export const MessageEditor = forwardRef( onModeChange={onModeChange} repoPath={repoPath} cloudBranch={cloudBranch} - cloudDiffStats={cloudDiffStats} disabled={disabled} isBashMode={isBashMode} isCloud={isCloud} From 3b73bc0d3aee8e6513d8e5732b967cf6639d599e Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Tue, 14 Apr 2026 14:53:35 -0700 Subject: [PATCH 05/16] Remove copy path and copy task id from task context menu --- apps/code/src/main/services/context-menu/service.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/apps/code/src/main/services/context-menu/service.ts b/apps/code/src/main/services/context-menu/service.ts index 1308e2a22..6d89f1a26 100644 --- a/apps/code/src/main/services/context-menu/service.ts +++ b/apps/code/src/main/services/context-menu/service.ts @@ -118,7 +118,6 @@ export class ContextMenuService { return this.showMenu([ this.item(isPinned ? "Unpin" : "Pin", { type: "pin" }), this.item("Rename", { type: "rename" }), - this.item("Copy Task ID", { type: "copy-task-id" }), ...(worktreePath ? [ this.separator(), @@ -273,11 +272,6 @@ export class ContextMenuService { const lastUsedApp = apps.find((app) => app.id === lastUsedAppId) || apps[0]; const openIn = (appId: string): T => ({ type: "external-app", action: { type: "open-in-app", appId } }) as T; - const copyPath: T = { - type: "external-app", - action: { type: "copy-path" }, - } as T; - return [ this.item(`Open in ${lastUsedApp.name}`, openIn(lastUsedApp.id)), { @@ -293,7 +287,6 @@ export class ContextMenuService { action: openIn(app.id), })), }, - this.item("Copy Path", copyPath, { accelerator: "CmdOrCtrl+Shift+C" }), ]; } From 1f0c0032627bc2975d8e345759e2c83b19a348b7 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Tue, 14 Apr 2026 18:26:26 -0700 Subject: [PATCH 06/16] latest --- .../sessions/components/ConversationView.tsx | 17 +++++++++++++++++ .../components/session-update/UserMessage.tsx | 6 ++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/apps/code/src/renderer/features/sessions/components/ConversationView.tsx b/apps/code/src/renderer/features/sessions/components/ConversationView.tsx index b5bacb4dc..259c51171 100644 --- a/apps/code/src/renderer/features/sessions/components/ConversationView.tsx +++ b/apps/code/src/renderer/features/sessions/components/ConversationView.tsx @@ -73,6 +73,19 @@ export function ConversationView({ } const firstUserMessageId = firstUserMessageIdRef.current; + const initialItemIdsRef = useRef | null>(null); + if (initialItemIdsRef.current === null) { + initialItemIdsRef.current = new Set( + conversationItems + .filter((i) => i.type === "user_message") + .map((i) => i.id), + ); + } + const hasMountedRef = useRef(false); + useEffect(() => { + hasMountedRef.current = true; + }, []); + const pendingPermissions = usePendingPermissionsForTask(taskId ?? ""); const pendingPermissionsCount = pendingPermissions.size; const queuedMessages = useQueuedMessagesForTask(taskId); @@ -148,6 +161,10 @@ export function ConversationView({ content={item.content} attachments={item.attachments} timestamp={item.timestamp} + animate={ + hasMountedRef.current && + !initialItemIdsRef.current?.has(item.id) + } sourceUrl={ slackThreadUrl && item.id === firstUserMessageId ? slackThreadUrl diff --git a/apps/code/src/renderer/features/sessions/components/session-update/UserMessage.tsx b/apps/code/src/renderer/features/sessions/components/session-update/UserMessage.tsx index 1ae0b122f..2edd0b34a 100644 --- a/apps/code/src/renderer/features/sessions/components/session-update/UserMessage.tsx +++ b/apps/code/src/renderer/features/sessions/components/session-update/UserMessage.tsx @@ -29,6 +29,7 @@ interface UserMessageProps { timestamp?: number; sourceUrl?: string; attachments?: UserMessageAttachment[]; + animate?: boolean; } function formatTimestamp(ts: number): string { @@ -47,6 +48,7 @@ export function UserMessage({ timestamp, sourceUrl, attachments = [], + animate = true, }: UserMessageProps) { const containsFileMentions = hasFileMentions(content); const showAttachmentChips = attachments.length > 0 && !containsFileMentions; @@ -70,9 +72,9 @@ export function UserMessage({ return ( Date: Tue, 14 Apr 2026 18:26:29 -0700 Subject: [PATCH 07/16] latest --- .../components/sections/CloudEnvironmentsSettings.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/code/src/renderer/features/settings/components/sections/CloudEnvironmentsSettings.tsx b/apps/code/src/renderer/features/settings/components/sections/CloudEnvironmentsSettings.tsx index ffaff5bc6..4455bae6f 100644 --- a/apps/code/src/renderer/features/settings/components/sections/CloudEnvironmentsSettings.tsx +++ b/apps/code/src/renderer/features/settings/components/sections/CloudEnvironmentsSettings.tsx @@ -130,7 +130,9 @@ function NetworkAccessSelect({ onChange: (v: NetworkAccessLevel) => void; }) { const [open, setOpen] = useState(false); - const current = NETWORK_ACCESS_OPTIONS.find((o) => o.value === value); + const current = + NETWORK_ACCESS_OPTIONS.find((o) => o.value === value) ?? + NETWORK_ACCESS_OPTIONS[0]; if (!current) { return null; From 17cbd7841c9f2bbf95df3c1fa9d74a81524641f4 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Wed, 15 Apr 2026 13:46:19 -0700 Subject: [PATCH 08/16] Update CloudEnvironmentsSettings.tsx --- .../components/sections/CloudEnvironmentsSettings.tsx | 4 ---- 1 file changed, 4 deletions(-) diff --git a/apps/code/src/renderer/features/settings/components/sections/CloudEnvironmentsSettings.tsx b/apps/code/src/renderer/features/settings/components/sections/CloudEnvironmentsSettings.tsx index 4455bae6f..e9489b4a6 100644 --- a/apps/code/src/renderer/features/settings/components/sections/CloudEnvironmentsSettings.tsx +++ b/apps/code/src/renderer/features/settings/components/sections/CloudEnvironmentsSettings.tsx @@ -134,10 +134,6 @@ function NetworkAccessSelect({ NETWORK_ACCESS_OPTIONS.find((o) => o.value === value) ?? NETWORK_ACCESS_OPTIONS[0]; - if (!current) { - return null; - } - return (
- ); -} diff --git a/apps/code/src/renderer/features/message-editor/stores/draftStore.ts b/apps/code/src/renderer/features/message-editor/stores/draftStore.ts index 1429e8a0e..e57eb3c9b 100644 --- a/apps/code/src/renderer/features/message-editor/stores/draftStore.ts +++ b/apps/code/src/renderer/features/message-editor/stores/draftStore.ts @@ -7,18 +7,11 @@ import type { EditorContent } from "../utils/content"; type SessionId = string; -export interface CloudDiffStats { - filesChanged: number; - linesAdded: number; - linesRemoved: number; -} - export interface EditorContext { sessionId: string; taskId: string | undefined; repoPath: string | null | undefined; cloudBranch?: string | null; - cloudDiffStats?: CloudDiffStats | null; disabled: boolean; isLoading: boolean; } @@ -87,7 +80,6 @@ export const useDraftStore = create()( taskId: context.taskId ?? existing?.taskId, repoPath: context.repoPath ?? existing?.repoPath, cloudBranch: context.cloudBranch ?? existing?.cloudBranch, - cloudDiffStats: context.cloudDiffStats ?? existing?.cloudDiffStats, disabled: context.disabled ?? existing?.disabled ?? false, isLoading: context.isLoading ?? existing?.isLoading ?? false, }; @@ -96,12 +88,6 @@ export const useDraftStore = create()( existing?.taskId === newContext.taskId && existing?.repoPath === newContext.repoPath && existing?.cloudBranch === newContext.cloudBranch && - existing?.cloudDiffStats?.filesChanged === - newContext.cloudDiffStats?.filesChanged && - existing?.cloudDiffStats?.linesAdded === - newContext.cloudDiffStats?.linesAdded && - existing?.cloudDiffStats?.linesRemoved === - newContext.cloudDiffStats?.linesRemoved && existing?.disabled === newContext.disabled && existing?.isLoading === newContext.isLoading ) { diff --git a/apps/code/src/renderer/features/sessions/components/SessionFooter.tsx b/apps/code/src/renderer/features/sessions/components/SessionFooter.tsx index a60704c2c..5a3c2ff56 100644 --- a/apps/code/src/renderer/features/sessions/components/SessionFooter.tsx +++ b/apps/code/src/renderer/features/sessions/components/SessionFooter.tsx @@ -79,9 +79,9 @@ export function SessionFooter({ return ( - - - {showDuration && ( + {showDuration && ( + + Generated in {formatDuration(lastGenerationDuration)} - )} - + + )} diff --git a/apps/code/src/renderer/features/sessions/components/SessionView.tsx b/apps/code/src/renderer/features/sessions/components/SessionView.tsx index b18f24631..0d94024a2 100644 --- a/apps/code/src/renderer/features/sessions/components/SessionView.tsx +++ b/apps/code/src/renderer/features/sessions/components/SessionView.tsx @@ -44,11 +44,6 @@ interface SessionViewProps { onCancelPrompt: () => void; repoPath?: string | null; cloudBranch?: string | null; - cloudDiffStats?: { - filesChanged: number; - linesAdded: number; - linesRemoved: number; - } | null; isSuspended?: boolean; onRestoreWorktree?: () => void; isRestoring?: boolean; @@ -79,7 +74,6 @@ export function SessionView({ onCancelPrompt, repoPath, cloudBranch, - cloudDiffStats, isSuspended = false, onRestoreWorktree, isRestoring = false, @@ -133,7 +127,6 @@ export function SessionView({ taskId, repoPath, cloudBranch, - cloudDiffStats, disabled: !isRunning, isLoading: !!isPromptPending, }); diff --git a/apps/code/src/renderer/features/sessions/components/session-update/UserMessage.tsx b/apps/code/src/renderer/features/sessions/components/session-update/UserMessage.tsx index 2edd0b34a..06fabfef4 100644 --- a/apps/code/src/renderer/features/sessions/components/session-update/UserMessage.tsx +++ b/apps/code/src/renderer/features/sessions/components/session-update/UserMessage.tsx @@ -64,10 +64,17 @@ export function UserMessage({ } }, []); + const copiedTimerRef = useRef>(undefined); + + useEffect(() => { + return () => clearTimeout(copiedTimerRef.current); + }, []); + const handleCopy = useCallback(() => { navigator.clipboard.writeText(content); setCopied(true); - setTimeout(() => setCopied(false), 2000); + clearTimeout(copiedTimerRef.current); + copiedTimerRef.current = setTimeout(() => setCopied(false), 2000); }, [content]); return ( diff --git a/apps/code/src/renderer/features/task-detail/components/TaskLogsPanel.tsx b/apps/code/src/renderer/features/task-detail/components/TaskLogsPanel.tsx index 1347c7347..965df1b36 100644 --- a/apps/code/src/renderer/features/task-detail/components/TaskLogsPanel.tsx +++ b/apps/code/src/renderer/features/task-detail/components/TaskLogsPanel.tsx @@ -1,11 +1,6 @@ import { BackgroundWrapper } from "@components/BackgroundWrapper"; import { ErrorBoundary } from "@components/ErrorBoundary"; import { useFolders } from "@features/folders/hooks/useFolders"; -import { - useCloudBranchChangedFiles, - useCloudPrChangedFiles, -} from "@features/git-interaction/hooks/useGitQueries"; -import { computeDiffStats } from "@features/git-interaction/utils/diffStats"; import { useDraftStore } from "@features/message-editor/stores/draftStore"; import { ProvisioningView } from "@features/provisioning/components/ProvisioningView"; import { useProvisioningStore } from "@features/provisioning/stores/provisioningStore"; @@ -23,7 +18,7 @@ import { import { Box, Flex } from "@radix-ui/themes"; import type { Task } from "@shared/types"; import { getTaskRepository } from "@utils/repository"; -import { useCallback, useEffect, useMemo } from "react"; +import { useCallback, useEffect } from "react"; interface TaskLogsPanelProps { taskId: string; @@ -81,27 +76,11 @@ export function TaskLogsPanel({ taskId, task, hideInput }: TaskLogsPanelProps) { handleBashCommand, } = useSessionCallbacks({ taskId, task, session, repoPath }); - const cloudOutput = session?.cloudOutput ?? null; - const prUrl = - isCloud && cloudOutput?.pr_url ? (cloudOutput.pr_url as string) : null; const slackThreadUrl = typeof task.latest_run?.state?.slack_thread_url === "string" ? task.latest_run.state.slack_thread_url : undefined; - const cloudRepo = isCloud ? (task.repository ?? null) : null; - const { data: prFiles } = useCloudPrChangedFiles(prUrl); - const { data: branchFiles } = useCloudBranchChangedFiles( - !prUrl ? cloudRepo : null, - !prUrl ? cloudBranch : null, - ); - const cloudDiffStats = useMemo(() => { - if (!isCloud) return null; - const files = prUrl ? prFiles : branchFiles; - if (!files || files.length === 0) return null; - return computeDiffStats(files); - }, [isCloud, prUrl, prFiles, branchFiles]); - useEffect(() => { requestFocus(taskId); }, [taskId, requestFocus]); @@ -152,7 +131,6 @@ export function TaskLogsPanel({ taskId, task, hideInput }: TaskLogsPanelProps) { onCancelPrompt={handleCancelPrompt} repoPath={repoPath} cloudBranch={cloudBranch} - cloudDiffStats={cloudDiffStats} hasError={hasError} errorTitle={errorTitle} errorMessage={errorMessage ?? undefined} diff --git a/apps/code/src/renderer/hooks/useTaskContextMenu.ts b/apps/code/src/renderer/hooks/useTaskContextMenu.ts index b3ccff57f..c57a2725d 100644 --- a/apps/code/src/renderer/hooks/useTaskContextMenu.ts +++ b/apps/code/src/renderer/hooks/useTaskContextMenu.ts @@ -8,7 +8,6 @@ import type { Task } from "@shared/types"; import { handleExternalAppAction } from "@utils/handleExternalAppAction"; import { logger } from "@utils/logger"; import { useCallback, useState } from "react"; -import { toast } from "sonner"; const log = logger.scope("context-menu"); @@ -70,10 +69,6 @@ export function useTaskContextMenu() { case "pin": onTogglePin?.(); break; - case "copy-task-id": - navigator.clipboard.writeText(task.id); - toast.success("Task ID copied"); - break; case "suspend": if (isSuspended) { await restoreTask(task.id); From 0449de74c168577ac422e49f622ea3f53b0ff846 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Wed, 15 Apr 2026 15:09:36 -0700 Subject: [PATCH 13/16] Move setContext call from render body into useEffect --- .../sessions/components/SessionView.tsx | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/apps/code/src/renderer/features/sessions/components/SessionView.tsx b/apps/code/src/renderer/features/sessions/components/SessionView.tsx index 0d94024a2..1ef6a2bd5 100644 --- a/apps/code/src/renderer/features/sessions/components/SessionView.tsx +++ b/apps/code/src/renderer/features/sessions/components/SessionView.tsx @@ -123,13 +123,24 @@ export function SessionView({ const sessionId = taskId ?? "default"; const setContext = useDraftStore((s) => s.actions.setContext); const requestFocus = useDraftStore((s) => s.actions.requestFocus); - setContext(sessionId, { + + useEffect(() => { + setContext(sessionId, { + taskId, + repoPath, + cloudBranch, + disabled: !isRunning, + isLoading: !!isPromptPending, + }); + }, [ + setContext, + sessionId, taskId, repoPath, cloudBranch, - disabled: !isRunning, - isLoading: !!isPromptPending, - }); + isRunning, + isPromptPending, + ]); useHotkeys( "shift+tab", From e84b20086e26efcf2dd28b56f4d8ce0fa9e0f9a4 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Wed, 15 Apr 2026 15:40:52 -0700 Subject: [PATCH 14/16] Rename auto-accept permissions to bypass permissions --- .../components/sections/ClaudeCodeSettings.tsx | 14 +++++++------- .../claude/permissions/permission-options.ts | 2 +- packages/agent/src/execution-mode.ts | 6 +++--- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/apps/code/src/renderer/features/settings/components/sections/ClaudeCodeSettings.tsx b/apps/code/src/renderer/features/settings/components/sections/ClaudeCodeSettings.tsx index 313d80022..092c7c4a0 100644 --- a/apps/code/src/renderer/features/settings/components/sections/ClaudeCodeSettings.tsx +++ b/apps/code/src/renderer/features/settings/components/sections/ClaudeCodeSettings.tsx @@ -178,7 +178,7 @@ export function ClaudeCodeSettings() { @@ -195,7 +195,7 @@ export function ClaudeCodeSettings() { - Auto-accept is enabled. All actions (shell commands, file edits, web + Bypass is enabled. All actions (shell commands, file edits, web requests) run without approval. Use shift+tab to cycle to this mode per session. @@ -211,16 +211,16 @@ export function ClaudeCodeSettings() { - Enable auto-accept permissions + Enable bypass permissions - With auto-accept enabled, Claude will execute every action - without asking — including shell commands, file edits, web - requests and any installed MCP tools. + With bypass enabled, Claude will execute every action without + asking -- including shell commands, file edits, web requests and + any installed MCP tools. This mode is intended for sandboxed environments (containers or @@ -228,7 +228,7 @@ export function ClaudeCodeSettings() { By proceeding, you accept all responsibility for actions taken - while auto-accept is enabled. + while bypass is enabled. diff --git a/packages/agent/src/adapters/claude/permissions/permission-options.ts b/packages/agent/src/adapters/claude/permissions/permission-options.ts index aed7a27cf..551be7c31 100644 --- a/packages/agent/src/adapters/claude/permissions/permission-options.ts +++ b/packages/agent/src/adapters/claude/permissions/permission-options.ts @@ -100,7 +100,7 @@ export function buildExitPlanModePermissionOptions(): PermissionOption[] { if (ALLOW_BYPASS) { options.push({ kind: "allow_always", - name: "Yes, auto-accept all permissions", + name: "Yes, bypass all permissions", optionId: "bypassPermissions", }); } diff --git a/packages/agent/src/execution-mode.ts b/packages/agent/src/execution-mode.ts index d3eba723d..57e93317c 100644 --- a/packages/agent/src/execution-mode.ts +++ b/packages/agent/src/execution-mode.ts @@ -35,8 +35,8 @@ const availableModes: ModeInfo[] = [ if (ALLOW_BYPASS) { availableModes.push({ id: "bypassPermissions", - name: "Auto-accept Permissions", - description: "Auto-accept all permission requests", + name: "Bypass Permissions", + description: "Bypass all permission prompts", }); } @@ -84,7 +84,7 @@ if (ALLOW_BYPASS) { codexModes.push({ id: "full-access", name: "Full Access", - description: "Auto-accept all permission requests", + description: "Bypass all permission prompts", }); } From fb4e6f0267c177268d46796242e8a88be4ce406c Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Wed, 15 Apr 2026 16:45:21 -0700 Subject: [PATCH 15/16] Update ConversationView.tsx --- .../sessions/components/ConversationView.tsx | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/apps/code/src/renderer/features/sessions/components/ConversationView.tsx b/apps/code/src/renderer/features/sessions/components/ConversationView.tsx index 259c51171..4f0542fd8 100644 --- a/apps/code/src/renderer/features/sessions/components/ConversationView.tsx +++ b/apps/code/src/renderer/features/sessions/components/ConversationView.tsx @@ -73,17 +73,17 @@ export function ConversationView({ } const firstUserMessageId = firstUserMessageIdRef.current; - const initialItemIdsRef = useRef | null>(null); - if (initialItemIdsRef.current === null) { - initialItemIdsRef.current = new Set( - conversationItems - .filter((i) => i.type === "user_message") - .map((i) => i.id), - ); - } - const hasMountedRef = useRef(false); + const [initialItemIds] = useState( + () => + new Set( + conversationItems + .filter((i) => i.type === "user_message") + .map((i) => i.id), + ), + ); + const [hasMounted, setHasMounted] = useState(false); useEffect(() => { - hasMountedRef.current = true; + setHasMounted(true); }, []); const pendingPermissions = usePendingPermissionsForTask(taskId ?? ""); @@ -161,10 +161,7 @@ export function ConversationView({ content={item.content} attachments={item.attachments} timestamp={item.timestamp} - animate={ - hasMountedRef.current && - !initialItemIdsRef.current?.has(item.id) - } + animate={hasMounted && !initialItemIds.has(item.id)} sourceUrl={ slackThreadUrl && item.id === firstUserMessageId ? slackThreadUrl @@ -211,7 +208,14 @@ export function ConversationView({ ); } }, - [repoPath, taskId, slackThreadUrl, firstUserMessageId], + [ + repoPath, + taskId, + slackThreadUrl, + firstUserMessageId, + hasMounted, + initialItemIds, + ], ); const getItemKey = useCallback((item: ConversationItem) => item.id, []); From 3b0d10802796531a3f23f2b18a0dff8356db1073 Mon Sep 17 00:00:00 2001 From: Charles Vien Date: Wed, 15 Apr 2026 16:51:24 -0700 Subject: [PATCH 16/16] Update ConversationView.tsx --- .../sessions/components/ConversationView.tsx | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/apps/code/src/renderer/features/sessions/components/ConversationView.tsx b/apps/code/src/renderer/features/sessions/components/ConversationView.tsx index 4f0542fd8..1de710ce5 100644 --- a/apps/code/src/renderer/features/sessions/components/ConversationView.tsx +++ b/apps/code/src/renderer/features/sessions/components/ConversationView.tsx @@ -81,10 +81,6 @@ export function ConversationView({ .map((i) => i.id), ), ); - const [hasMounted, setHasMounted] = useState(false); - useEffect(() => { - setHasMounted(true); - }, []); const pendingPermissions = usePendingPermissionsForTask(taskId ?? ""); const pendingPermissionsCount = pendingPermissions.size; @@ -161,7 +157,7 @@ export function ConversationView({ content={item.content} attachments={item.attachments} timestamp={item.timestamp} - animate={hasMounted && !initialItemIds.has(item.id)} + animate={!initialItemIds.has(item.id)} sourceUrl={ slackThreadUrl && item.id === firstUserMessageId ? slackThreadUrl @@ -208,14 +204,7 @@ export function ConversationView({ ); } }, - [ - repoPath, - taskId, - slackThreadUrl, - firstUserMessageId, - hasMounted, - initialItemIds, - ], + [repoPath, taskId, slackThreadUrl, firstUserMessageId, initialItemIds], ); const getItemKey = useCallback((item: ConversationItem) => item.id, []);