Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions packages/types/src/global-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,11 @@ export const globalSettingsSchema = z.object({
includeTaskHistoryInEnhance: z.boolean().optional(),
historyPreviewCollapsed: z.boolean().optional(),
reasoningBlockCollapsed: z.boolean().optional(),
/**
* Whether to auto-expand diffs in "Roo wants to edit this file" chat messages.
* @default false
*/
autoExpandDiffs: z.boolean().optional(),
/**
* Controls the keyboard behavior for sending messages in the chat input.
* - "send": Enter sends message, Shift+Enter creates newline (default)
Expand Down
1 change: 1 addition & 0 deletions packages/types/src/vscode-extension-host.ts
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,7 @@ export type ExtensionState = Pick<
| "openRouterImageGenerationSelectedModel"
| "includeTaskHistoryInEnhance"
| "reasoningBlockCollapsed"
| "autoExpandDiffs"
| "enterBehavior"
| "includeCurrentTime"
| "includeCurrentCost"
Expand Down
44 changes: 44 additions & 0 deletions webview-ui/src/components/chat/ChatView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
cloudIsAuthenticated,
messageQueue = [],
showWorktreesInHomeScreen,
autoExpandDiffs,
} = useExtensionState()

// Show a WarningRow when the user sends a message with a retired provider.
Expand Down Expand Up @@ -1261,6 +1262,49 @@ const ChatViewComponent: React.ForwardRefRenderFunction<ChatViewRef, ChatViewPro
return result
}, [isCondensing, visibleMessages])

// Auto-expand diff tool messages when the autoExpandDiffs setting is enabled.
// This watches for new messages that contain file-edit diffs and marks them as expanded
// so users don't need to click on each collapsed diff block to review changes.
const DIFF_TOOL_NAMES = useMemo(
() =>
new Set([
"editedExistingFile",
"appliedDiff",
"newFileCreated",
"insertContent",
"searchAndReplace",
"search_and_replace",
]),
[],
)

useEffect(() => {
if (!autoExpandDiffs) return

const newExpansions: Record<number, boolean> = {}

for (const msg of groupedMessages) {
// Skip messages already tracked in expandedRows
if (expandedRows[msg.ts] !== undefined) continue

if (msg.type === "ask" && msg.ask === "tool") {
try {
const tool = JSON.parse(msg.text || "{}")
// Handle both single diff tools and batch diff messages
if (DIFF_TOOL_NAMES.has(tool.tool) || tool.tool === "batchDiffApproval") {
newExpansions[msg.ts] = true
}
} catch {
// ignore parse errors
}
}
}

if (Object.keys(newExpansions).length > 0) {
setExpandedRows((prev) => ({ ...prev, ...newExpansions }))
}
}, [autoExpandDiffs, groupedMessages, expandedRows, DIFF_TOOL_NAMES])

// Scroll lifecycle is managed by a dedicated hook to keep ChatView focused
// on message handling and UI orchestration.
const {
Expand Down
3 changes: 3 additions & 0 deletions webview-ui/src/components/settings/SettingsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
openRouterImageApiKey,
openRouterImageGenerationSelectedModel,
reasoningBlockCollapsed,
autoExpandDiffs,
enterBehavior,
includeCurrentTime,
includeCurrentCost,
Expand Down Expand Up @@ -412,6 +413,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
followupAutoApproveTimeoutMs,
includeTaskHistoryInEnhance: includeTaskHistoryInEnhance ?? true,
reasoningBlockCollapsed: reasoningBlockCollapsed ?? true,
autoExpandDiffs: autoExpandDiffs ?? false,
enterBehavior: enterBehavior ?? "send",
includeCurrentTime: includeCurrentTime ?? true,
includeCurrentCost: includeCurrentCost ?? true,
Expand Down Expand Up @@ -891,6 +893,7 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
{renderTab === "ui" && (
<UISettings
reasoningBlockCollapsed={reasoningBlockCollapsed ?? true}
autoExpandDiffs={autoExpandDiffs ?? false}
enterBehavior={enterBehavior ?? "send"}
setCachedStateField={setCachedStateField}
/>
Expand Down
24 changes: 24 additions & 0 deletions webview-ui/src/components/settings/UISettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import { ExtensionStateContextType } from "@/context/ExtensionStateContext"

interface UISettingsProps extends HTMLAttributes<HTMLDivElement> {
reasoningBlockCollapsed: boolean
autoExpandDiffs: boolean
enterBehavior: "send" | "newline"
setCachedStateField: SetCachedStateField<keyof ExtensionStateContextType>
}

export const UISettings = ({
reasoningBlockCollapsed,
autoExpandDiffs,
enterBehavior,
setCachedStateField,
...props
Expand All @@ -38,6 +40,10 @@ export const UISettings = ({
})
}

const handleAutoExpandDiffsChange = (value: boolean) => {
setCachedStateField("autoExpandDiffs", value)
}

const handleEnterBehaviorChange = (requireCtrlEnter: boolean) => {
const newBehavior = requireCtrlEnter ? "newline" : "send"
setCachedStateField("enterBehavior", newBehavior)
Expand Down Expand Up @@ -72,6 +78,24 @@ export const UISettings = ({
</div>
</SearchableSetting>

{/* Auto-Expand Diffs Setting */}
<SearchableSetting
settingId="ui-auto-expand-diffs"
section="ui"
label={t("settings:ui.autoExpandDiffs.label")}>
<div className="flex flex-col gap-1">
<VSCodeCheckbox
checked={autoExpandDiffs}
onChange={(e: any) => handleAutoExpandDiffsChange(e.target.checked)}
data-testid="auto-expand-diffs-checkbox">
<span className="font-medium">{t("settings:ui.autoExpandDiffs.label")}</span>
</VSCodeCheckbox>
<div className="text-vscode-descriptionForeground text-sm ml-5 mt-1">
{t("settings:ui.autoExpandDiffs.description")}
</div>
</div>
</SearchableSetting>

{/* Enter Key Behavior Setting */}
<SearchableSetting
settingId="ui-enter-behavior"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,7 @@ describe("SettingsView - Change Detection Fix", () => {
openRouterImageApiKey: undefined,
openRouterImageGenerationSelectedModel: undefined,
reasoningBlockCollapsed: true,
autoExpandDiffs: false,
...overrides,
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ describe("SettingsView - Unsaved Changes Detection", () => {
openRouterImageApiKey: undefined,
openRouterImageGenerationSelectedModel: undefined,
reasoningBlockCollapsed: true,
autoExpandDiffs: false,
}

beforeEach(() => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { UISettings } from "../UISettings"
describe("UISettings", () => {
const defaultProps = {
reasoningBlockCollapsed: false,
autoExpandDiffs: false,
enterBehavior: "send" as const,
setCachedStateField: vi.fn(),
}
Expand Down
2 changes: 2 additions & 0 deletions webview-ui/src/context/ExtensionStateContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
terminalZdotdir: false, // Default ZDOTDIR handling setting
historyPreviewCollapsed: false, // Initialize the new state (default to expanded)
reasoningBlockCollapsed: true, // Default to collapsed
autoExpandDiffs: false, // Default to collapsed diffs
enterBehavior: "send", // Default: Enter sends, Shift+Enter creates newline
cloudUserInfo: null,
cloudIsAuthenticated: false,
Expand Down Expand Up @@ -488,6 +489,7 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
const contextValue: ExtensionStateContextType = {
...state,
reasoningBlockCollapsed: state.reasoningBlockCollapsed ?? true,
autoExpandDiffs: state.autoExpandDiffs ?? false,
didHydrateState,
showWelcome,
theme,
Expand Down
4 changes: 4 additions & 0 deletions webview-ui/src/i18n/locales/en/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,10 @@
"label": "Collapse Thinking messages by default",
"description": "When enabled, thinking blocks will be collapsed by default until you interact with them"
},
"autoExpandDiffs": {
"label": "Auto-expand diffs in chat messages",
"description": "When enabled, file edit diffs will be automatically expanded instead of collapsed behind the filename"
},
"requireCtrlEnterToSend": {
"label": "Require {{primaryMod}}+Enter to send messages",
"description": "When enabled, you must press {{primaryMod}}+Enter to send messages instead of just Enter"
Expand Down
Loading