Files
claude-code/src/components/EffortPanel/EffortPanel.tsx
claude-code-best 15216eb2e6 fix(effort): 统一用色版——选中 suggestion(蓝),未选中 subtle(灰)
弃用 purple_FOR_SUBAGENTS_ONLY(subagent 专用)。改与项目其他面板一致:
- 选中档位 + ▲:color="suggestion"(Medium blue rgb(87,105,247))+ bold
- 未选中档位 + 空 ▲ 占位:color="subtle"(Light gray rgb(175,175,175))
- 标题 / Faster / Smarter:color="suggestion"
- 分隔线 / 副标签 / 底栏:color="subtle"

Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
2026-06-14 14:43:24 +08:00

118 lines
4.1 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import * as React from 'react';
import { Box, Text } from '@anthropic/ink';
import { useKeybindings } from '../../keybindings/useKeybinding.js';
import { type EffortValue, getDisplayedEffortLevel, getEffortEnvOverride } from '../../utils/effort.js';
import {
type PanelPosition,
CANCEL_MESSAGE,
computeConfirmOutcome,
getInitialCursor,
moveLeft,
moveRight,
PANEL_POSITIONS,
} from './effortPanelState.js';
import { executeEffort } from '../../commands/effort/effort.js';
import { useMainLoopModel } from '../../hooks/useMainLoopModel.js';
import { useSetAppState } from '../../state/AppState.js';
// 每档固定宽度Ink Box 自动对齐。PANEL_WIDTH = SEGMENT * 6。
const SEGMENT = 12;
const PANEL_WIDTH = SEGMENT * PANEL_POSITIONS.length;
const SUBLABEL_ULTRACODE = 'xhigh + workflows';
type Props = {
appStateEffort: EffortValue | undefined;
onDone: (message: string) => void;
};
export function EffortPanel({ appStateEffort, onDone }: Props): React.ReactNode {
const setAppState = useSetAppState();
const model = useMainLoopModel();
const envOverride = getEffortEnvOverride();
const displayed = getDisplayedEffortLevel(model, appStateEffort);
const initialCursor = getInitialCursor({ envOverride, appStateEffort, displayed });
const [cursor, setCursor] = React.useState<PanelPosition>(initialCursor);
const [done, setDone] = React.useState(false);
const handleConfirm = React.useCallback(() => {
if (done) return;
setDone(true);
const outcome = computeConfirmOutcome(cursor, executeEffort);
if (outcome.kind === 'apply' && outcome.effortUpdate) {
setAppState(prev => ({
...prev,
effortValue: outcome.effortUpdate!.value,
}));
}
onDone(outcome.message);
}, [cursor, done, onDone, setAppState]);
const handleCancel = React.useCallback(() => {
if (done) return;
setDone(true);
onDone(CANCEL_MESSAGE);
}, [done, onDone]);
useKeybindings(
{
'effortPanel:decrease': () => setCursor(c => moveLeft(c)),
'effortPanel:increase': () => setCursor(c => moveRight(c)),
'effortPanel:home': () => setCursor('low'),
'effortPanel:end': () => setCursor('ultracode'),
'effortPanel:confirm': handleConfirm,
'effortPanel:cancel': handleCancel,
},
{ context: 'EffortPanel' },
);
const envActive = envOverride !== null && envOverride !== undefined;
const envRaw = process.env.CLAUDE_CODE_EFFORT_LEVEL;
return (
<Box flexDirection="column" paddingX={1} width={PANEL_WIDTH + 2}>
<Text bold color="suggestion">
Effort
</Text>
{envActive && <Text color="warning">{`⚠ CLAUDE_CODE_EFFORT_LEVEL=${envRaw} overrides this session`}</Text>}
<Box marginTop={1} flexDirection="row" justifyContent="space-between">
<Text color="suggestion">Faster</Text>
<Text color="suggestion">Smarter</Text>
</Box>
{/* 分隔线 */}
<Text color="subtle">{'─'.repeat(PANEL_WIDTH)}</Text>
{/* ▲ 行:每段独立居中,与下方档位文字严格对齐 */}
<Box flexDirection="row">
{PANEL_POSITIONS.map(p => (
<Box key={`cursor-${p}`} width={SEGMENT} justifyContent="center">
<Text bold color={cursor === p ? 'suggestion' : 'subtle'}>
{cursor === p ? '▲' : ' '}
</Text>
</Box>
))}
</Box>
{/* 档位名:选中 suggestion + bold未选中 subtle */}
<Box flexDirection="row">
{PANEL_POSITIONS.map(p => (
<Box key={`label-${p}`} width={SEGMENT} justifyContent="center">
<Text bold={cursor === p} color={cursor === p ? 'suggestion' : 'subtle'}>
{p}
</Text>
</Box>
))}
</Box>
{/* ultracode 副标签:右对齐到最末段 */}
<Box flexDirection="row">
<Box width={SEGMENT * (PANEL_POSITIONS.length - 1)} />
<Box width={SEGMENT} justifyContent="center">
<Text color="subtle">{SUBLABEL_ULTRACODE}</Text>
</Box>
</Box>
<Box marginTop={1}>
<Text color="subtle">/ adjust · Enter confirm · Esc cancel</Text>
</Box>
</Box>
);
}