mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-17 13:55:50 +00:00
弃用 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>
118 lines
4.1 KiB
TypeScript
118 lines
4.1 KiB
TypeScript
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>
|
||
);
|
||
}
|