mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-18 14:25:51 +00:00
Feature/add auto mode settings and fix bug (#368)
* refactor: 将 convertMessagesToLangfuse 参数类型从 unknown 收窄为联合类型 将 readonly unknown[] 改为 readonly LangfuseInputMessage[], 其中 LangfuseInputMessage = UserMessage | AssistantMessage | ChatCompletionMessageParam, 让调用方获得编译期类型检查。 * fix: 修复 Config 面板第二次进入时左右键无反应的问题 将左右键枚举值切换从依赖 DOM 焦点的 onKeyDown 改为 useKeybindings 系统, 确保按键在任何焦点状态下都能正确响应。同时修复 isSearchMode 初始值和布局问题。 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: 修复 PowerShellTool.isSearchOrReadCommand 在 input 为 undefined 时崩溃的问题 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat: 添加 RSS 内存指示器并解绑 auto 权限模式与 TRANSCRIPT_CLASSIFIER - 在 REPL 底栏添加 RSS 内存使用显示,512MB 以下 dimColor,512MB-1GB warning 色,1GB 以上 error 色 - auto 权限模式不再依赖 TRANSCRIPT_CLASSIFIER feature flag,classifier 不可用时 fallback 到 prompting - Config 面板 defaultPermissionMode 使用类型安全的 permissionModeFromString,显示改用 shortTitle - bypassPermissions title 缩短为 Bypass 与 shortTitle 一致 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix: 同步 permissionModeTitle 测试断言与 bypassPermissions 的新 title 值 Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -16,6 +16,7 @@ import {
|
||||
import chalk from 'chalk';
|
||||
import {
|
||||
permissionModeTitle,
|
||||
permissionModeShortTitle,
|
||||
permissionModeFromString,
|
||||
toExternalPermissionMode,
|
||||
isExternalPermissionMode,
|
||||
@@ -153,7 +154,7 @@ export function Config({
|
||||
const initialLanguage = React.useRef(currentLanguage);
|
||||
const [selectedIndex, setSelectedIndex] = useState(0);
|
||||
const [scrollOffset, setScrollOffset] = useState(0);
|
||||
const [isSearchMode, setIsSearchMode] = useState(true);
|
||||
const [isSearchMode, setIsSearchMode] = useState(false);
|
||||
const isTerminalFocused = useTerminalFocus();
|
||||
const { rows } = useTerminalSize();
|
||||
// contentHeight is set by Settings.tsx (same value passed to Tabs to fix
|
||||
@@ -167,6 +168,9 @@ export function Config({
|
||||
const thinkingEnabled = useAppState(s => s.thinkingEnabled);
|
||||
const isFastMode = useAppState(s => (isFastModeEnabled() ? s.fastMode : false));
|
||||
const promptSuggestionEnabled = useAppState(s => s.promptSuggestionEnabled);
|
||||
const currentDefaultPermissionMode = permissionModeFromString(
|
||||
settingsData?.permissions?.defaultMode ?? 'default',
|
||||
);
|
||||
// Show auto in the default-mode dropdown when the user has opted in OR the
|
||||
// config is fully 'enabled' — even if currently circuit-broken ('disabled'),
|
||||
// an opted-in user should still see it in settings (it's a temporary state).
|
||||
@@ -558,27 +562,23 @@ export function Config({
|
||||
{
|
||||
id: 'defaultPermissionMode',
|
||||
label: 'Default permission mode',
|
||||
value: settingsData?.permissions?.defaultMode || 'default',
|
||||
value: currentDefaultPermissionMode,
|
||||
options: (() => {
|
||||
const priorityOrder: PermissionMode[] = ['default', 'plan'];
|
||||
const allModes: readonly PermissionMode[] = feature('TRANSCRIPT_CLASSIFIER')
|
||||
? PERMISSION_MODES
|
||||
: EXTERNAL_PERMISSION_MODES;
|
||||
const excluded: PermissionMode[] = ['bypassPermissions'];
|
||||
if (feature('TRANSCRIPT_CLASSIFIER') && !showAutoInDefaultModePicker) {
|
||||
excluded.push('auto');
|
||||
}
|
||||
return [...priorityOrder, ...allModes.filter(m => !priorityOrder.includes(m) && !excluded.includes(m))];
|
||||
return [...priorityOrder, ...PERMISSION_MODES.filter(m => !priorityOrder.includes(m))];
|
||||
})(),
|
||||
type: 'enum' as const,
|
||||
onChange(mode: string) {
|
||||
const parsedMode = permissionModeFromString(mode);
|
||||
// Internal modes (e.g. auto) are stored directly
|
||||
const validatedMode = isExternalPermissionMode(parsedMode) ? toExternalPermissionMode(parsedMode) : parsedMode;
|
||||
// auto is an internal-only mode — store it directly, don't convert
|
||||
// to its external mapping ('default') which would make it invisible.
|
||||
const validatedMode = parsedMode === 'auto'
|
||||
? parsedMode
|
||||
: (isExternalPermissionMode(parsedMode) ? toExternalPermissionMode(parsedMode) : parsedMode);
|
||||
const result = updateSettingsForSource('userSettings', {
|
||||
permissions: {
|
||||
...settingsData?.permissions,
|
||||
defaultMode: validatedMode as ExternalPermissionMode,
|
||||
defaultMode: validatedMode as (typeof PERMISSION_MODES)[number],
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1548,6 +1548,8 @@ export function Config({
|
||||
'scroll:lineUp': () => moveSelection(-1),
|
||||
'scroll:lineDown': () => moveSelection(1),
|
||||
'select:accept': toggleSetting,
|
||||
'select:previousValue': () => toggleSetting(),
|
||||
'select:nextValue': () => toggleSetting(),
|
||||
'settings:search': () => {
|
||||
setIsSearchMode(true);
|
||||
setSearchQuery('');
|
||||
@@ -1936,13 +1938,13 @@ export function Config({
|
||||
|
||||
return (
|
||||
<React.Fragment key={setting.id}>
|
||||
<Box>
|
||||
<Box width="100%">
|
||||
<Box width={44}>
|
||||
<Text color={isSelected ? 'suggestion' : undefined}>
|
||||
{isSelected ? figures.pointer : ' '} {setting.label}
|
||||
</Text>
|
||||
</Box>
|
||||
<Box key={isSelected ? 'selected' : 'unselected'}>
|
||||
<Box flexGrow={1}>
|
||||
{setting.type === 'boolean' ? (
|
||||
<>
|
||||
<Text color={isSelected ? 'suggestion' : undefined}>{setting.value.toString()}</Text>
|
||||
@@ -1963,7 +1965,7 @@ export function Config({
|
||||
</Text>
|
||||
) : setting.id === 'defaultPermissionMode' ? (
|
||||
<Text color={isSelected ? 'suggestion' : undefined}>
|
||||
{permissionModeTitle(setting.value as PermissionMode)}
|
||||
{permissionModeShortTitle(setting.value as PermissionMode)}
|
||||
</Text>
|
||||
) : setting.id === 'autoUpdatesChannel' && autoUpdaterDisabledReason ? (
|
||||
<Box flexDirection="column">
|
||||
|
||||
Reference in New Issue
Block a user