feat(ui): centralize interaction preferences
Expose interaction defaults in Settings and reuse the same registry for command palette actions.
This commit is contained in:
@@ -45,7 +45,6 @@ export const SettingsScreen: Component = () => {
|
|||||||
<div class="settings-screen-frame">
|
<div class="settings-screen-frame">
|
||||||
<Dialog.Content class="modal-surface settings-screen-shell">
|
<Dialog.Content class="modal-surface settings-screen-shell">
|
||||||
<Dialog.Title class="sr-only">{t("settings.title")}</Dialog.Title>
|
<Dialog.Title class="sr-only">{t("settings.title")}</Dialog.Title>
|
||||||
<Dialog.Description class="sr-only">{t("settings.description")}</Dialog.Description>
|
|
||||||
|
|
||||||
<aside class="settings-screen-nav">
|
<aside class="settings-screen-nav">
|
||||||
<div class="settings-screen-nav-header">
|
<div class="settings-screen-nav-header">
|
||||||
@@ -55,7 +54,6 @@ export const SettingsScreen: Component = () => {
|
|||||||
</span>
|
</span>
|
||||||
<div>
|
<div>
|
||||||
<h2 class="settings-screen-title">{t("settings.title")}</h2>
|
<h2 class="settings-screen-title">{t("settings.title")}</h2>
|
||||||
<p class="settings-screen-subtitle">{t("settings.description")}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,7 +1,10 @@
|
|||||||
import type { Component } from "solid-js"
|
import { Select } from "@kobalte/core/select"
|
||||||
import { Check, Laptop, Moon, Sun } from "lucide-solid"
|
import { createEffect, createMemo, createSignal, For, type Component } from "solid-js"
|
||||||
|
import { Check, ChevronDown, Laptop, Moon, Sun } from "lucide-solid"
|
||||||
import { useI18n } from "../../lib/i18n"
|
import { useI18n } from "../../lib/i18n"
|
||||||
import { useTheme, type ThemeMode } from "../../lib/theme"
|
import { useTheme, type ThemeMode } from "../../lib/theme"
|
||||||
|
import { useConfig } from "../../stores/preferences"
|
||||||
|
import { getBehaviorSettings, type BehaviorSetting } from "../../lib/settings/behavior-registry"
|
||||||
|
|
||||||
const themeModeOptions: Array<{ value: ThemeMode; icon: typeof Laptop }> = [
|
const themeModeOptions: Array<{ value: ThemeMode; icon: typeof Laptop }> = [
|
||||||
{ value: "system", icon: Laptop },
|
{ value: "system", icon: Laptop },
|
||||||
@@ -12,6 +15,200 @@ const themeModeOptions: Array<{ value: ThemeMode; icon: typeof Laptop }> = [
|
|||||||
export const AppearanceSettingsSection: Component = () => {
|
export const AppearanceSettingsSection: Component = () => {
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
const { themeMode, setThemeMode } = useTheme()
|
const { themeMode, setThemeMode } = useTheme()
|
||||||
|
const {
|
||||||
|
preferences,
|
||||||
|
updatePreferences,
|
||||||
|
toggleShowThinkingBlocks,
|
||||||
|
toggleKeyboardShortcutHints,
|
||||||
|
toggleShowTimelineTools,
|
||||||
|
toggleUsageMetrics,
|
||||||
|
toggleAutoCleanupBlankSessions,
|
||||||
|
togglePromptSubmitOnEnter,
|
||||||
|
setDiffViewMode,
|
||||||
|
setToolOutputExpansion,
|
||||||
|
setDiagnosticsExpansion,
|
||||||
|
setThinkingBlocksExpansion,
|
||||||
|
setToolInputsVisibility,
|
||||||
|
} = useConfig()
|
||||||
|
|
||||||
|
const behaviorSettings = createMemo(() =>
|
||||||
|
getBehaviorSettings({
|
||||||
|
preferences,
|
||||||
|
updatePreferences,
|
||||||
|
toggleShowThinkingBlocks,
|
||||||
|
toggleKeyboardShortcutHints,
|
||||||
|
toggleShowTimelineTools,
|
||||||
|
toggleUsageMetrics,
|
||||||
|
toggleAutoCleanupBlankSessions,
|
||||||
|
togglePromptSubmitOnEnter,
|
||||||
|
setDiffViewMode,
|
||||||
|
setToolOutputExpansion,
|
||||||
|
setDiagnosticsExpansion,
|
||||||
|
setThinkingBlocksExpansion,
|
||||||
|
setToolInputsVisibility,
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
|
||||||
|
const [overrides, setOverrides] = createSignal<Map<string, unknown>>(new Map())
|
||||||
|
|
||||||
|
const setOverride = (id: string, value: unknown) => {
|
||||||
|
setOverrides((prev) => {
|
||||||
|
const next = new Map(prev)
|
||||||
|
next.set(id, value)
|
||||||
|
return next
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
const current = overrides()
|
||||||
|
if (current.size === 0) return
|
||||||
|
|
||||||
|
const prefs = preferences()
|
||||||
|
const settings = behaviorSettings()
|
||||||
|
|
||||||
|
let changed = false
|
||||||
|
const next = new Map(current)
|
||||||
|
for (const setting of settings) {
|
||||||
|
if (!next.has(setting.id)) continue
|
||||||
|
const overrideValue = next.get(setting.id)
|
||||||
|
const actualValue = setting.get(prefs)
|
||||||
|
if (Object.is(actualValue, overrideValue)) {
|
||||||
|
next.delete(setting.id)
|
||||||
|
changed = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changed) {
|
||||||
|
setOverrides(next)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const readSettingValue = (setting: BehaviorSetting) => {
|
||||||
|
const current = overrides()
|
||||||
|
if (current.has(setting.id)) return current.get(setting.id)
|
||||||
|
return setting.get(preferences())
|
||||||
|
}
|
||||||
|
|
||||||
|
type SelectOption = { value: string; label: string }
|
||||||
|
|
||||||
|
const BehaviorRow: Component<{ setting: BehaviorSetting }> = (props) => {
|
||||||
|
const setting = props.setting
|
||||||
|
const disabled = createMemo(() => (setting.disabled ? Boolean(setting.disabled()) : false))
|
||||||
|
|
||||||
|
if (setting.kind === "toggle") {
|
||||||
|
const options = createMemo<SelectOption[]>(() => [
|
||||||
|
{ value: "true", label: t("settings.common.enabled") },
|
||||||
|
{ value: "false", label: t("settings.common.disabled") },
|
||||||
|
])
|
||||||
|
const currentValue = createMemo(() => String(Boolean(readSettingValue(setting))))
|
||||||
|
const selectedOption = createMemo(() => options().find((opt) => opt.value === currentValue()))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class={`settings-toggle-row ${disabled() ? "opacity-60" : ""}`}>
|
||||||
|
<div>
|
||||||
|
<div class="settings-toggle-title">{t(setting.titleKey)}</div>
|
||||||
|
<div class="settings-toggle-caption">{t(setting.subtitleKey)}</div>
|
||||||
|
</div>
|
||||||
|
<Select<SelectOption>
|
||||||
|
value={selectedOption()}
|
||||||
|
onChange={(opt) => {
|
||||||
|
if (!opt) return
|
||||||
|
const next = opt.value === "true"
|
||||||
|
setOverride(setting.id, next)
|
||||||
|
setting.set(next)
|
||||||
|
}}
|
||||||
|
options={options()}
|
||||||
|
optionValue="value"
|
||||||
|
optionTextValue="label"
|
||||||
|
disabled={disabled()}
|
||||||
|
itemComponent={(itemProps) => (
|
||||||
|
<Select.Item item={itemProps.item} class="selector-option">
|
||||||
|
<Select.ItemLabel class="selector-option-label">{itemProps.item.rawValue.label}</Select.ItemLabel>
|
||||||
|
</Select.Item>
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Select.Trigger class="selector-trigger" aria-label={t(setting.titleKey)}>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<Select.Value<SelectOption>>
|
||||||
|
{(state) => (
|
||||||
|
<span class="selector-trigger-primary selector-trigger-primary--align-left">
|
||||||
|
{state.selectedOption()?.label}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</Select.Value>
|
||||||
|
</div>
|
||||||
|
<Select.Icon class="selector-trigger-icon">
|
||||||
|
<ChevronDown class="w-3 h-3" />
|
||||||
|
</Select.Icon>
|
||||||
|
</Select.Trigger>
|
||||||
|
|
||||||
|
<Select.Portal>
|
||||||
|
<Select.Content class="selector-popover">
|
||||||
|
<Select.Listbox class="selector-listbox" />
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Portal>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const enumSetting = setting as Extract<BehaviorSetting, { kind: "enum" }>
|
||||||
|
const options = createMemo<SelectOption[]>(() =>
|
||||||
|
enumSetting.options.map((opt: { value: string; labelKey: string }) => ({
|
||||||
|
value: String(opt.value),
|
||||||
|
label: t(opt.labelKey),
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
const currentValue = createMemo(() => String(readSettingValue(setting) ?? ""))
|
||||||
|
const selectedOption = createMemo(() => options().find((opt) => opt.value === currentValue()))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div class={`settings-toggle-row ${disabled() ? "opacity-60" : ""}`}>
|
||||||
|
<div>
|
||||||
|
<div class="settings-toggle-title">{t(setting.titleKey)}</div>
|
||||||
|
<div class="settings-toggle-caption">{t(setting.subtitleKey)}</div>
|
||||||
|
</div>
|
||||||
|
<Select<SelectOption>
|
||||||
|
value={selectedOption()}
|
||||||
|
onChange={(opt) => {
|
||||||
|
if (!opt) return
|
||||||
|
setOverride(setting.id, opt.value)
|
||||||
|
enumSetting.set(opt.value as any)
|
||||||
|
}}
|
||||||
|
options={options()}
|
||||||
|
optionValue="value"
|
||||||
|
optionTextValue="label"
|
||||||
|
disabled={disabled()}
|
||||||
|
itemComponent={(itemProps) => (
|
||||||
|
<Select.Item item={itemProps.item} class="selector-option">
|
||||||
|
<Select.ItemLabel class="selector-option-label">{itemProps.item.rawValue.label}</Select.ItemLabel>
|
||||||
|
</Select.Item>
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Select.Trigger class="selector-trigger" aria-label={t(setting.titleKey)}>
|
||||||
|
<div class="flex-1 min-w-0">
|
||||||
|
<Select.Value<SelectOption>>
|
||||||
|
{(state) => (
|
||||||
|
<span class="selector-trigger-primary selector-trigger-primary--align-left">
|
||||||
|
{state.selectedOption()?.label}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</Select.Value>
|
||||||
|
</div>
|
||||||
|
<Select.Icon class="selector-trigger-icon">
|
||||||
|
<ChevronDown class="w-3 h-3" />
|
||||||
|
</Select.Icon>
|
||||||
|
</Select.Trigger>
|
||||||
|
|
||||||
|
<Select.Portal>
|
||||||
|
<Select.Content class="selector-popover">
|
||||||
|
<Select.Listbox class="selector-listbox" />
|
||||||
|
</Select.Content>
|
||||||
|
</Select.Portal>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
const modeLabel = (mode: ThemeMode) => {
|
const modeLabel = (mode: ThemeMode) => {
|
||||||
if (mode === "system") return t("theme.mode.system")
|
if (mode === "system") return t("theme.mode.system")
|
||||||
@@ -54,6 +251,20 @@ export const AppearanceSettingsSection: Component = () => {
|
|||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="settings-card">
|
||||||
|
<div class="settings-card-header">
|
||||||
|
<div>
|
||||||
|
<h3 class="settings-card-title">{t("settings.appearance.behavior.title")}</h3>
|
||||||
|
<p class="settings-card-subtitle">{t("settings.appearance.behavior.subtitle")}</p>
|
||||||
|
</div>
|
||||||
|
<span class="settings-scope-badge">{t("settings.scope.device")}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="settings-stack">
|
||||||
|
<For each={behaviorSettings()}>{(setting) => <BehaviorRow setting={setting} />}</For>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { getLogger } from "../logger"
|
|||||||
import { requestData } from "../opencode-api"
|
import { requestData } from "../opencode-api"
|
||||||
import { emitSessionSidebarRequest } from "../session-sidebar-events"
|
import { emitSessionSidebarRequest } from "../session-sidebar-events"
|
||||||
import { tGlobal } from "../i18n"
|
import { tGlobal } from "../i18n"
|
||||||
import { runtimeEnv } from "../runtime-env"
|
import { registerBehaviorCommands } from "../settings/behavior-registry"
|
||||||
|
|
||||||
const log = getLogger("actions")
|
const log = getLogger("actions")
|
||||||
|
|
||||||
@@ -427,178 +427,19 @@ export function useCommands(options: UseCommandsOptions) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
commandRegistry.register({
|
registerBehaviorCommands((command) => commandRegistry.register(command), {
|
||||||
id: "prompt-submit-shortcut",
|
preferences: options.preferences,
|
||||||
label: () =>
|
toggleShowThinkingBlocks: options.toggleShowThinkingBlocks,
|
||||||
options.preferences().promptSubmitOnEnter
|
toggleKeyboardShortcutHints: options.toggleKeyboardShortcutHints,
|
||||||
? tGlobal("commands.promptSubmitShortcut.label.swapped")
|
toggleShowTimelineTools: options.toggleShowTimelineTools,
|
||||||
: tGlobal("commands.promptSubmitShortcut.label.default"),
|
toggleUsageMetrics: options.toggleUsageMetrics,
|
||||||
description: () => tGlobal("commands.promptSubmitShortcut.description"),
|
toggleAutoCleanupBlankSessions: options.toggleAutoCleanupBlankSessions,
|
||||||
category: "Input & Focus",
|
togglePromptSubmitOnEnter: options.togglePromptSubmitOnEnter,
|
||||||
keywords: () => splitKeywords("commands.promptSubmitShortcut.keywords"),
|
setDiffViewMode: options.setDiffViewMode,
|
||||||
action: options.togglePromptSubmitOnEnter,
|
setToolOutputExpansion: options.setToolOutputExpansion,
|
||||||
})
|
setDiagnosticsExpansion: options.setDiagnosticsExpansion,
|
||||||
|
setThinkingBlocksExpansion: options.setThinkingBlocksExpansion,
|
||||||
commandRegistry.register({
|
setToolInputsVisibility: options.setToolInputsVisibility,
|
||||||
id: "thinking",
|
|
||||||
label: () => tGlobal(options.preferences().showThinkingBlocks ? "commands.thinkingBlocks.label.hide" : "commands.thinkingBlocks.label.show"),
|
|
||||||
description: () => tGlobal("commands.thinkingBlocks.description"),
|
|
||||||
category: "System",
|
|
||||||
keywords: () => ["/thinking", ...splitKeywords("commands.thinkingBlocks.keywords")],
|
|
||||||
action: options.toggleShowThinkingBlocks,
|
|
||||||
})
|
|
||||||
|
|
||||||
commandRegistry.register({
|
|
||||||
id: "timeline-tools",
|
|
||||||
label: () => tGlobal(options.preferences().showTimelineTools ? "commands.timelineToolCalls.label.hide" : "commands.timelineToolCalls.label.show"),
|
|
||||||
description: () => tGlobal("commands.timelineToolCalls.description"),
|
|
||||||
category: "System",
|
|
||||||
keywords: () => splitKeywords("commands.timelineToolCalls.keywords"),
|
|
||||||
action: options.toggleShowTimelineTools,
|
|
||||||
})
|
|
||||||
|
|
||||||
commandRegistry.register({
|
|
||||||
id: "keyboard-shortcut-hints",
|
|
||||||
label: () =>
|
|
||||||
tGlobal(
|
|
||||||
options.preferences().showKeyboardShortcutHints
|
|
||||||
? "commands.keyboardShortcutHints.label.hide"
|
|
||||||
: "commands.keyboardShortcutHints.label.show",
|
|
||||||
),
|
|
||||||
description: () =>
|
|
||||||
tGlobal(
|
|
||||||
runtimeEnv.host === "web"
|
|
||||||
? "commands.keyboardShortcutHints.description.disabledWeb"
|
|
||||||
: "commands.keyboardShortcutHints.description",
|
|
||||||
),
|
|
||||||
category: "System",
|
|
||||||
keywords: () => splitKeywords("commands.keyboardShortcutHints.keywords"),
|
|
||||||
disabled: () => runtimeEnv.host === "web",
|
|
||||||
action: options.toggleKeyboardShortcutHints,
|
|
||||||
})
|
|
||||||
|
|
||||||
commandRegistry.register({
|
|
||||||
id: "thinking-default-visibility",
|
|
||||||
label: () => {
|
|
||||||
const mode = options.preferences().thinkingBlocksExpansion ?? "expanded"
|
|
||||||
const state = mode === "expanded" ? tGlobal("commands.common.expanded") : tGlobal("commands.common.collapsed")
|
|
||||||
return tGlobal("commands.thinkingBlocksDefault.label", { state })
|
|
||||||
},
|
|
||||||
description: () => tGlobal("commands.thinkingBlocksDefault.description"),
|
|
||||||
category: "System",
|
|
||||||
keywords: () => ["/thinking", ...splitKeywords("commands.thinkingBlocksDefault.keywords")],
|
|
||||||
action: () => {
|
|
||||||
const mode = options.preferences().thinkingBlocksExpansion ?? "expanded"
|
|
||||||
const next: ExpansionPreference = mode === "expanded" ? "collapsed" : "expanded"
|
|
||||||
options.setThinkingBlocksExpansion(next)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
commandRegistry.register({
|
|
||||||
id: "diff-view-split",
|
|
||||||
label: () => {
|
|
||||||
const prefix = (options.preferences().diffViewMode || "split") === "split" ? "✓ " : ""
|
|
||||||
return `${prefix}${tGlobal("commands.diffViewSplit.label")}`
|
|
||||||
},
|
|
||||||
description: () => tGlobal("commands.diffViewSplit.description"),
|
|
||||||
category: "System",
|
|
||||||
keywords: () => splitKeywords("commands.diffViewSplit.keywords"),
|
|
||||||
action: () => options.setDiffViewMode("split"),
|
|
||||||
})
|
|
||||||
|
|
||||||
commandRegistry.register({
|
|
||||||
id: "diff-view-unified",
|
|
||||||
label: () => {
|
|
||||||
const prefix = (options.preferences().diffViewMode || "split") === "unified" ? "✓ " : ""
|
|
||||||
return `${prefix}${tGlobal("commands.diffViewUnified.label")}`
|
|
||||||
},
|
|
||||||
description: () => tGlobal("commands.diffViewUnified.description"),
|
|
||||||
category: "System",
|
|
||||||
keywords: () => splitKeywords("commands.diffViewUnified.keywords"),
|
|
||||||
action: () => options.setDiffViewMode("unified"),
|
|
||||||
})
|
|
||||||
|
|
||||||
commandRegistry.register({
|
|
||||||
id: "tool-output-default-visibility",
|
|
||||||
label: () => {
|
|
||||||
const mode = options.preferences().toolOutputExpansion || "expanded"
|
|
||||||
const state = mode === "expanded" ? tGlobal("commands.common.expanded") : tGlobal("commands.common.collapsed")
|
|
||||||
return tGlobal("commands.toolOutputsDefault.label", { state })
|
|
||||||
},
|
|
||||||
description: () => tGlobal("commands.toolOutputsDefault.description"),
|
|
||||||
category: "System",
|
|
||||||
keywords: () => splitKeywords("commands.toolOutputsDefault.keywords"),
|
|
||||||
action: () => {
|
|
||||||
const mode = options.preferences().toolOutputExpansion || "expanded"
|
|
||||||
const next: ExpansionPreference = mode === "expanded" ? "collapsed" : "expanded"
|
|
||||||
options.setToolOutputExpansion(next)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
commandRegistry.register({
|
|
||||||
id: "diagnostics-default-visibility",
|
|
||||||
label: () => {
|
|
||||||
const mode = options.preferences().diagnosticsExpansion || "expanded"
|
|
||||||
const state = mode === "expanded" ? tGlobal("commands.common.expanded") : tGlobal("commands.common.collapsed")
|
|
||||||
return tGlobal("commands.diagnosticsDefault.label", { state })
|
|
||||||
},
|
|
||||||
description: () => tGlobal("commands.diagnosticsDefault.description"),
|
|
||||||
category: "System",
|
|
||||||
keywords: () => splitKeywords("commands.diagnosticsDefault.keywords"),
|
|
||||||
action: () => {
|
|
||||||
const mode = options.preferences().diagnosticsExpansion || "expanded"
|
|
||||||
const next: ExpansionPreference = mode === "expanded" ? "collapsed" : "expanded"
|
|
||||||
options.setDiagnosticsExpansion(next)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
commandRegistry.register({
|
|
||||||
id: "tool-inputs-visibility",
|
|
||||||
label: () => {
|
|
||||||
const mode = options.preferences().toolInputsVisibility || "hidden"
|
|
||||||
const state =
|
|
||||||
mode === "expanded"
|
|
||||||
? tGlobal("commands.common.expanded")
|
|
||||||
: mode === "collapsed"
|
|
||||||
? tGlobal("commands.common.collapsed")
|
|
||||||
: tGlobal("commands.common.hidden")
|
|
||||||
return tGlobal("commands.toolInputsVisibility.label", { state })
|
|
||||||
},
|
|
||||||
description: () => tGlobal("commands.toolInputsVisibility.description"),
|
|
||||||
category: "System",
|
|
||||||
keywords: () => splitKeywords("commands.toolInputsVisibility.keywords"),
|
|
||||||
action: () => {
|
|
||||||
const mode = options.preferences().toolInputsVisibility || "hidden"
|
|
||||||
const next: ToolInputsVisibilityPreference =
|
|
||||||
mode === "hidden" ? "collapsed" : mode === "collapsed" ? "expanded" : "hidden"
|
|
||||||
options.setToolInputsVisibility(next)
|
|
||||||
},
|
|
||||||
})
|
|
||||||
|
|
||||||
commandRegistry.register({
|
|
||||||
id: "token-usage-visibility",
|
|
||||||
label: () => {
|
|
||||||
const visible = options.preferences().showUsageMetrics ?? true
|
|
||||||
const state = visible ? tGlobal("commands.common.visible") : tGlobal("commands.common.hidden")
|
|
||||||
return tGlobal("commands.tokenUsageDisplay.label", { state })
|
|
||||||
},
|
|
||||||
description: () => tGlobal("commands.tokenUsageDisplay.description"),
|
|
||||||
category: "System",
|
|
||||||
keywords: () => splitKeywords("commands.tokenUsageDisplay.keywords"),
|
|
||||||
action: options.toggleUsageMetrics,
|
|
||||||
})
|
|
||||||
|
|
||||||
commandRegistry.register({
|
|
||||||
id: "auto-cleanup-blank-sessions",
|
|
||||||
label: () => {
|
|
||||||
const enabled = options.preferences().autoCleanupBlankSessions
|
|
||||||
const state = enabled ? tGlobal("commands.common.enabled") : tGlobal("commands.common.disabled")
|
|
||||||
return tGlobal("commands.autoCleanupBlankSessions.label", { state })
|
|
||||||
},
|
|
||||||
description: () => tGlobal("commands.autoCleanupBlankSessions.description"),
|
|
||||||
category: "System",
|
|
||||||
keywords: () => splitKeywords("commands.autoCleanupBlankSessions.keywords"),
|
|
||||||
action: options.toggleAutoCleanupBlankSessions,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
commandRegistry.register({
|
commandRegistry.register({
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ export const settingsMessages = {
|
|||||||
"contextUsagePanel.unavailable": "--",
|
"contextUsagePanel.unavailable": "--",
|
||||||
|
|
||||||
"settings.title": "Settings",
|
"settings.title": "Settings",
|
||||||
"settings.description": "Manage appearance, notifications, remote access, and OpenCode runtime options.",
|
|
||||||
"settings.navigationAriaLabel": "Settings sections",
|
"settings.navigationAriaLabel": "Settings sections",
|
||||||
"settings.close": "Close settings",
|
"settings.close": "Close settings",
|
||||||
"settings.content.eyebrow": "Workspace preferences",
|
"settings.content.eyebrow": "Workspace preferences",
|
||||||
@@ -70,6 +69,7 @@ export const settingsMessages = {
|
|||||||
"settings.scope.device": "This device",
|
"settings.scope.device": "This device",
|
||||||
"settings.scope.server": "Server setting",
|
"settings.scope.server": "Server setting",
|
||||||
"settings.common.enabled": "Enabled",
|
"settings.common.enabled": "Enabled",
|
||||||
|
"settings.common.disabled": "Disabled",
|
||||||
"settings.section.appearance.title": "Appearance",
|
"settings.section.appearance.title": "Appearance",
|
||||||
"settings.section.appearance.subtitle": "Adjust how the app looks on this device.",
|
"settings.section.appearance.subtitle": "Adjust how the app looks on this device.",
|
||||||
"settings.appearance.theme.title": "Theme",
|
"settings.appearance.theme.title": "Theme",
|
||||||
@@ -112,4 +112,31 @@ export const settingsMessages = {
|
|||||||
"settings.section.opencode.subtitle": "Choose the OpenCode binary and environment used for new instances.",
|
"settings.section.opencode.subtitle": "Choose the OpenCode binary and environment used for new instances.",
|
||||||
"settings.opencode.runtime.title": "Runtime",
|
"settings.opencode.runtime.title": "Runtime",
|
||||||
"settings.opencode.runtime.subtitle": "Configure which OpenCode binary new instances launch with.",
|
"settings.opencode.runtime.subtitle": "Configure which OpenCode binary new instances launch with.",
|
||||||
|
|
||||||
|
"settings.appearance.behavior.title": "Interaction",
|
||||||
|
"settings.appearance.behavior.subtitle": "Message, diff, and input defaults.",
|
||||||
|
"settings.behavior.keyboardHints.title": "Keyboard shortcut hints",
|
||||||
|
"settings.behavior.keyboardHints.subtitle": "Show keyboard shortcut hints across the UI.",
|
||||||
|
"settings.behavior.thinking.title": "Thinking sections",
|
||||||
|
"settings.behavior.thinking.subtitle": "Show or hide AI thinking sections in messages.",
|
||||||
|
"settings.behavior.thinkingDefault.title": "Thinking default",
|
||||||
|
"settings.behavior.thinkingDefault.subtitle": "Choose whether thinking sections start expanded or collapsed.",
|
||||||
|
"settings.behavior.timelineTools.title": "Timeline tool calls",
|
||||||
|
"settings.behavior.timelineTools.subtitle": "Show or hide tool call entries in the message timeline.",
|
||||||
|
"settings.behavior.diffView.title": "Diff view",
|
||||||
|
"settings.behavior.diffView.subtitle": "Choose how tool-call diffs are displayed.",
|
||||||
|
"settings.behavior.diffView.option.split": "Split",
|
||||||
|
"settings.behavior.diffView.option.unified": "Unified",
|
||||||
|
"settings.behavior.toolOutputsDefault.title": "Tool outputs default",
|
||||||
|
"settings.behavior.toolOutputsDefault.subtitle": "Choose whether tool outputs start expanded or collapsed.",
|
||||||
|
"settings.behavior.diagnosticsDefault.title": "Diagnostics default",
|
||||||
|
"settings.behavior.diagnosticsDefault.subtitle": "Choose whether diagnostics output starts expanded or collapsed.",
|
||||||
|
"settings.behavior.toolInputsVisibility.title": "Tool inputs visibility",
|
||||||
|
"settings.behavior.toolInputsVisibility.subtitle": "Set default visibility for tool call input arguments.",
|
||||||
|
"settings.behavior.usageMetrics.title": "Token usage metrics",
|
||||||
|
"settings.behavior.usageMetrics.subtitle": "Show or hide token and cost stats for assistant messages.",
|
||||||
|
"settings.behavior.autoCleanup.title": "Auto-cleanup blank sessions",
|
||||||
|
"settings.behavior.autoCleanup.subtitle": "Automatically clean up blank sessions when creating new ones.",
|
||||||
|
"settings.behavior.promptSubmit.title": "Enter to submit",
|
||||||
|
"settings.behavior.promptSubmit.subtitle": "Use Enter to submit prompts; Cmd/Ctrl+Enter inserts a new line.",
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ export const settingsMessages = {
|
|||||||
"contextUsagePanel.unavailable": "--",
|
"contextUsagePanel.unavailable": "--",
|
||||||
|
|
||||||
"settings.title": "Settings",
|
"settings.title": "Settings",
|
||||||
"settings.description": "Manage appearance, notifications, remote access, and OpenCode runtime options.",
|
|
||||||
"settings.navigationAriaLabel": "Settings sections",
|
"settings.navigationAriaLabel": "Settings sections",
|
||||||
"settings.close": "Close settings",
|
"settings.close": "Close settings",
|
||||||
"settings.content.eyebrow": "Workspace preferences",
|
"settings.content.eyebrow": "Workspace preferences",
|
||||||
@@ -70,6 +69,7 @@ export const settingsMessages = {
|
|||||||
"settings.scope.device": "This device",
|
"settings.scope.device": "This device",
|
||||||
"settings.scope.server": "Server setting",
|
"settings.scope.server": "Server setting",
|
||||||
"settings.common.enabled": "Enabled",
|
"settings.common.enabled": "Enabled",
|
||||||
|
"settings.common.disabled": "Desactivado",
|
||||||
"settings.section.appearance.title": "Appearance",
|
"settings.section.appearance.title": "Appearance",
|
||||||
"settings.section.appearance.subtitle": "Adjust how the app looks on this device.",
|
"settings.section.appearance.subtitle": "Adjust how the app looks on this device.",
|
||||||
"settings.appearance.theme.title": "Theme",
|
"settings.appearance.theme.title": "Theme",
|
||||||
@@ -112,4 +112,31 @@ export const settingsMessages = {
|
|||||||
"settings.section.opencode.subtitle": "Choose the OpenCode binary and environment used for new instances.",
|
"settings.section.opencode.subtitle": "Choose the OpenCode binary and environment used for new instances.",
|
||||||
"settings.opencode.runtime.title": "Runtime",
|
"settings.opencode.runtime.title": "Runtime",
|
||||||
"settings.opencode.runtime.subtitle": "Configure which OpenCode binary new instances launch with.",
|
"settings.opencode.runtime.subtitle": "Configure which OpenCode binary new instances launch with.",
|
||||||
|
|
||||||
|
"settings.appearance.behavior.title": "Interaccion",
|
||||||
|
"settings.appearance.behavior.subtitle": "Valores predeterminados de mensajes, diffs y entrada.",
|
||||||
|
"settings.behavior.keyboardHints.title": "Sugerencias de atajos de teclado",
|
||||||
|
"settings.behavior.keyboardHints.subtitle": "Muestra sugerencias de atajos de teclado en toda la interfaz.",
|
||||||
|
"settings.behavior.thinking.title": "Secciones de pensamiento",
|
||||||
|
"settings.behavior.thinking.subtitle": "Muestra u oculta las secciones de pensamiento de la IA en los mensajes.",
|
||||||
|
"settings.behavior.thinkingDefault.title": "Pensamiento por defecto",
|
||||||
|
"settings.behavior.thinkingDefault.subtitle": "Elige si las secciones de pensamiento comienzan expandidas o contraidas.",
|
||||||
|
"settings.behavior.timelineTools.title": "Llamadas de herramientas en la linea de tiempo",
|
||||||
|
"settings.behavior.timelineTools.subtitle": "Muestra u oculta entradas de llamadas de herramientas en la linea de tiempo de mensajes.",
|
||||||
|
"settings.behavior.diffView.title": "Vista de diferencias",
|
||||||
|
"settings.behavior.diffView.subtitle": "Elige como se muestran los diffs de llamadas de herramientas.",
|
||||||
|
"settings.behavior.diffView.option.split": "Dividida",
|
||||||
|
"settings.behavior.diffView.option.unified": "Unificada",
|
||||||
|
"settings.behavior.toolOutputsDefault.title": "Salidas de herramientas por defecto",
|
||||||
|
"settings.behavior.toolOutputsDefault.subtitle": "Elige si las salidas de herramientas comienzan expandidas o contraidas.",
|
||||||
|
"settings.behavior.diagnosticsDefault.title": "Diagnosticos por defecto",
|
||||||
|
"settings.behavior.diagnosticsDefault.subtitle": "Elige si la salida de diagnosticos comienza expandida o contraida.",
|
||||||
|
"settings.behavior.toolInputsVisibility.title": "Visibilidad de entradas de herramientas",
|
||||||
|
"settings.behavior.toolInputsVisibility.subtitle": "Establece la visibilidad por defecto de los argumentos de entrada de las llamadas de herramientas.",
|
||||||
|
"settings.behavior.usageMetrics.title": "Metricas de uso de tokens",
|
||||||
|
"settings.behavior.usageMetrics.subtitle": "Muestra u oculta estadisticas de tokens y costo en mensajes del asistente.",
|
||||||
|
"settings.behavior.autoCleanup.title": "Limpieza automatica de sesiones en blanco",
|
||||||
|
"settings.behavior.autoCleanup.subtitle": "Limpia automaticamente las sesiones en blanco al crear nuevas.",
|
||||||
|
"settings.behavior.promptSubmit.title": "Enter para enviar",
|
||||||
|
"settings.behavior.promptSubmit.subtitle": "Usa Enter para enviar; Cmd/Ctrl+Enter inserta una nueva linea.",
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ export const settingsMessages = {
|
|||||||
"contextUsagePanel.unavailable": "--",
|
"contextUsagePanel.unavailable": "--",
|
||||||
|
|
||||||
"settings.title": "Settings",
|
"settings.title": "Settings",
|
||||||
"settings.description": "Manage appearance, notifications, remote access, and OpenCode runtime options.",
|
|
||||||
"settings.navigationAriaLabel": "Settings sections",
|
"settings.navigationAriaLabel": "Settings sections",
|
||||||
"settings.close": "Close settings",
|
"settings.close": "Close settings",
|
||||||
"settings.content.eyebrow": "Workspace preferences",
|
"settings.content.eyebrow": "Workspace preferences",
|
||||||
@@ -70,6 +69,7 @@ export const settingsMessages = {
|
|||||||
"settings.scope.device": "This device",
|
"settings.scope.device": "This device",
|
||||||
"settings.scope.server": "Server setting",
|
"settings.scope.server": "Server setting",
|
||||||
"settings.common.enabled": "Enabled",
|
"settings.common.enabled": "Enabled",
|
||||||
|
"settings.common.disabled": "Desactive",
|
||||||
"settings.section.appearance.title": "Appearance",
|
"settings.section.appearance.title": "Appearance",
|
||||||
"settings.section.appearance.subtitle": "Adjust how the app looks on this device.",
|
"settings.section.appearance.subtitle": "Adjust how the app looks on this device.",
|
||||||
"settings.appearance.theme.title": "Theme",
|
"settings.appearance.theme.title": "Theme",
|
||||||
@@ -112,4 +112,31 @@ export const settingsMessages = {
|
|||||||
"settings.section.opencode.subtitle": "Choose the OpenCode binary and environment used for new instances.",
|
"settings.section.opencode.subtitle": "Choose the OpenCode binary and environment used for new instances.",
|
||||||
"settings.opencode.runtime.title": "Runtime",
|
"settings.opencode.runtime.title": "Runtime",
|
||||||
"settings.opencode.runtime.subtitle": "Configure which OpenCode binary new instances launch with.",
|
"settings.opencode.runtime.subtitle": "Configure which OpenCode binary new instances launch with.",
|
||||||
|
|
||||||
|
"settings.appearance.behavior.title": "Interaction",
|
||||||
|
"settings.appearance.behavior.subtitle": "Parametres par defaut pour les messages, les diffs et la saisie.",
|
||||||
|
"settings.behavior.keyboardHints.title": "Indications de raccourcis clavier",
|
||||||
|
"settings.behavior.keyboardHints.subtitle": "Afficher des indications de raccourcis clavier dans toute l'interface.",
|
||||||
|
"settings.behavior.thinking.title": "Sections de reflexion",
|
||||||
|
"settings.behavior.thinking.subtitle": "Afficher ou masquer les sections de reflexion de l'IA dans les messages.",
|
||||||
|
"settings.behavior.thinkingDefault.title": "Etat initial de la reflexion",
|
||||||
|
"settings.behavior.thinkingDefault.subtitle": "Choisir si les sections de reflexion commencent developpees ou reduites.",
|
||||||
|
"settings.behavior.timelineTools.title": "Appels d'outils dans la chronologie",
|
||||||
|
"settings.behavior.timelineTools.subtitle": "Afficher ou masquer les entrees d'appels d'outils dans la chronologie des messages.",
|
||||||
|
"settings.behavior.diffView.title": "Vue du diff",
|
||||||
|
"settings.behavior.diffView.subtitle": "Choisir comment les diffs des appels d'outils sont affiches.",
|
||||||
|
"settings.behavior.diffView.option.split": "Scinde",
|
||||||
|
"settings.behavior.diffView.option.unified": "Unifie",
|
||||||
|
"settings.behavior.toolOutputsDefault.title": "Etat initial des sorties d'outils",
|
||||||
|
"settings.behavior.toolOutputsDefault.subtitle": "Choisir si les sorties d'outils commencent developpees ou reduites.",
|
||||||
|
"settings.behavior.diagnosticsDefault.title": "Etat initial des diagnostics",
|
||||||
|
"settings.behavior.diagnosticsDefault.subtitle": "Choisir si la sortie des diagnostics commence developpee ou reduite.",
|
||||||
|
"settings.behavior.toolInputsVisibility.title": "Visibilite des entrees d'outils",
|
||||||
|
"settings.behavior.toolInputsVisibility.subtitle": "Definir la visibilite par defaut des arguments d'entree des appels d'outils.",
|
||||||
|
"settings.behavior.usageMetrics.title": "Metriques d'utilisation des tokens",
|
||||||
|
"settings.behavior.usageMetrics.subtitle": "Afficher ou masquer les stats de tokens et de cout pour les messages de l'assistant.",
|
||||||
|
"settings.behavior.autoCleanup.title": "Nettoyage auto des sessions vides",
|
||||||
|
"settings.behavior.autoCleanup.subtitle": "Nettoyer automatiquement les sessions vides lors de la creation de nouvelles.",
|
||||||
|
"settings.behavior.promptSubmit.title": "Entrer pour envoyer",
|
||||||
|
"settings.behavior.promptSubmit.subtitle": "Utiliser Entrer pour envoyer; Cmd/Ctrl+Entrer insere une nouvelle ligne.",
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ export const settingsMessages = {
|
|||||||
"contextUsagePanel.unavailable": "--",
|
"contextUsagePanel.unavailable": "--",
|
||||||
|
|
||||||
"settings.title": "Settings",
|
"settings.title": "Settings",
|
||||||
"settings.description": "Manage appearance, notifications, remote access, and OpenCode runtime options.",
|
|
||||||
"settings.navigationAriaLabel": "Settings sections",
|
"settings.navigationAriaLabel": "Settings sections",
|
||||||
"settings.close": "Close settings",
|
"settings.close": "Close settings",
|
||||||
"settings.content.eyebrow": "Workspace preferences",
|
"settings.content.eyebrow": "Workspace preferences",
|
||||||
@@ -70,6 +69,7 @@ export const settingsMessages = {
|
|||||||
"settings.scope.device": "This device",
|
"settings.scope.device": "This device",
|
||||||
"settings.scope.server": "Server setting",
|
"settings.scope.server": "Server setting",
|
||||||
"settings.common.enabled": "Enabled",
|
"settings.common.enabled": "Enabled",
|
||||||
|
"settings.common.disabled": "無効",
|
||||||
"settings.section.appearance.title": "Appearance",
|
"settings.section.appearance.title": "Appearance",
|
||||||
"settings.section.appearance.subtitle": "Adjust how the app looks on this device.",
|
"settings.section.appearance.subtitle": "Adjust how the app looks on this device.",
|
||||||
"settings.appearance.theme.title": "Theme",
|
"settings.appearance.theme.title": "Theme",
|
||||||
@@ -112,4 +112,31 @@ export const settingsMessages = {
|
|||||||
"settings.section.opencode.subtitle": "Choose the OpenCode binary and environment used for new instances.",
|
"settings.section.opencode.subtitle": "Choose the OpenCode binary and environment used for new instances.",
|
||||||
"settings.opencode.runtime.title": "Runtime",
|
"settings.opencode.runtime.title": "Runtime",
|
||||||
"settings.opencode.runtime.subtitle": "Configure which OpenCode binary new instances launch with.",
|
"settings.opencode.runtime.subtitle": "Configure which OpenCode binary new instances launch with.",
|
||||||
|
|
||||||
|
"settings.appearance.behavior.title": "操作",
|
||||||
|
"settings.appearance.behavior.subtitle": "メッセージ、差分、入力の既定値。",
|
||||||
|
"settings.behavior.keyboardHints.title": "キーボードショートカットのヒント",
|
||||||
|
"settings.behavior.keyboardHints.subtitle": "UI全体でキーボードショートカットのヒントを表示します。",
|
||||||
|
"settings.behavior.thinking.title": "思考セクション",
|
||||||
|
"settings.behavior.thinking.subtitle": "メッセージ内のAIの思考セクションを表示/非表示にします。",
|
||||||
|
"settings.behavior.thinkingDefault.title": "思考の既定",
|
||||||
|
"settings.behavior.thinkingDefault.subtitle": "思考セクションを最初に展開/折りたたみのどちらで表示するかを選びます。",
|
||||||
|
"settings.behavior.timelineTools.title": "タイムラインのツール呼び出し",
|
||||||
|
"settings.behavior.timelineTools.subtitle": "メッセージタイムラインでツール呼び出しを表示/非表示にします。",
|
||||||
|
"settings.behavior.diffView.title": "差分表示",
|
||||||
|
"settings.behavior.diffView.subtitle": "ツール呼び出しの差分の表示方法を選びます。",
|
||||||
|
"settings.behavior.diffView.option.split": "分割",
|
||||||
|
"settings.behavior.diffView.option.unified": "統合",
|
||||||
|
"settings.behavior.toolOutputsDefault.title": "ツール出力の既定",
|
||||||
|
"settings.behavior.toolOutputsDefault.subtitle": "ツール出力を最初に展開/折りたたみのどちらで表示するかを選びます。",
|
||||||
|
"settings.behavior.diagnosticsDefault.title": "診断の既定",
|
||||||
|
"settings.behavior.diagnosticsDefault.subtitle": "診断出力を最初に展開/折りたたみのどちらで表示するかを選びます。",
|
||||||
|
"settings.behavior.toolInputsVisibility.title": "ツール入力の表示",
|
||||||
|
"settings.behavior.toolInputsVisibility.subtitle": "ツール呼び出しの入力引数の既定の表示状態を設定します。",
|
||||||
|
"settings.behavior.usageMetrics.title": "トークン使用量メトリクス",
|
||||||
|
"settings.behavior.usageMetrics.subtitle": "アシスタントのメッセージにトークン数とコストの統計を表示/非表示にします。",
|
||||||
|
"settings.behavior.autoCleanup.title": "空のセッションを自動クリーンアップ",
|
||||||
|
"settings.behavior.autoCleanup.subtitle": "新しいセッション作成時に空のセッションを自動的にクリーンアップします。",
|
||||||
|
"settings.behavior.promptSubmit.title": "Enterで送信",
|
||||||
|
"settings.behavior.promptSubmit.subtitle": "Enterで送信し、Cmd/Ctrl+Enterで改行します。",
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ export const settingsMessages = {
|
|||||||
"contextUsagePanel.unavailable": "--",
|
"contextUsagePanel.unavailable": "--",
|
||||||
|
|
||||||
"settings.title": "Settings",
|
"settings.title": "Settings",
|
||||||
"settings.description": "Manage appearance, notifications, remote access, and OpenCode runtime options.",
|
|
||||||
"settings.navigationAriaLabel": "Settings sections",
|
"settings.navigationAriaLabel": "Settings sections",
|
||||||
"settings.close": "Close settings",
|
"settings.close": "Close settings",
|
||||||
"settings.content.eyebrow": "Workspace preferences",
|
"settings.content.eyebrow": "Workspace preferences",
|
||||||
@@ -70,6 +69,7 @@ export const settingsMessages = {
|
|||||||
"settings.scope.device": "This device",
|
"settings.scope.device": "This device",
|
||||||
"settings.scope.server": "Server setting",
|
"settings.scope.server": "Server setting",
|
||||||
"settings.common.enabled": "Enabled",
|
"settings.common.enabled": "Enabled",
|
||||||
|
"settings.common.disabled": "Отключено",
|
||||||
"settings.section.appearance.title": "Appearance",
|
"settings.section.appearance.title": "Appearance",
|
||||||
"settings.section.appearance.subtitle": "Adjust how the app looks on this device.",
|
"settings.section.appearance.subtitle": "Adjust how the app looks on this device.",
|
||||||
"settings.appearance.theme.title": "Theme",
|
"settings.appearance.theme.title": "Theme",
|
||||||
@@ -112,4 +112,31 @@ export const settingsMessages = {
|
|||||||
"settings.section.opencode.subtitle": "Choose the OpenCode binary and environment used for new instances.",
|
"settings.section.opencode.subtitle": "Choose the OpenCode binary and environment used for new instances.",
|
||||||
"settings.opencode.runtime.title": "Runtime",
|
"settings.opencode.runtime.title": "Runtime",
|
||||||
"settings.opencode.runtime.subtitle": "Configure which OpenCode binary new instances launch with.",
|
"settings.opencode.runtime.subtitle": "Configure which OpenCode binary new instances launch with.",
|
||||||
|
|
||||||
|
"settings.appearance.behavior.title": "Взаимодействие",
|
||||||
|
"settings.appearance.behavior.subtitle": "Значения по умолчанию для сообщений, диффов и ввода.",
|
||||||
|
"settings.behavior.keyboardHints.title": "Подсказки сочетаний клавиш",
|
||||||
|
"settings.behavior.keyboardHints.subtitle": "Показывать подсказки сочетаний клавиш по всему интерфейсу.",
|
||||||
|
"settings.behavior.thinking.title": "Разделы размышлений",
|
||||||
|
"settings.behavior.thinking.subtitle": "Показывать или скрывать разделы размышлений ИИ в сообщениях.",
|
||||||
|
"settings.behavior.thinkingDefault.title": "Размышления по умолчанию",
|
||||||
|
"settings.behavior.thinkingDefault.subtitle": "Выберите, начинать ли разделы размышлений развернутыми или свернутыми.",
|
||||||
|
"settings.behavior.timelineTools.title": "Вызовы инструментов в таймлайне",
|
||||||
|
"settings.behavior.timelineTools.subtitle": "Показывать или скрывать записи вызовов инструментов в таймлайне сообщений.",
|
||||||
|
"settings.behavior.diffView.title": "Вид диффа",
|
||||||
|
"settings.behavior.diffView.subtitle": "Выберите, как отображаются диффы вызовов инструментов.",
|
||||||
|
"settings.behavior.diffView.option.split": "Раздельный",
|
||||||
|
"settings.behavior.diffView.option.unified": "Единый",
|
||||||
|
"settings.behavior.toolOutputsDefault.title": "Выводы инструментов по умолчанию",
|
||||||
|
"settings.behavior.toolOutputsDefault.subtitle": "Выберите, начинать ли выводы инструментов развернутыми или свернутыми.",
|
||||||
|
"settings.behavior.diagnosticsDefault.title": "Диагностика по умолчанию",
|
||||||
|
"settings.behavior.diagnosticsDefault.subtitle": "Выберите, начинать ли вывод диагностики развернутым или свернутым.",
|
||||||
|
"settings.behavior.toolInputsVisibility.title": "Видимость входных данных инструмента",
|
||||||
|
"settings.behavior.toolInputsVisibility.subtitle": "Задайте видимость по умолчанию для входных аргументов вызовов инструментов.",
|
||||||
|
"settings.behavior.usageMetrics.title": "Метрики использования токенов",
|
||||||
|
"settings.behavior.usageMetrics.subtitle": "Показывать или скрывать статистику токенов и стоимости в сообщениях ассистента.",
|
||||||
|
"settings.behavior.autoCleanup.title": "Автоочистка пустых сессий",
|
||||||
|
"settings.behavior.autoCleanup.subtitle": "Автоматически очищать пустые сессии при создании новых.",
|
||||||
|
"settings.behavior.promptSubmit.title": "Enter для отправки",
|
||||||
|
"settings.behavior.promptSubmit.subtitle": "Enter отправляет; Cmd/Ctrl+Enter вставляет новую строку.",
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
@@ -57,7 +57,6 @@ export const settingsMessages = {
|
|||||||
"contextUsagePanel.unavailable": "--",
|
"contextUsagePanel.unavailable": "--",
|
||||||
|
|
||||||
"settings.title": "Settings",
|
"settings.title": "Settings",
|
||||||
"settings.description": "Manage appearance, notifications, remote access, and OpenCode runtime options.",
|
|
||||||
"settings.navigationAriaLabel": "Settings sections",
|
"settings.navigationAriaLabel": "Settings sections",
|
||||||
"settings.close": "Close settings",
|
"settings.close": "Close settings",
|
||||||
"settings.content.eyebrow": "Workspace preferences",
|
"settings.content.eyebrow": "Workspace preferences",
|
||||||
@@ -70,6 +69,7 @@ export const settingsMessages = {
|
|||||||
"settings.scope.device": "This device",
|
"settings.scope.device": "This device",
|
||||||
"settings.scope.server": "Server setting",
|
"settings.scope.server": "Server setting",
|
||||||
"settings.common.enabled": "Enabled",
|
"settings.common.enabled": "Enabled",
|
||||||
|
"settings.common.disabled": "已禁用",
|
||||||
"settings.section.appearance.title": "Appearance",
|
"settings.section.appearance.title": "Appearance",
|
||||||
"settings.section.appearance.subtitle": "Adjust how the app looks on this device.",
|
"settings.section.appearance.subtitle": "Adjust how the app looks on this device.",
|
||||||
"settings.appearance.theme.title": "Theme",
|
"settings.appearance.theme.title": "Theme",
|
||||||
@@ -112,4 +112,31 @@ export const settingsMessages = {
|
|||||||
"settings.section.opencode.subtitle": "Choose the OpenCode binary and environment used for new instances.",
|
"settings.section.opencode.subtitle": "Choose the OpenCode binary and environment used for new instances.",
|
||||||
"settings.opencode.runtime.title": "Runtime",
|
"settings.opencode.runtime.title": "Runtime",
|
||||||
"settings.opencode.runtime.subtitle": "Configure which OpenCode binary new instances launch with.",
|
"settings.opencode.runtime.subtitle": "Configure which OpenCode binary new instances launch with.",
|
||||||
|
|
||||||
|
"settings.appearance.behavior.title": "交互",
|
||||||
|
"settings.appearance.behavior.subtitle": "消息、差异与输入的默认值。",
|
||||||
|
"settings.behavior.keyboardHints.title": "键盘快捷键提示",
|
||||||
|
"settings.behavior.keyboardHints.subtitle": "在整个界面中显示键盘快捷键提示。",
|
||||||
|
"settings.behavior.thinking.title": "思考区块",
|
||||||
|
"settings.behavior.thinking.subtitle": "在消息中显示或隐藏AI的思考区块。",
|
||||||
|
"settings.behavior.thinkingDefault.title": "思考默认状态",
|
||||||
|
"settings.behavior.thinkingDefault.subtitle": "选择思考区块默认是展开还是折叠。",
|
||||||
|
"settings.behavior.timelineTools.title": "时间线工具调用",
|
||||||
|
"settings.behavior.timelineTools.subtitle": "在消息时间线中显示或隐藏工具调用条目。",
|
||||||
|
"settings.behavior.diffView.title": "差异视图",
|
||||||
|
"settings.behavior.diffView.subtitle": "选择工具调用差异的显示方式。",
|
||||||
|
"settings.behavior.diffView.option.split": "分栏",
|
||||||
|
"settings.behavior.diffView.option.unified": "统一",
|
||||||
|
"settings.behavior.toolOutputsDefault.title": "工具输出默认状态",
|
||||||
|
"settings.behavior.toolOutputsDefault.subtitle": "选择工具输出默认是展开还是折叠。",
|
||||||
|
"settings.behavior.diagnosticsDefault.title": "诊断默认状态",
|
||||||
|
"settings.behavior.diagnosticsDefault.subtitle": "选择诊断输出默认是展开还是折叠。",
|
||||||
|
"settings.behavior.toolInputsVisibility.title": "工具输入可见性",
|
||||||
|
"settings.behavior.toolInputsVisibility.subtitle": "设置工具调用输入参数的默认可见性。",
|
||||||
|
"settings.behavior.usageMetrics.title": "令牌用量指标",
|
||||||
|
"settings.behavior.usageMetrics.subtitle": "显示或隐藏助手消息的令牌与成本统计。",
|
||||||
|
"settings.behavior.autoCleanup.title": "自动清理空会话",
|
||||||
|
"settings.behavior.autoCleanup.subtitle": "创建新会话时自动清理空会话。",
|
||||||
|
"settings.behavior.promptSubmit.title": "回车发送",
|
||||||
|
"settings.behavior.promptSubmit.subtitle": "使用回车发送;Cmd/Ctrl+回车插入新行。",
|
||||||
} as const
|
} as const
|
||||||
|
|||||||
452
packages/ui/src/lib/settings/behavior-registry.ts
Normal file
452
packages/ui/src/lib/settings/behavior-registry.ts
Normal file
@@ -0,0 +1,452 @@
|
|||||||
|
import type { Accessor } from "solid-js"
|
||||||
|
import type {
|
||||||
|
Preferences,
|
||||||
|
ExpansionPreference,
|
||||||
|
ToolInputsVisibilityPreference,
|
||||||
|
} from "../../stores/preferences"
|
||||||
|
import type { Command } from "../commands"
|
||||||
|
import { tGlobal } from "../i18n"
|
||||||
|
import { runtimeEnv } from "../runtime-env"
|
||||||
|
|
||||||
|
export type BehaviorSettingKind = "toggle" | "enum"
|
||||||
|
|
||||||
|
export type BehaviorToggleSetting = {
|
||||||
|
kind: "toggle"
|
||||||
|
id: string
|
||||||
|
titleKey: string
|
||||||
|
subtitleKey: string
|
||||||
|
get: (preferences: Preferences) => boolean
|
||||||
|
set: (next: boolean) => void
|
||||||
|
disabled?: () => boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BehaviorEnumSetting<T extends string = string> = {
|
||||||
|
kind: "enum"
|
||||||
|
id: string
|
||||||
|
titleKey: string
|
||||||
|
subtitleKey: string
|
||||||
|
get: (preferences: Preferences) => T
|
||||||
|
set: (next: T) => void
|
||||||
|
options: Array<{ value: T; labelKey: string }>
|
||||||
|
disabled?: () => boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export type BehaviorSetting = BehaviorToggleSetting | BehaviorEnumSetting
|
||||||
|
|
||||||
|
export type BehaviorRegistryActions = {
|
||||||
|
preferences: Accessor<Preferences>
|
||||||
|
updatePreferences?: (updates: Partial<Preferences>) => void
|
||||||
|
toggleShowThinkingBlocks: () => void
|
||||||
|
toggleKeyboardShortcutHints: () => void
|
||||||
|
toggleShowTimelineTools: () => void
|
||||||
|
toggleUsageMetrics: () => void
|
||||||
|
toggleAutoCleanupBlankSessions: () => void
|
||||||
|
togglePromptSubmitOnEnter: () => void
|
||||||
|
setDiffViewMode: (mode: "split" | "unified") => void
|
||||||
|
setToolOutputExpansion: (mode: ExpansionPreference) => void
|
||||||
|
setDiagnosticsExpansion: (mode: ExpansionPreference) => void
|
||||||
|
setThinkingBlocksExpansion: (mode: ExpansionPreference) => void
|
||||||
|
setToolInputsVisibility: (mode: ToolInputsVisibilityPreference) => void
|
||||||
|
}
|
||||||
|
|
||||||
|
function splitKeywords(key: string): string[] {
|
||||||
|
return tGlobal(key)
|
||||||
|
.split(",")
|
||||||
|
.map((value) => value.trim())
|
||||||
|
.filter(Boolean)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setBooleanByToggle(getCurrent: () => boolean, toggle: () => void, next: boolean) {
|
||||||
|
if (getCurrent() === next) return
|
||||||
|
toggle()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getBehaviorSettings(actions: BehaviorRegistryActions): BehaviorSetting[] {
|
||||||
|
const prefs = actions.preferences
|
||||||
|
const updatePreferences = actions.updatePreferences
|
||||||
|
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
kind: "toggle",
|
||||||
|
id: "behavior.keyboardShortcutHints",
|
||||||
|
titleKey: "settings.behavior.keyboardHints.title",
|
||||||
|
subtitleKey: "settings.behavior.keyboardHints.subtitle",
|
||||||
|
get: (p) => Boolean(p.showKeyboardShortcutHints ?? true),
|
||||||
|
set: (next) => {
|
||||||
|
if (updatePreferences) {
|
||||||
|
updatePreferences({ showKeyboardShortcutHints: next })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setBooleanByToggle(
|
||||||
|
() => Boolean(prefs().showKeyboardShortcutHints ?? true),
|
||||||
|
actions.toggleKeyboardShortcutHints,
|
||||||
|
next,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
disabled: () => runtimeEnv.host === "web",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "toggle",
|
||||||
|
id: "behavior.thinkingBlocks",
|
||||||
|
titleKey: "settings.behavior.thinking.title",
|
||||||
|
subtitleKey: "settings.behavior.thinking.subtitle",
|
||||||
|
get: (p) => Boolean(p.showThinkingBlocks),
|
||||||
|
set: (next) => {
|
||||||
|
if (updatePreferences) {
|
||||||
|
updatePreferences({ showThinkingBlocks: next })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setBooleanByToggle(
|
||||||
|
() => Boolean(prefs().showThinkingBlocks),
|
||||||
|
actions.toggleShowThinkingBlocks,
|
||||||
|
next,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "enum",
|
||||||
|
id: "behavior.thinkingBlocksDefault",
|
||||||
|
titleKey: "settings.behavior.thinkingDefault.title",
|
||||||
|
subtitleKey: "settings.behavior.thinkingDefault.subtitle",
|
||||||
|
get: (p) => (p.thinkingBlocksExpansion ?? "expanded") as ExpansionPreference,
|
||||||
|
set: (next) => {
|
||||||
|
if (updatePreferences) {
|
||||||
|
updatePreferences({ thinkingBlocksExpansion: next as ExpansionPreference })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
actions.setThinkingBlocksExpansion(next as ExpansionPreference)
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{ value: "expanded", labelKey: "commands.common.expanded" },
|
||||||
|
{ value: "collapsed", labelKey: "commands.common.collapsed" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "toggle",
|
||||||
|
id: "behavior.timelineToolCalls",
|
||||||
|
titleKey: "settings.behavior.timelineTools.title",
|
||||||
|
subtitleKey: "settings.behavior.timelineTools.subtitle",
|
||||||
|
get: (p) => Boolean(p.showTimelineTools),
|
||||||
|
set: (next) => {
|
||||||
|
if (updatePreferences) {
|
||||||
|
updatePreferences({ showTimelineTools: next })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setBooleanByToggle(
|
||||||
|
() => Boolean(prefs().showTimelineTools),
|
||||||
|
actions.toggleShowTimelineTools,
|
||||||
|
next,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "enum",
|
||||||
|
id: "behavior.diffViewMode",
|
||||||
|
titleKey: "settings.behavior.diffView.title",
|
||||||
|
subtitleKey: "settings.behavior.diffView.subtitle",
|
||||||
|
get: (p) => (p.diffViewMode ?? "split") as "split" | "unified",
|
||||||
|
set: (next) => {
|
||||||
|
if (updatePreferences) {
|
||||||
|
updatePreferences({ diffViewMode: next as "split" | "unified" })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
actions.setDiffViewMode(next as "split" | "unified")
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{ value: "split", labelKey: "settings.behavior.diffView.option.split" },
|
||||||
|
{ value: "unified", labelKey: "settings.behavior.diffView.option.unified" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "enum",
|
||||||
|
id: "behavior.toolOutputsDefault",
|
||||||
|
titleKey: "settings.behavior.toolOutputsDefault.title",
|
||||||
|
subtitleKey: "settings.behavior.toolOutputsDefault.subtitle",
|
||||||
|
get: (p) => (p.toolOutputExpansion ?? "expanded") as ExpansionPreference,
|
||||||
|
set: (next) => {
|
||||||
|
if (updatePreferences) {
|
||||||
|
updatePreferences({ toolOutputExpansion: next as ExpansionPreference })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
actions.setToolOutputExpansion(next as ExpansionPreference)
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{ value: "expanded", labelKey: "commands.common.expanded" },
|
||||||
|
{ value: "collapsed", labelKey: "commands.common.collapsed" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "enum",
|
||||||
|
id: "behavior.diagnosticsDefault",
|
||||||
|
titleKey: "settings.behavior.diagnosticsDefault.title",
|
||||||
|
subtitleKey: "settings.behavior.diagnosticsDefault.subtitle",
|
||||||
|
get: (p) => (p.diagnosticsExpansion ?? "expanded") as ExpansionPreference,
|
||||||
|
set: (next) => {
|
||||||
|
if (updatePreferences) {
|
||||||
|
updatePreferences({ diagnosticsExpansion: next as ExpansionPreference })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
actions.setDiagnosticsExpansion(next as ExpansionPreference)
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{ value: "expanded", labelKey: "commands.common.expanded" },
|
||||||
|
{ value: "collapsed", labelKey: "commands.common.collapsed" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "enum",
|
||||||
|
id: "behavior.toolInputsVisibility",
|
||||||
|
titleKey: "settings.behavior.toolInputsVisibility.title",
|
||||||
|
subtitleKey: "settings.behavior.toolInputsVisibility.subtitle",
|
||||||
|
get: (p) => (p.toolInputsVisibility ?? "hidden") as ToolInputsVisibilityPreference,
|
||||||
|
set: (next) => {
|
||||||
|
if (updatePreferences) {
|
||||||
|
updatePreferences({ toolInputsVisibility: next as ToolInputsVisibilityPreference })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
actions.setToolInputsVisibility(next as ToolInputsVisibilityPreference)
|
||||||
|
},
|
||||||
|
options: [
|
||||||
|
{ value: "hidden", labelKey: "commands.common.hidden" },
|
||||||
|
{ value: "collapsed", labelKey: "commands.common.collapsed" },
|
||||||
|
{ value: "expanded", labelKey: "commands.common.expanded" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "toggle",
|
||||||
|
id: "behavior.usageMetrics",
|
||||||
|
titleKey: "settings.behavior.usageMetrics.title",
|
||||||
|
subtitleKey: "settings.behavior.usageMetrics.subtitle",
|
||||||
|
get: (p) => Boolean(p.showUsageMetrics ?? true),
|
||||||
|
set: (next) => {
|
||||||
|
if (updatePreferences) {
|
||||||
|
updatePreferences({ showUsageMetrics: next })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setBooleanByToggle(
|
||||||
|
() => Boolean(prefs().showUsageMetrics ?? true),
|
||||||
|
actions.toggleUsageMetrics,
|
||||||
|
next,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "toggle",
|
||||||
|
id: "behavior.autoCleanupBlankSessions",
|
||||||
|
titleKey: "settings.behavior.autoCleanup.title",
|
||||||
|
subtitleKey: "settings.behavior.autoCleanup.subtitle",
|
||||||
|
get: (p) => Boolean(p.autoCleanupBlankSessions),
|
||||||
|
set: (next) => {
|
||||||
|
if (updatePreferences) {
|
||||||
|
updatePreferences({ autoCleanupBlankSessions: next })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setBooleanByToggle(
|
||||||
|
() => Boolean(prefs().autoCleanupBlankSessions),
|
||||||
|
actions.toggleAutoCleanupBlankSessions,
|
||||||
|
next,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
kind: "toggle",
|
||||||
|
id: "behavior.promptSubmitOnEnter",
|
||||||
|
titleKey: "settings.behavior.promptSubmit.title",
|
||||||
|
subtitleKey: "settings.behavior.promptSubmit.subtitle",
|
||||||
|
get: (p) => Boolean(p.promptSubmitOnEnter),
|
||||||
|
set: (next) => {
|
||||||
|
if (updatePreferences) {
|
||||||
|
updatePreferences({ promptSubmitOnEnter: next })
|
||||||
|
return
|
||||||
|
}
|
||||||
|
setBooleanByToggle(
|
||||||
|
() => Boolean(prefs().promptSubmitOnEnter),
|
||||||
|
actions.togglePromptSubmitOnEnter,
|
||||||
|
next,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getBehaviorCommands(actions: BehaviorRegistryActions): Command[] {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
id: "prompt-submit-shortcut",
|
||||||
|
label: () =>
|
||||||
|
actions.preferences().promptSubmitOnEnter
|
||||||
|
? tGlobal("commands.promptSubmitShortcut.label.swapped")
|
||||||
|
: tGlobal("commands.promptSubmitShortcut.label.default"),
|
||||||
|
description: () => tGlobal("commands.promptSubmitShortcut.description"),
|
||||||
|
category: "Input & Focus",
|
||||||
|
keywords: () => splitKeywords("commands.promptSubmitShortcut.keywords"),
|
||||||
|
action: actions.togglePromptSubmitOnEnter,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "thinking",
|
||||||
|
label: () =>
|
||||||
|
tGlobal(
|
||||||
|
actions.preferences().showThinkingBlocks
|
||||||
|
? "commands.thinkingBlocks.label.hide"
|
||||||
|
: "commands.thinkingBlocks.label.show",
|
||||||
|
),
|
||||||
|
description: () => tGlobal("commands.thinkingBlocks.description"),
|
||||||
|
category: "System",
|
||||||
|
keywords: () => ["/thinking", ...splitKeywords("commands.thinkingBlocks.keywords")],
|
||||||
|
action: actions.toggleShowThinkingBlocks,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "timeline-tools",
|
||||||
|
label: () =>
|
||||||
|
tGlobal(
|
||||||
|
actions.preferences().showTimelineTools
|
||||||
|
? "commands.timelineToolCalls.label.hide"
|
||||||
|
: "commands.timelineToolCalls.label.show",
|
||||||
|
),
|
||||||
|
description: () => tGlobal("commands.timelineToolCalls.description"),
|
||||||
|
category: "System",
|
||||||
|
keywords: () => splitKeywords("commands.timelineToolCalls.keywords"),
|
||||||
|
action: actions.toggleShowTimelineTools,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "keyboard-shortcut-hints",
|
||||||
|
label: () =>
|
||||||
|
tGlobal(
|
||||||
|
actions.preferences().showKeyboardShortcutHints
|
||||||
|
? "commands.keyboardShortcutHints.label.hide"
|
||||||
|
: "commands.keyboardShortcutHints.label.show",
|
||||||
|
),
|
||||||
|
description: () =>
|
||||||
|
tGlobal(
|
||||||
|
runtimeEnv.host === "web"
|
||||||
|
? "commands.keyboardShortcutHints.description.disabledWeb"
|
||||||
|
: "commands.keyboardShortcutHints.description",
|
||||||
|
),
|
||||||
|
category: "System",
|
||||||
|
keywords: () => splitKeywords("commands.keyboardShortcutHints.keywords"),
|
||||||
|
disabled: () => runtimeEnv.host === "web",
|
||||||
|
action: actions.toggleKeyboardShortcutHints,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "thinking-default-visibility",
|
||||||
|
label: () => {
|
||||||
|
const mode = actions.preferences().thinkingBlocksExpansion ?? "expanded"
|
||||||
|
const state = mode === "expanded" ? tGlobal("commands.common.expanded") : tGlobal("commands.common.collapsed")
|
||||||
|
return tGlobal("commands.thinkingBlocksDefault.label", { state })
|
||||||
|
},
|
||||||
|
description: () => tGlobal("commands.thinkingBlocksDefault.description"),
|
||||||
|
category: "System",
|
||||||
|
keywords: () => ["/thinking", ...splitKeywords("commands.thinkingBlocksDefault.keywords")],
|
||||||
|
action: () => {
|
||||||
|
const mode = actions.preferences().thinkingBlocksExpansion ?? "expanded"
|
||||||
|
const next: ExpansionPreference = mode === "expanded" ? "collapsed" : "expanded"
|
||||||
|
actions.setThinkingBlocksExpansion(next)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "diff-view-split",
|
||||||
|
label: () => {
|
||||||
|
const prefix = (actions.preferences().diffViewMode || "split") === "split" ? "✓ " : ""
|
||||||
|
return `${prefix}${tGlobal("commands.diffViewSplit.label")}`
|
||||||
|
},
|
||||||
|
description: () => tGlobal("commands.diffViewSplit.description"),
|
||||||
|
category: "System",
|
||||||
|
keywords: () => splitKeywords("commands.diffViewSplit.keywords"),
|
||||||
|
action: () => actions.setDiffViewMode("split"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "diff-view-unified",
|
||||||
|
label: () => {
|
||||||
|
const prefix = (actions.preferences().diffViewMode || "split") === "unified" ? "✓ " : ""
|
||||||
|
return `${prefix}${tGlobal("commands.diffViewUnified.label")}`
|
||||||
|
},
|
||||||
|
description: () => tGlobal("commands.diffViewUnified.description"),
|
||||||
|
category: "System",
|
||||||
|
keywords: () => splitKeywords("commands.diffViewUnified.keywords"),
|
||||||
|
action: () => actions.setDiffViewMode("unified"),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "tool-output-default-visibility",
|
||||||
|
label: () => {
|
||||||
|
const mode = actions.preferences().toolOutputExpansion || "expanded"
|
||||||
|
const state = mode === "expanded" ? tGlobal("commands.common.expanded") : tGlobal("commands.common.collapsed")
|
||||||
|
return tGlobal("commands.toolOutputsDefault.label", { state })
|
||||||
|
},
|
||||||
|
description: () => tGlobal("commands.toolOutputsDefault.description"),
|
||||||
|
category: "System",
|
||||||
|
keywords: () => splitKeywords("commands.toolOutputsDefault.keywords"),
|
||||||
|
action: () => {
|
||||||
|
const mode = actions.preferences().toolOutputExpansion || "expanded"
|
||||||
|
const next: ExpansionPreference = mode === "expanded" ? "collapsed" : "expanded"
|
||||||
|
actions.setToolOutputExpansion(next)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "diagnostics-default-visibility",
|
||||||
|
label: () => {
|
||||||
|
const mode = actions.preferences().diagnosticsExpansion || "expanded"
|
||||||
|
const state = mode === "expanded" ? tGlobal("commands.common.expanded") : tGlobal("commands.common.collapsed")
|
||||||
|
return tGlobal("commands.diagnosticsDefault.label", { state })
|
||||||
|
},
|
||||||
|
description: () => tGlobal("commands.diagnosticsDefault.description"),
|
||||||
|
category: "System",
|
||||||
|
keywords: () => splitKeywords("commands.diagnosticsDefault.keywords"),
|
||||||
|
action: () => {
|
||||||
|
const mode = actions.preferences().diagnosticsExpansion || "expanded"
|
||||||
|
const next: ExpansionPreference = mode === "expanded" ? "collapsed" : "expanded"
|
||||||
|
actions.setDiagnosticsExpansion(next)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "tool-inputs-visibility",
|
||||||
|
label: () => {
|
||||||
|
const mode = actions.preferences().toolInputsVisibility || "hidden"
|
||||||
|
const state =
|
||||||
|
mode === "expanded"
|
||||||
|
? tGlobal("commands.common.expanded")
|
||||||
|
: mode === "collapsed"
|
||||||
|
? tGlobal("commands.common.collapsed")
|
||||||
|
: tGlobal("commands.common.hidden")
|
||||||
|
return tGlobal("commands.toolInputsVisibility.label", { state })
|
||||||
|
},
|
||||||
|
description: () => tGlobal("commands.toolInputsVisibility.description"),
|
||||||
|
category: "System",
|
||||||
|
keywords: () => splitKeywords("commands.toolInputsVisibility.keywords"),
|
||||||
|
action: () => {
|
||||||
|
const mode = actions.preferences().toolInputsVisibility || "hidden"
|
||||||
|
const next: ToolInputsVisibilityPreference =
|
||||||
|
mode === "hidden" ? "collapsed" : mode === "collapsed" ? "expanded" : "hidden"
|
||||||
|
actions.setToolInputsVisibility(next)
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "token-usage-visibility",
|
||||||
|
label: () => {
|
||||||
|
const visible = actions.preferences().showUsageMetrics ?? true
|
||||||
|
const state = visible ? tGlobal("commands.common.visible") : tGlobal("commands.common.hidden")
|
||||||
|
return tGlobal("commands.tokenUsageDisplay.label", { state })
|
||||||
|
},
|
||||||
|
description: () => tGlobal("commands.tokenUsageDisplay.description"),
|
||||||
|
category: "System",
|
||||||
|
keywords: () => splitKeywords("commands.tokenUsageDisplay.keywords"),
|
||||||
|
action: actions.toggleUsageMetrics,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: "auto-cleanup-blank-sessions",
|
||||||
|
label: () => {
|
||||||
|
const enabled = actions.preferences().autoCleanupBlankSessions
|
||||||
|
const state = enabled ? tGlobal("commands.common.enabled") : tGlobal("commands.common.disabled")
|
||||||
|
return tGlobal("commands.autoCleanupBlankSessions.label", { state })
|
||||||
|
},
|
||||||
|
description: () => tGlobal("commands.autoCleanupBlankSessions.description"),
|
||||||
|
category: "System",
|
||||||
|
keywords: () => splitKeywords("commands.autoCleanupBlankSessions.keywords"),
|
||||||
|
action: actions.toggleAutoCleanupBlankSessions,
|
||||||
|
},
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
export function registerBehaviorCommands(register: (command: Command) => void, actions: BehaviorRegistryActions) {
|
||||||
|
const commands = getBehaviorCommands(actions)
|
||||||
|
commands.forEach((command) => register(command))
|
||||||
|
}
|
||||||
@@ -15,6 +15,9 @@
|
|||||||
ring-color: var(--accent-primary);
|
ring-color: var(--accent-primary);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.selector-trigger:disabled,
|
||||||
|
.selector-trigger[aria-disabled="true"],
|
||||||
|
.selector-trigger[data-disabled],
|
||||||
.selector-trigger-disabled {
|
.selector-trigger-disabled {
|
||||||
@apply opacity-50 cursor-not-allowed;
|
@apply opacity-50 cursor-not-allowed;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user