mirror of
https://github.com/RooVetGit/Roo-Code.git
synced 2026-08-28 05:27:24 +00:00
Revert "feat: add task header highlight for visual status indication (#11305)"
This reverts commit 5313cb503a.
629 lines
27 KiB
TypeScript
629 lines
27 KiB
TypeScript
import React, { createContext, useCallback, useContext, useEffect, useState } from "react"
|
|
|
|
import {
|
|
type ProviderSettings,
|
|
type ProviderSettingsEntry,
|
|
type CustomModePrompts,
|
|
type ModeConfig,
|
|
type ExperimentId,
|
|
type TodoItem,
|
|
type TelemetrySetting,
|
|
type OrganizationAllowList,
|
|
type CloudOrganizationMembership,
|
|
type ExtensionMessage,
|
|
type ExtensionState,
|
|
type MarketplaceInstalledMetadata,
|
|
type Command,
|
|
type McpServer,
|
|
type SkillMetadata,
|
|
RouterModels,
|
|
ORGANIZATION_ALLOW_ALL,
|
|
DEFAULT_CHECKPOINT_TIMEOUT_SECONDS,
|
|
} from "@roo-code/types"
|
|
|
|
import { findLastIndex } from "@roo/array"
|
|
|
|
import { checkExistKey } from "@roo/checkExistApiConfig"
|
|
import { Mode, defaultModeSlug, defaultPrompts } from "@roo/modes"
|
|
import { CustomSupportPrompts } from "@roo/support-prompt"
|
|
import { experimentDefault } from "@roo/experiments"
|
|
|
|
import { vscode } from "@src/utils/vscode"
|
|
import { convertTextMateToHljs } from "@src/utils/textMateToHljs"
|
|
|
|
export interface ExtensionStateContextType extends ExtensionState {
|
|
historyPreviewCollapsed?: boolean // Add the new state property
|
|
didHydrateState: boolean
|
|
showWelcome: boolean
|
|
theme: any
|
|
mcpServers: McpServer[]
|
|
hasSystemPromptOverride?: boolean
|
|
currentCheckpoint?: string
|
|
currentTaskTodos?: TodoItem[] // Initial todos for the current task
|
|
filePaths: string[]
|
|
openedTabs: Array<{ label: string; isActive: boolean; path?: string }>
|
|
commands: Command[]
|
|
skills: SkillMetadata[]
|
|
organizationAllowList: OrganizationAllowList
|
|
organizationSettingsVersion: number
|
|
cloudIsAuthenticated: boolean
|
|
cloudOrganizations?: CloudOrganizationMembership[]
|
|
sharingEnabled: boolean
|
|
publicSharingEnabled: boolean
|
|
mdmCompliant?: boolean
|
|
hasOpenedModeSelector: boolean // New property to track if user has opened mode selector
|
|
setHasOpenedModeSelector: (value: boolean) => void // Setter for the new property
|
|
alwaysAllowFollowupQuestions: boolean // New property for follow-up questions auto-approve
|
|
setAlwaysAllowFollowupQuestions: (value: boolean) => void // Setter for the new property
|
|
followupAutoApproveTimeoutMs: number | undefined // Timeout in ms for auto-approving follow-up questions
|
|
setFollowupAutoApproveTimeoutMs: (value: number) => void // Setter for the timeout
|
|
marketplaceItems?: any[]
|
|
marketplaceInstalledMetadata?: MarketplaceInstalledMetadata
|
|
profileThresholds: Record<string, number>
|
|
setProfileThresholds: (value: Record<string, number>) => void
|
|
setApiConfiguration: (config: ProviderSettings) => void
|
|
setCustomInstructions: (value?: string) => void
|
|
setAlwaysAllowReadOnly: (value: boolean) => void
|
|
setAlwaysAllowReadOnlyOutsideWorkspace: (value: boolean) => void
|
|
setAlwaysAllowWrite: (value: boolean) => void
|
|
setAlwaysAllowWriteOutsideWorkspace: (value: boolean) => void
|
|
setAlwaysAllowExecute: (value: boolean) => void
|
|
setAlwaysAllowBrowser: (value: boolean) => void
|
|
setAlwaysAllowMcp: (value: boolean) => void
|
|
setAlwaysAllowModeSwitch: (value: boolean) => void
|
|
setAlwaysAllowSubtasks: (value: boolean) => void
|
|
setBrowserToolEnabled: (value: boolean) => void
|
|
setShowRooIgnoredFiles: (value: boolean) => void
|
|
setEnableSubfolderRules: (value: boolean) => void
|
|
setShowAnnouncement: (value: boolean) => void
|
|
setAllowedCommands: (value: string[]) => void
|
|
setDeniedCommands: (value: string[]) => void
|
|
setAllowedMaxRequests: (value: number | undefined) => void
|
|
setAllowedMaxCost: (value: number | undefined) => void
|
|
setSoundEnabled: (value: boolean) => void
|
|
setSoundVolume: (value: number) => void
|
|
terminalShellIntegrationTimeout?: number
|
|
setTerminalShellIntegrationTimeout: (value: number) => void
|
|
terminalShellIntegrationDisabled?: boolean
|
|
setTerminalShellIntegrationDisabled: (value: boolean) => void
|
|
terminalZdotdir?: boolean
|
|
setTerminalZdotdir: (value: boolean) => void
|
|
setTtsEnabled: (value: boolean) => void
|
|
setTtsSpeed: (value: number) => void
|
|
setEnableCheckpoints: (value: boolean) => void
|
|
checkpointTimeout: number
|
|
setCheckpointTimeout: (value: number) => void
|
|
setBrowserViewportSize: (value: string) => void
|
|
setWriteDelayMs: (value: number) => void
|
|
screenshotQuality?: number
|
|
setScreenshotQuality: (value: number) => void
|
|
terminalOutputPreviewSize?: "small" | "medium" | "large"
|
|
setTerminalOutputPreviewSize: (value: "small" | "medium" | "large") => void
|
|
mcpEnabled: boolean
|
|
setMcpEnabled: (value: boolean) => void
|
|
remoteControlEnabled: boolean
|
|
setRemoteControlEnabled: (value: boolean) => void
|
|
taskSyncEnabled: boolean
|
|
setTaskSyncEnabled: (value: boolean) => void
|
|
featureRoomoteControlEnabled: boolean
|
|
setFeatureRoomoteControlEnabled: (value: boolean) => void
|
|
setCurrentApiConfigName: (value: string) => void
|
|
setListApiConfigMeta: (value: ProviderSettingsEntry[]) => void
|
|
mode: Mode
|
|
setMode: (value: Mode) => void
|
|
setCustomModePrompts: (value: CustomModePrompts) => void
|
|
setCustomSupportPrompts: (value: CustomSupportPrompts) => void
|
|
enhancementApiConfigId?: string
|
|
setEnhancementApiConfigId: (value: string) => void
|
|
setExperimentEnabled: (id: ExperimentId, enabled: boolean) => void
|
|
setAutoApprovalEnabled: (value: boolean) => void
|
|
customModes: ModeConfig[]
|
|
setCustomModes: (value: ModeConfig[]) => void
|
|
setMaxOpenTabsContext: (value: number) => void
|
|
maxWorkspaceFiles: number
|
|
setMaxWorkspaceFiles: (value: number) => void
|
|
setTelemetrySetting: (value: TelemetrySetting) => void
|
|
remoteBrowserEnabled?: boolean
|
|
setRemoteBrowserEnabled: (value: boolean) => void
|
|
awsUsePromptCache?: boolean
|
|
setAwsUsePromptCache: (value: boolean) => void
|
|
maxImageFileSize: number
|
|
setMaxImageFileSize: (value: number) => void
|
|
maxTotalImageSize: number
|
|
setMaxTotalImageSize: (value: number) => void
|
|
machineId?: string
|
|
pinnedApiConfigs?: Record<string, boolean>
|
|
setPinnedApiConfigs: (value: Record<string, boolean>) => void
|
|
togglePinnedApiConfig: (configName: string) => void
|
|
setHistoryPreviewCollapsed: (value: boolean) => void
|
|
setReasoningBlockCollapsed: (value: boolean) => void
|
|
enterBehavior?: "send" | "newline"
|
|
setEnterBehavior: (value: "send" | "newline") => void
|
|
autoCondenseContext: boolean
|
|
setAutoCondenseContext: (value: boolean) => void
|
|
autoCondenseContextPercent: number
|
|
setAutoCondenseContextPercent: (value: number) => void
|
|
routerModels?: RouterModels
|
|
includeDiagnosticMessages?: boolean
|
|
setIncludeDiagnosticMessages: (value: boolean) => void
|
|
maxDiagnosticMessages?: number
|
|
setMaxDiagnosticMessages: (value: number) => void
|
|
includeTaskHistoryInEnhance?: boolean
|
|
setIncludeTaskHistoryInEnhance: (value: boolean) => void
|
|
includeCurrentTime?: boolean
|
|
setIncludeCurrentTime: (value: boolean) => void
|
|
includeCurrentCost?: boolean
|
|
setIncludeCurrentCost: (value: boolean) => void
|
|
showWorktreesInHomeScreen: boolean
|
|
setShowWorktreesInHomeScreen: (value: boolean) => void
|
|
}
|
|
|
|
export const ExtensionStateContext = createContext<ExtensionStateContextType | undefined>(undefined)
|
|
|
|
export const mergeExtensionState = (prevState: ExtensionState, newState: Partial<ExtensionState>) => {
|
|
const { customModePrompts: prevCustomModePrompts, experiments: prevExperiments, ...prevRest } = prevState
|
|
|
|
const {
|
|
apiConfiguration,
|
|
customModePrompts: newCustomModePrompts,
|
|
customSupportPrompts,
|
|
experiments: newExperiments,
|
|
...newRest
|
|
} = newState
|
|
|
|
const customModePrompts = { ...prevCustomModePrompts, ...(newCustomModePrompts ?? {}) }
|
|
const experiments = { ...prevExperiments, ...(newExperiments ?? {}) }
|
|
const rest = { ...prevRest, ...newRest }
|
|
|
|
// Note that we completely replace the previous apiConfiguration and customSupportPrompts objects
|
|
// with new ones since the state that is broadcast is the entire objects so merging is not necessary.
|
|
return {
|
|
...rest,
|
|
apiConfiguration: apiConfiguration ?? prevState.apiConfiguration,
|
|
customModePrompts,
|
|
customSupportPrompts: customSupportPrompts ?? prevState.customSupportPrompts,
|
|
experiments,
|
|
}
|
|
}
|
|
|
|
export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
|
const [state, setState] = useState<ExtensionState>({
|
|
apiConfiguration: {},
|
|
version: "",
|
|
clineMessages: [],
|
|
taskHistory: [],
|
|
shouldShowAnnouncement: false,
|
|
allowedCommands: [],
|
|
deniedCommands: [],
|
|
soundEnabled: false,
|
|
soundVolume: 0.5,
|
|
isBrowserSessionActive: false,
|
|
ttsEnabled: false,
|
|
ttsSpeed: 1.0,
|
|
enableCheckpoints: true,
|
|
checkpointTimeout: DEFAULT_CHECKPOINT_TIMEOUT_SECONDS, // Default to 15 seconds
|
|
language: "en", // Default language code
|
|
writeDelayMs: 1000,
|
|
browserViewportSize: "900x600",
|
|
screenshotQuality: 75,
|
|
terminalShellIntegrationTimeout: 4000,
|
|
mcpEnabled: true,
|
|
remoteControlEnabled: false,
|
|
taskSyncEnabled: false,
|
|
featureRoomoteControlEnabled: false,
|
|
currentApiConfigName: "default",
|
|
listApiConfigMeta: [],
|
|
mode: defaultModeSlug,
|
|
customModePrompts: defaultPrompts,
|
|
customSupportPrompts: {},
|
|
experiments: experimentDefault,
|
|
enhancementApiConfigId: "",
|
|
hasOpenedModeSelector: false, // Default to false (not opened yet)
|
|
autoApprovalEnabled: false,
|
|
customModes: [],
|
|
maxOpenTabsContext: 20,
|
|
maxWorkspaceFiles: 200,
|
|
cwd: "",
|
|
browserToolEnabled: true,
|
|
telemetrySetting: "unset",
|
|
showRooIgnoredFiles: true, // Default to showing .rooignore'd files with lock symbol (current behavior).
|
|
enableSubfolderRules: false, // Default to disabled - must be enabled to load rules from subdirectories
|
|
renderContext: "sidebar",
|
|
maxImageFileSize: 5, // Default max image file size in MB
|
|
maxTotalImageSize: 20, // Default max total image size in MB
|
|
pinnedApiConfigs: {}, // Empty object for pinned API configs
|
|
terminalZshOhMy: false, // Default Oh My Zsh integration setting
|
|
terminalZshP10k: false, // Default Powerlevel10k integration setting
|
|
terminalZdotdir: false, // Default ZDOTDIR handling setting
|
|
historyPreviewCollapsed: false, // Initialize the new state (default to expanded)
|
|
reasoningBlockCollapsed: true, // Default to collapsed
|
|
enterBehavior: "send", // Default: Enter sends, Shift+Enter creates newline
|
|
cloudUserInfo: null,
|
|
cloudIsAuthenticated: false,
|
|
cloudOrganizations: [],
|
|
sharingEnabled: false,
|
|
publicSharingEnabled: false,
|
|
organizationAllowList: ORGANIZATION_ALLOW_ALL,
|
|
organizationSettingsVersion: -1,
|
|
autoCondenseContext: true,
|
|
autoCondenseContextPercent: 100,
|
|
profileThresholds: {},
|
|
codebaseIndexConfig: {
|
|
codebaseIndexEnabled: true,
|
|
codebaseIndexQdrantUrl: "http://localhost:6333",
|
|
codebaseIndexEmbedderProvider: "openai",
|
|
codebaseIndexEmbedderBaseUrl: "",
|
|
codebaseIndexEmbedderModelId: "",
|
|
codebaseIndexSearchMaxResults: undefined,
|
|
codebaseIndexSearchMinScore: undefined,
|
|
},
|
|
codebaseIndexModels: { ollama: {}, openai: {} },
|
|
includeDiagnosticMessages: true,
|
|
maxDiagnosticMessages: 50,
|
|
openRouterImageApiKey: "",
|
|
openRouterImageGenerationSelectedModel: "",
|
|
includeCurrentTime: true,
|
|
includeCurrentCost: true,
|
|
lockApiConfigAcrossModes: false,
|
|
})
|
|
|
|
const [didHydrateState, setDidHydrateState] = useState(false)
|
|
const [showWelcome, setShowWelcome] = useState(false)
|
|
const [theme, setTheme] = useState<any>(undefined)
|
|
const [filePaths, setFilePaths] = useState<string[]>([])
|
|
const [openedTabs, setOpenedTabs] = useState<Array<{ label: string; isActive: boolean; path?: string }>>([])
|
|
const [commands, setCommands] = useState<Command[]>([])
|
|
const [skills, setSkills] = useState<SkillMetadata[]>([])
|
|
const [mcpServers, setMcpServers] = useState<McpServer[]>([])
|
|
const [currentCheckpoint, setCurrentCheckpoint] = useState<string>()
|
|
const [extensionRouterModels, setExtensionRouterModels] = useState<RouterModels | undefined>(undefined)
|
|
const [marketplaceItems, setMarketplaceItems] = useState<any[]>([])
|
|
const [alwaysAllowFollowupQuestions, setAlwaysAllowFollowupQuestions] = useState(false) // Add state for follow-up questions auto-approve
|
|
const [followupAutoApproveTimeoutMs, setFollowupAutoApproveTimeoutMs] = useState<number | undefined>(undefined) // Will be set from global settings
|
|
const [marketplaceInstalledMetadata, setMarketplaceInstalledMetadata] = useState<MarketplaceInstalledMetadata>({
|
|
project: {},
|
|
global: {},
|
|
})
|
|
const [includeTaskHistoryInEnhance, setIncludeTaskHistoryInEnhance] = useState(true)
|
|
const [prevCloudIsAuthenticated, setPrevCloudIsAuthenticated] = useState(false)
|
|
const [includeCurrentTime, setIncludeCurrentTime] = useState(true)
|
|
const [includeCurrentCost, setIncludeCurrentCost] = useState(true)
|
|
|
|
const setListApiConfigMeta = useCallback(
|
|
(value: ProviderSettingsEntry[]) => setState((prevState) => ({ ...prevState, listApiConfigMeta: value })),
|
|
[],
|
|
)
|
|
|
|
const setApiConfiguration = useCallback((value: ProviderSettings) => {
|
|
setState((prevState) => ({
|
|
...prevState,
|
|
apiConfiguration: {
|
|
...prevState.apiConfiguration,
|
|
...value,
|
|
},
|
|
}))
|
|
}, [])
|
|
|
|
const handleMessage = useCallback(
|
|
(event: MessageEvent) => {
|
|
const message: ExtensionMessage = event.data
|
|
switch (message.type) {
|
|
case "state": {
|
|
const newState = message.state ?? {}
|
|
setState((prevState) => mergeExtensionState(prevState, newState))
|
|
setShowWelcome(!checkExistKey(newState.apiConfiguration))
|
|
setDidHydrateState(true)
|
|
// Update alwaysAllowFollowupQuestions if present in state message
|
|
if ((newState as any).alwaysAllowFollowupQuestions !== undefined) {
|
|
setAlwaysAllowFollowupQuestions((newState as any).alwaysAllowFollowupQuestions)
|
|
}
|
|
// Update followupAutoApproveTimeoutMs if present in state message
|
|
if ((newState as any).followupAutoApproveTimeoutMs !== undefined) {
|
|
setFollowupAutoApproveTimeoutMs((newState as any).followupAutoApproveTimeoutMs)
|
|
}
|
|
// Update includeTaskHistoryInEnhance if present in state message
|
|
if ((newState as any).includeTaskHistoryInEnhance !== undefined) {
|
|
setIncludeTaskHistoryInEnhance((newState as any).includeTaskHistoryInEnhance)
|
|
}
|
|
// Update includeCurrentTime if present in state message
|
|
if ((newState as any).includeCurrentTime !== undefined) {
|
|
setIncludeCurrentTime((newState as any).includeCurrentTime)
|
|
}
|
|
// Update includeCurrentCost if present in state message
|
|
if ((newState as any).includeCurrentCost !== undefined) {
|
|
setIncludeCurrentCost((newState as any).includeCurrentCost)
|
|
}
|
|
// Handle marketplace data if present in state message
|
|
if (newState.marketplaceItems !== undefined) {
|
|
setMarketplaceItems(newState.marketplaceItems)
|
|
}
|
|
if (newState.marketplaceInstalledMetadata !== undefined) {
|
|
setMarketplaceInstalledMetadata(newState.marketplaceInstalledMetadata)
|
|
}
|
|
break
|
|
}
|
|
case "action": {
|
|
if (message.action === "toggleAutoApprove") {
|
|
// Toggle the auto-approval state
|
|
setState((prevState) => {
|
|
const newValue = !(prevState.autoApprovalEnabled ?? false)
|
|
// Also send the update to the extension
|
|
vscode.postMessage({ type: "autoApprovalEnabled", bool: newValue })
|
|
return { ...prevState, autoApprovalEnabled: newValue }
|
|
})
|
|
}
|
|
break
|
|
}
|
|
case "theme": {
|
|
if (message.text) {
|
|
setTheme(convertTextMateToHljs(JSON.parse(message.text)))
|
|
}
|
|
break
|
|
}
|
|
case "workspaceUpdated": {
|
|
const paths = message.filePaths ?? []
|
|
const tabs = message.openedTabs ?? []
|
|
|
|
setFilePaths(paths)
|
|
setOpenedTabs(tabs)
|
|
break
|
|
}
|
|
case "commands": {
|
|
setCommands(message.commands ?? [])
|
|
break
|
|
}
|
|
case "skills": {
|
|
setSkills(message.skills ?? [])
|
|
break
|
|
}
|
|
case "messageUpdated": {
|
|
const clineMessage = message.clineMessage!
|
|
setState((prevState) => {
|
|
// worth noting it will never be possible for a more up-to-date message to be sent here or in normal messages post since the presentAssistantContent function uses lock
|
|
const lastIndex = findLastIndex(prevState.clineMessages, (msg) => msg.ts === clineMessage.ts)
|
|
if (lastIndex !== -1) {
|
|
const newClineMessages = [...prevState.clineMessages]
|
|
newClineMessages[lastIndex] = clineMessage
|
|
return { ...prevState, clineMessages: newClineMessages }
|
|
}
|
|
return prevState
|
|
})
|
|
break
|
|
}
|
|
case "mcpServers": {
|
|
setMcpServers(message.mcpServers ?? [])
|
|
break
|
|
}
|
|
case "currentCheckpointUpdated": {
|
|
setCurrentCheckpoint(message.text)
|
|
break
|
|
}
|
|
case "listApiConfig": {
|
|
setListApiConfigMeta(message.listApiConfig ?? [])
|
|
break
|
|
}
|
|
case "routerModels": {
|
|
setExtensionRouterModels(message.routerModels)
|
|
break
|
|
}
|
|
case "marketplaceData": {
|
|
if (message.marketplaceItems !== undefined) {
|
|
setMarketplaceItems(message.marketplaceItems)
|
|
}
|
|
if (message.marketplaceInstalledMetadata !== undefined) {
|
|
setMarketplaceInstalledMetadata(message.marketplaceInstalledMetadata)
|
|
}
|
|
break
|
|
}
|
|
case "taskHistoryUpdated": {
|
|
// Efficiently update just the task history without replacing entire state
|
|
if (message.taskHistory !== undefined) {
|
|
setState((prevState) => ({
|
|
...prevState,
|
|
taskHistory: message.taskHistory!,
|
|
}))
|
|
}
|
|
break
|
|
}
|
|
case "taskHistoryItemUpdated": {
|
|
const item = message.taskHistoryItem
|
|
if (!item) {
|
|
break
|
|
}
|
|
setState((prevState) => {
|
|
const existingIndex = prevState.taskHistory.findIndex((h) => h.id === item.id)
|
|
let nextHistory: typeof prevState.taskHistory
|
|
if (existingIndex === -1) {
|
|
nextHistory = [item, ...prevState.taskHistory]
|
|
} else {
|
|
nextHistory = [...prevState.taskHistory]
|
|
nextHistory[existingIndex] = item
|
|
}
|
|
// Keep UI semantics consistent with extension: newest-first ordering.
|
|
nextHistory.sort((a, b) => b.ts - a.ts)
|
|
return {
|
|
...prevState,
|
|
taskHistory: nextHistory,
|
|
currentTaskItem:
|
|
prevState.currentTaskItem?.id === item.id ? item : prevState.currentTaskItem,
|
|
}
|
|
})
|
|
break
|
|
}
|
|
}
|
|
},
|
|
[setListApiConfigMeta],
|
|
)
|
|
|
|
useEffect(() => {
|
|
window.addEventListener("message", handleMessage)
|
|
return () => {
|
|
window.removeEventListener("message", handleMessage)
|
|
}
|
|
}, [handleMessage])
|
|
|
|
useEffect(() => {
|
|
vscode.postMessage({ type: "webviewDidLaunch" })
|
|
}, [])
|
|
|
|
// Watch for authentication state changes and refresh Roo models
|
|
useEffect(() => {
|
|
const currentAuth = state.cloudIsAuthenticated ?? false
|
|
const currentProvider = state.apiConfiguration?.apiProvider
|
|
if (!prevCloudIsAuthenticated && currentAuth && currentProvider === "roo") {
|
|
// User just authenticated and Roo is the active provider - refresh Roo models
|
|
vscode.postMessage({ type: "requestRooModels" })
|
|
}
|
|
setPrevCloudIsAuthenticated(currentAuth)
|
|
}, [state.cloudIsAuthenticated, prevCloudIsAuthenticated, state.apiConfiguration?.apiProvider])
|
|
|
|
const contextValue: ExtensionStateContextType = {
|
|
...state,
|
|
reasoningBlockCollapsed: state.reasoningBlockCollapsed ?? true,
|
|
didHydrateState,
|
|
showWelcome,
|
|
theme,
|
|
mcpServers,
|
|
currentCheckpoint,
|
|
filePaths,
|
|
openedTabs,
|
|
commands,
|
|
skills,
|
|
soundVolume: state.soundVolume,
|
|
ttsSpeed: state.ttsSpeed,
|
|
writeDelayMs: state.writeDelayMs,
|
|
screenshotQuality: state.screenshotQuality,
|
|
routerModels: extensionRouterModels,
|
|
cloudIsAuthenticated: state.cloudIsAuthenticated ?? false,
|
|
cloudOrganizations: state.cloudOrganizations ?? [],
|
|
organizationSettingsVersion: state.organizationSettingsVersion ?? -1,
|
|
marketplaceItems,
|
|
marketplaceInstalledMetadata,
|
|
profileThresholds: state.profileThresholds ?? {},
|
|
alwaysAllowFollowupQuestions,
|
|
followupAutoApproveTimeoutMs,
|
|
remoteControlEnabled: state.remoteControlEnabled ?? false,
|
|
taskSyncEnabled: state.taskSyncEnabled,
|
|
featureRoomoteControlEnabled: state.featureRoomoteControlEnabled ?? false,
|
|
setExperimentEnabled: (id, enabled) =>
|
|
setState((prevState) => ({ ...prevState, experiments: { ...prevState.experiments, [id]: enabled } })),
|
|
setApiConfiguration,
|
|
setCustomInstructions: (value) => setState((prevState) => ({ ...prevState, customInstructions: value })),
|
|
setAlwaysAllowReadOnly: (value) => setState((prevState) => ({ ...prevState, alwaysAllowReadOnly: value })),
|
|
setAlwaysAllowReadOnlyOutsideWorkspace: (value) =>
|
|
setState((prevState) => ({ ...prevState, alwaysAllowReadOnlyOutsideWorkspace: value })),
|
|
setAlwaysAllowWrite: (value) => setState((prevState) => ({ ...prevState, alwaysAllowWrite: value })),
|
|
setAlwaysAllowWriteOutsideWorkspace: (value) =>
|
|
setState((prevState) => ({ ...prevState, alwaysAllowWriteOutsideWorkspace: value })),
|
|
setAlwaysAllowExecute: (value) => setState((prevState) => ({ ...prevState, alwaysAllowExecute: value })),
|
|
setAlwaysAllowBrowser: (value) => setState((prevState) => ({ ...prevState, alwaysAllowBrowser: value })),
|
|
setAlwaysAllowMcp: (value) => setState((prevState) => ({ ...prevState, alwaysAllowMcp: value })),
|
|
setAlwaysAllowModeSwitch: (value) => setState((prevState) => ({ ...prevState, alwaysAllowModeSwitch: value })),
|
|
setAlwaysAllowSubtasks: (value) => setState((prevState) => ({ ...prevState, alwaysAllowSubtasks: value })),
|
|
setAlwaysAllowFollowupQuestions,
|
|
setFollowupAutoApproveTimeoutMs: (value) =>
|
|
setState((prevState) => ({ ...prevState, followupAutoApproveTimeoutMs: value })),
|
|
setShowAnnouncement: (value) => setState((prevState) => ({ ...prevState, shouldShowAnnouncement: value })),
|
|
setAllowedCommands: (value) => setState((prevState) => ({ ...prevState, allowedCommands: value })),
|
|
setDeniedCommands: (value) => setState((prevState) => ({ ...prevState, deniedCommands: value })),
|
|
setAllowedMaxRequests: (value) => setState((prevState) => ({ ...prevState, allowedMaxRequests: value })),
|
|
setAllowedMaxCost: (value) => setState((prevState) => ({ ...prevState, allowedMaxCost: value })),
|
|
setSoundEnabled: (value) => setState((prevState) => ({ ...prevState, soundEnabled: value })),
|
|
setSoundVolume: (value) => setState((prevState) => ({ ...prevState, soundVolume: value })),
|
|
setTtsEnabled: (value) => setState((prevState) => ({ ...prevState, ttsEnabled: value })),
|
|
setTtsSpeed: (value) => setState((prevState) => ({ ...prevState, ttsSpeed: value })),
|
|
setEnableCheckpoints: (value) => setState((prevState) => ({ ...prevState, enableCheckpoints: value })),
|
|
setCheckpointTimeout: (value) => setState((prevState) => ({ ...prevState, checkpointTimeout: value })),
|
|
setBrowserViewportSize: (value: string) =>
|
|
setState((prevState) => ({ ...prevState, browserViewportSize: value })),
|
|
setWriteDelayMs: (value) => setState((prevState) => ({ ...prevState, writeDelayMs: value })),
|
|
setScreenshotQuality: (value) => setState((prevState) => ({ ...prevState, screenshotQuality: value })),
|
|
setTerminalOutputPreviewSize: (value) =>
|
|
setState((prevState) => ({ ...prevState, terminalOutputPreviewSize: value })),
|
|
setTerminalShellIntegrationTimeout: (value) =>
|
|
setState((prevState) => ({ ...prevState, terminalShellIntegrationTimeout: value })),
|
|
setTerminalShellIntegrationDisabled: (value) =>
|
|
setState((prevState) => ({ ...prevState, terminalShellIntegrationDisabled: value })),
|
|
setTerminalZdotdir: (value) => setState((prevState) => ({ ...prevState, terminalZdotdir: value })),
|
|
setMcpEnabled: (value) => setState((prevState) => ({ ...prevState, mcpEnabled: value })),
|
|
setRemoteControlEnabled: (value) => setState((prevState) => ({ ...prevState, remoteControlEnabled: value })),
|
|
setTaskSyncEnabled: (value) => setState((prevState) => ({ ...prevState, taskSyncEnabled: value }) as any),
|
|
setFeatureRoomoteControlEnabled: (value) =>
|
|
setState((prevState) => ({ ...prevState, featureRoomoteControlEnabled: value })),
|
|
setCurrentApiConfigName: (value) => setState((prevState) => ({ ...prevState, currentApiConfigName: value })),
|
|
setListApiConfigMeta,
|
|
setMode: (value: Mode) => setState((prevState) => ({ ...prevState, mode: value })),
|
|
setCustomModePrompts: (value) => setState((prevState) => ({ ...prevState, customModePrompts: value })),
|
|
setCustomSupportPrompts: (value) => setState((prevState) => ({ ...prevState, customSupportPrompts: value })),
|
|
setEnhancementApiConfigId: (value) =>
|
|
setState((prevState) => ({ ...prevState, enhancementApiConfigId: value })),
|
|
setAutoApprovalEnabled: (value) => setState((prevState) => ({ ...prevState, autoApprovalEnabled: value })),
|
|
setCustomModes: (value) => setState((prevState) => ({ ...prevState, customModes: value })),
|
|
setMaxOpenTabsContext: (value) => setState((prevState) => ({ ...prevState, maxOpenTabsContext: value })),
|
|
setMaxWorkspaceFiles: (value) => setState((prevState) => ({ ...prevState, maxWorkspaceFiles: value })),
|
|
setBrowserToolEnabled: (value) => setState((prevState) => ({ ...prevState, browserToolEnabled: value })),
|
|
setTelemetrySetting: (value) => setState((prevState) => ({ ...prevState, telemetrySetting: value })),
|
|
setShowRooIgnoredFiles: (value) => setState((prevState) => ({ ...prevState, showRooIgnoredFiles: value })),
|
|
setEnableSubfolderRules: (value) => setState((prevState) => ({ ...prevState, enableSubfolderRules: value })),
|
|
setRemoteBrowserEnabled: (value) => setState((prevState) => ({ ...prevState, remoteBrowserEnabled: value })),
|
|
setAwsUsePromptCache: (value) => setState((prevState) => ({ ...prevState, awsUsePromptCache: value })),
|
|
setMaxImageFileSize: (value) => setState((prevState) => ({ ...prevState, maxImageFileSize: value })),
|
|
setMaxTotalImageSize: (value) => setState((prevState) => ({ ...prevState, maxTotalImageSize: value })),
|
|
setPinnedApiConfigs: (value) => setState((prevState) => ({ ...prevState, pinnedApiConfigs: value })),
|
|
togglePinnedApiConfig: (configId) =>
|
|
setState((prevState) => {
|
|
const currentPinned = prevState.pinnedApiConfigs || {}
|
|
const newPinned = {
|
|
...currentPinned,
|
|
[configId]: !currentPinned[configId],
|
|
}
|
|
|
|
// If the config is now unpinned, remove it from the object
|
|
if (!newPinned[configId]) {
|
|
delete newPinned[configId]
|
|
}
|
|
|
|
return { ...prevState, pinnedApiConfigs: newPinned }
|
|
}),
|
|
setHistoryPreviewCollapsed: (value) =>
|
|
setState((prevState) => ({ ...prevState, historyPreviewCollapsed: value })),
|
|
setReasoningBlockCollapsed: (value) =>
|
|
setState((prevState) => ({ ...prevState, reasoningBlockCollapsed: value })),
|
|
enterBehavior: state.enterBehavior ?? "send",
|
|
setEnterBehavior: (value) => setState((prevState) => ({ ...prevState, enterBehavior: value })),
|
|
setHasOpenedModeSelector: (value) => setState((prevState) => ({ ...prevState, hasOpenedModeSelector: value })),
|
|
setAutoCondenseContext: (value) => setState((prevState) => ({ ...prevState, autoCondenseContext: value })),
|
|
setAutoCondenseContextPercent: (value) =>
|
|
setState((prevState) => ({ ...prevState, autoCondenseContextPercent: value })),
|
|
setProfileThresholds: (value) => setState((prevState) => ({ ...prevState, profileThresholds: value })),
|
|
includeDiagnosticMessages: state.includeDiagnosticMessages,
|
|
setIncludeDiagnosticMessages: (value) => {
|
|
setState((prevState) => ({ ...prevState, includeDiagnosticMessages: value }))
|
|
},
|
|
maxDiagnosticMessages: state.maxDiagnosticMessages,
|
|
setMaxDiagnosticMessages: (value) => {
|
|
setState((prevState) => ({ ...prevState, maxDiagnosticMessages: value }))
|
|
},
|
|
includeTaskHistoryInEnhance,
|
|
setIncludeTaskHistoryInEnhance,
|
|
includeCurrentTime,
|
|
setIncludeCurrentTime,
|
|
includeCurrentCost,
|
|
setIncludeCurrentCost,
|
|
showWorktreesInHomeScreen: state.showWorktreesInHomeScreen ?? true,
|
|
setShowWorktreesInHomeScreen: (value) =>
|
|
setState((prevState) => ({ ...prevState, showWorktreesInHomeScreen: value })),
|
|
}
|
|
|
|
return <ExtensionStateContext.Provider value={contextValue}>{children}</ExtensionStateContext.Provider>
|
|
}
|
|
|
|
export const useExtensionState = () => {
|
|
const context = useContext(ExtensionStateContext)
|
|
|
|
if (context === undefined) {
|
|
throw new Error("useExtensionState must be used within an ExtensionStateContextProvider")
|
|
}
|
|
|
|
return context
|
|
}
|