mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-15 21:05:51 +00:00
feat(effort): 新增 EffortPanel 纯函数状态模块(PanelPosition + 移动/初始光标)
仅含纯函数与类型,无 React/Ink 依赖,便于单测。 - PANEL_POSITIONS:low → medium → high → xhigh → max → ultracode - moveLeft/moveRight:边界钳制(low 不再左移、ultracode 不再右移) - getInitialCursor:env override > displayed level Co-Authored-By: glm-5.2 <zai-org@claude-code-best.win>
This commit is contained in:
101
src/components/EffortPanel/__tests__/effortPanelState.test.ts
Normal file
101
src/components/EffortPanel/__tests__/effortPanelState.test.ts
Normal file
@@ -0,0 +1,101 @@
|
||||
import { describe, expect, test } from 'bun:test'
|
||||
import {
|
||||
END_POSITION,
|
||||
HOME_POSITION,
|
||||
PANEL_POSITIONS,
|
||||
type PanelPosition,
|
||||
getInitialCursor,
|
||||
isUltracode,
|
||||
moveLeft,
|
||||
moveRight,
|
||||
} from '../effortPanelState.js'
|
||||
|
||||
describe('effortPanelState', () => {
|
||||
test('PANEL_POSITIONS 顺序为 low → ultracode', () => {
|
||||
expect(PANEL_POSITIONS).toEqual([
|
||||
'low',
|
||||
'medium',
|
||||
'high',
|
||||
'xhigh',
|
||||
'max',
|
||||
'ultracode',
|
||||
])
|
||||
})
|
||||
|
||||
test('moveLeft 在 low 处保持 low', () => {
|
||||
expect(moveLeft('low')).toBe('low')
|
||||
})
|
||||
|
||||
test('moveLeft 正常左移', () => {
|
||||
expect(moveLeft('high')).toBe('medium')
|
||||
expect(moveLeft('ultracode')).toBe('max')
|
||||
})
|
||||
|
||||
test('moveRight 在 ultracode 处保持 ultracode', () => {
|
||||
expect(moveRight('ultracode')).toBe('ultracode')
|
||||
})
|
||||
|
||||
test('moveRight 正常右移', () => {
|
||||
expect(moveRight('medium')).toBe('high')
|
||||
expect(moveRight('max')).toBe('ultracode')
|
||||
})
|
||||
|
||||
test('HOME_POSITION 等于 low', () => {
|
||||
expect(HOME_POSITION).toBe('low')
|
||||
})
|
||||
|
||||
test('END_POSITION 等于 ultracode', () => {
|
||||
expect(END_POSITION).toBe('ultracode')
|
||||
})
|
||||
|
||||
test('isUltracode 守卫', () => {
|
||||
expect(isUltracode('ultracode')).toBe(true)
|
||||
expect(isUltracode('max')).toBe(false)
|
||||
})
|
||||
|
||||
test('getInitialCursor:env override 为合法档位时返回 env 值', () => {
|
||||
expect(
|
||||
getInitialCursor({
|
||||
envOverride: 'high',
|
||||
appStateEffort: 'medium',
|
||||
displayed: 'high',
|
||||
}),
|
||||
).toBe('high')
|
||||
})
|
||||
|
||||
test('getInitialCursor:env 为 null(unset)时用 displayed', () => {
|
||||
expect(
|
||||
getInitialCursor({
|
||||
envOverride: null,
|
||||
appStateEffort: undefined,
|
||||
displayed: 'medium',
|
||||
}),
|
||||
).toBe('medium')
|
||||
})
|
||||
|
||||
test('getInitialCursor:env undefined 时用 displayed', () => {
|
||||
expect(
|
||||
getInitialCursor({
|
||||
envOverride: undefined,
|
||||
appStateEffort: 'high',
|
||||
displayed: 'high',
|
||||
}),
|
||||
).toBe('high')
|
||||
})
|
||||
|
||||
test('getInitialCursor:env 是数值(ant-only)时落回 displayed', () => {
|
||||
// 数值不是合法 PanelPosition,回退
|
||||
expect(
|
||||
getInitialCursor({
|
||||
envOverride: 75,
|
||||
appStateEffort: 'medium',
|
||||
displayed: 'medium',
|
||||
}),
|
||||
).toBe('medium')
|
||||
})
|
||||
|
||||
test('PanelPosition 类型编译期检查(隐式)', () => {
|
||||
const p: PanelPosition = 'xhigh'
|
||||
expect(p).toBe('xhigh')
|
||||
})
|
||||
})
|
||||
91
src/components/EffortPanel/effortPanelState.ts
Normal file
91
src/components/EffortPanel/effortPanelState.ts
Normal file
@@ -0,0 +1,91 @@
|
||||
import type { EffortValue } from '../../utils/effort.js'
|
||||
|
||||
/**
|
||||
* 光标在面板上的位置。仅面板内部使用,不进入 AppState / settings / API。
|
||||
* 'ultracode' 不是 EffortLevel;它在本面板里仅作视觉占位与文案引导。
|
||||
*/
|
||||
export type PanelPosition =
|
||||
| 'low'
|
||||
| 'medium'
|
||||
| 'high'
|
||||
| 'xhigh'
|
||||
| 'max'
|
||||
| 'ultracode'
|
||||
|
||||
export const PANEL_POSITIONS: readonly PanelPosition[] = [
|
||||
'low',
|
||||
'medium',
|
||||
'high',
|
||||
'xhigh',
|
||||
'max',
|
||||
'ultracode',
|
||||
] as const
|
||||
|
||||
export const HOME_POSITION: PanelPosition = 'low'
|
||||
export const END_POSITION: PanelPosition = 'ultracode'
|
||||
|
||||
/**
|
||||
* 判断一个值是否可作为面板光标位置(不含 ultracode,因 ultracode 仅由面板内部产生)。
|
||||
*/
|
||||
function isNonUltracodePosition(
|
||||
value: unknown,
|
||||
): value is Exclude<PanelPosition, 'ultracode'> {
|
||||
return (
|
||||
typeof value === 'string' &&
|
||||
value !== 'ultracode' &&
|
||||
(PANEL_POSITIONS as readonly string[]).includes(value)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 把 EffortValue 归一化为面板可用的光标位置。
|
||||
* - null / undefined / 数值(ant-only)/ ultracode → undefined(让上层用 displayed)
|
||||
* - 合法 string 档位 → 返回该档位
|
||||
*/
|
||||
function normalizeToPanelPosition(
|
||||
value: EffortValue | null | undefined,
|
||||
): PanelPosition | undefined {
|
||||
if (value === null || value === undefined) return undefined
|
||||
if (typeof value === 'number') return undefined
|
||||
if (isNonUltracodePosition(value)) {
|
||||
return value
|
||||
}
|
||||
return undefined
|
||||
}
|
||||
|
||||
export function moveLeft(cursor: PanelPosition): PanelPosition {
|
||||
const idx = PANEL_POSITIONS.indexOf(cursor)
|
||||
if (idx <= 0) return PANEL_POSITIONS[0]
|
||||
return PANEL_POSITIONS[idx - 1]
|
||||
}
|
||||
|
||||
export function moveRight(cursor: PanelPosition): PanelPosition {
|
||||
const idx = PANEL_POSITIONS.indexOf(cursor)
|
||||
if (idx === -1 || idx >= PANEL_POSITIONS.length - 1) {
|
||||
return PANEL_POSITIONS[PANEL_POSITIONS.length - 1]
|
||||
}
|
||||
return PANEL_POSITIONS[idx + 1]
|
||||
}
|
||||
|
||||
export function isUltracode(cursor: PanelPosition): boolean {
|
||||
return cursor === 'ultracode'
|
||||
}
|
||||
|
||||
/**
|
||||
* 决定面板挂载时的初始光标位置。
|
||||
* 优先级:env override(若是合法档位)> displayed level
|
||||
*
|
||||
* @param envOverride getEffortEnvOverride() 的返回值:EffortValue | null | undefined
|
||||
* @param appStateEffort AppState.effortValue
|
||||
* @param displayed getDisplayedEffortLevel(model, appStateEffort) —— 必传,避免此处再依赖 model
|
||||
*/
|
||||
export function getInitialCursor(args: {
|
||||
envOverride: EffortValue | null | undefined
|
||||
appStateEffort: EffortValue | undefined
|
||||
displayed: PanelPosition
|
||||
}): PanelPosition {
|
||||
const fromEnv = normalizeToPanelPosition(args.envOverride)
|
||||
if (fromEnv !== undefined) return fromEnv
|
||||
// displayed 已经是 EffortLevel(不含 ultracode),合法
|
||||
return args.displayed
|
||||
}
|
||||
Reference in New Issue
Block a user