feat: 添加工具类命令(teleport、recap、break-cache、env、tui 等)

- /teleport: 从 claude.ai 恢复会话
- /recap: 生成会话摘要
- /break-cache: 提示缓存管理(once/always/off/status)
- /env: 环境信息展示(含密钥脱敏)
- /tui: 无闪烁 TUI 模式管理
- /onboarding: 引导流程
- /perf-issue: 性能问题诊断
- /debug-tool-call: 工具调用调试
- /usage: 用量统计(合并 /cost 和 /stats 别名)

Co-Authored-By: glm-5-turbo <zai-org@claude-code-best.win>
This commit is contained in:
claude-code-best
2026-05-09 23:04:31 +08:00
parent 6766f08e47
commit fdddb6dbe8
38 changed files with 5494 additions and 43 deletions

100
src/commands/tui/panel.tsx Normal file
View File

@@ -0,0 +1,100 @@
import React, { useMemo, useState } from 'react';
import { Box, Dialog, Text, useInput } from '@anthropic/ink';
import type { LocalJSXCommandOnDone } from '../../types/command.js';
import { callTui } from './index.js';
type TuiAction = {
label: string;
description: string;
run: () => void;
};
const ACTION_LABEL_COLUMN_WIDTH = 24;
async function runTuiAction(subcommand: string, onDone: LocalJSXCommandOnDone): Promise<void> {
const result = await callTui(subcommand);
if (result.type === 'text') {
onDone(result.value, { display: 'system' });
}
}
function TuiPanel({ onDone }: { onDone: LocalJSXCommandOnDone }): React.ReactNode {
const [selectedIndex, setSelectedIndex] = useState(0);
const actions = useMemo<TuiAction[]>(
() => [
{
label: 'Status',
description: 'Show marker and environment override state',
run: () => void runTuiAction('status', onDone),
},
{
label: 'Toggle',
description: 'Flip persisted TUI mode for the next session',
run: () => void runTuiAction('toggle', onDone),
},
{
label: 'On',
description: 'Enable flicker-free alternate-screen mode',
run: () => void runTuiAction('on', onDone),
},
{
label: 'Off',
description: 'Disable flicker-free alternate-screen mode',
run: () => void runTuiAction('off', onDone),
},
],
[onDone],
);
const selectCurrent = () => {
const action = actions[selectedIndex];
if (!action) return;
action.run();
};
useInput((_input, key) => {
if (key.upArrow) {
setSelectedIndex(index => Math.max(0, index - 1));
return;
}
if (key.downArrow) {
setSelectedIndex(index => Math.min(actions.length - 1, index + 1));
return;
}
if (key.return) {
selectCurrent();
}
});
return (
<Dialog
title="TUI Mode"
subtitle={`${actions.length} actions`}
onCancel={() => onDone('TUI mode panel dismissed', { display: 'system' })}
color="background"
hideInputGuide
>
<Box flexDirection="column">
{actions.map((action, index) => (
<Box key={action.label} flexDirection="row">
<Text>{`${index === selectedIndex ? '' : ' '} ${action.label}`.padEnd(ACTION_LABEL_COLUMN_WIDTH)}</Text>
<Text dimColor>{action.description}</Text>
</Box>
))}
<Box marginTop={1}>
<Text dimColor>/ select · Enter run · Esc close</Text>
</Box>
</Box>
</Dialog>
);
}
export async function call(onDone: LocalJSXCommandOnDone, _context: unknown, args?: string): Promise<React.ReactNode> {
const trimmed = args?.trim() ?? '';
if (trimmed) {
await runTuiAction(trimmed, onDone);
return null;
}
return <TuiPanel onDone={onDone} />;
}