mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-18 06:15:51 +00:00
更新大量 tsx 原始文件; 已经迁移 login panel; 部分 (#121)
* style(B1-1): 格式化 ink/buddy/cli/context/screens/tasks/services/keybindings/state (43 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 修复了 Box.tsx 和 ScrollBox.tsx 中无效的 global.d.ts import。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-2): 格式化 commands (79 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-3): 格式化 components/messages,permissions,mcp,sandbox,shell (104 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-4): 格式化 components/PromptInput,FeedbackSurvey,tasks,agents,skills,design-system,wizard (73 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-5): 格式化 components其余 + hooks + tools (232 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * style(B1-6): 格式化 main/entrypoints/utils/moreright (21 files) 纯格式化:移除分号、React Compiler import、import 多行展开。 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * docs: 更新 README,新增 Run.ps1/TODO.md,删除 V6.md - README.md: 大幅重写,更详细版本历史和配置示例 - Run.ps1: 新增 Windows 启动脚本 - TODO.md: 新增包完成清单 - V6.md: 删除(架构重构规划已不适用) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * fix: 修复以前的问题 * fix: 修复 login 面板的问题 --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,291 +1,153 @@
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import figures from 'figures';
|
||||
import React, { useMemo } from 'react';
|
||||
import type { DiffFile } from '../../hooks/useDiffData.js';
|
||||
import { useTerminalSize } from '../../hooks/useTerminalSize.js';
|
||||
import { Box, Text } from '../../ink.js';
|
||||
import { truncateStartToWidth } from '../../utils/format.js';
|
||||
import { plural } from '../../utils/stringUtils.js';
|
||||
const MAX_VISIBLE_FILES = 5;
|
||||
import figures from 'figures'
|
||||
import React, { useMemo } from 'react'
|
||||
import type { DiffFile } from '../../hooks/useDiffData.js'
|
||||
import { useTerminalSize } from '../../hooks/useTerminalSize.js'
|
||||
import { Box, Text } from '../../ink.js'
|
||||
import { truncateStartToWidth } from '../../utils/format.js'
|
||||
import { plural } from '../../utils/stringUtils.js'
|
||||
|
||||
const MAX_VISIBLE_FILES = 5
|
||||
|
||||
type Props = {
|
||||
files: DiffFile[];
|
||||
selectedIndex: number;
|
||||
};
|
||||
export function DiffFileList(t0) {
|
||||
const $ = _c(36);
|
||||
const {
|
||||
files,
|
||||
selectedIndex
|
||||
} = t0;
|
||||
const {
|
||||
columns
|
||||
} = useTerminalSize();
|
||||
let t1;
|
||||
bb0: {
|
||||
files: DiffFile[]
|
||||
selectedIndex: number
|
||||
}
|
||||
|
||||
export function DiffFileList({ files, selectedIndex }: Props): React.ReactNode {
|
||||
const { columns } = useTerminalSize()
|
||||
|
||||
// Calculate scroll window - must be before early return for hooks rules
|
||||
const { startIndex, endIndex } = useMemo(() => {
|
||||
if (files.length === 0 || files.length <= MAX_VISIBLE_FILES) {
|
||||
let t2;
|
||||
if ($[0] !== files.length) {
|
||||
t2 = {
|
||||
startIndex: 0,
|
||||
endIndex: files.length
|
||||
};
|
||||
$[0] = files.length;
|
||||
$[1] = t2;
|
||||
} else {
|
||||
t2 = $[1];
|
||||
}
|
||||
t1 = t2;
|
||||
break bb0;
|
||||
return { startIndex: 0, endIndex: files.length }
|
||||
}
|
||||
let start = Math.max(0, selectedIndex - Math.floor(MAX_VISIBLE_FILES / 2));
|
||||
let end = start + MAX_VISIBLE_FILES;
|
||||
|
||||
// Keep selected item roughly in the middle
|
||||
let start = Math.max(0, selectedIndex - Math.floor(MAX_VISIBLE_FILES / 2))
|
||||
let end = start + MAX_VISIBLE_FILES
|
||||
|
||||
// Adjust if we're at the end
|
||||
if (end > files.length) {
|
||||
end = files.length;
|
||||
start = Math.max(0, end - MAX_VISIBLE_FILES);
|
||||
end = files.length
|
||||
start = Math.max(0, end - MAX_VISIBLE_FILES)
|
||||
}
|
||||
let t2;
|
||||
if ($[2] !== end || $[3] !== start) {
|
||||
t2 = {
|
||||
startIndex: start,
|
||||
endIndex: end
|
||||
};
|
||||
$[2] = end;
|
||||
$[3] = start;
|
||||
$[4] = t2;
|
||||
} else {
|
||||
t2 = $[4];
|
||||
}
|
||||
t1 = t2;
|
||||
}
|
||||
const {
|
||||
startIndex,
|
||||
endIndex
|
||||
} = t1;
|
||||
|
||||
return { startIndex: start, endIndex: end }
|
||||
}, [files.length, selectedIndex])
|
||||
|
||||
if (files.length === 0) {
|
||||
let t2;
|
||||
if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t2 = <Text dimColor={true}>No changed files</Text>;
|
||||
$[5] = t2;
|
||||
} else {
|
||||
t2 = $[5];
|
||||
}
|
||||
return t2;
|
||||
return <Text dimColor>No changed files</Text>
|
||||
}
|
||||
let T0;
|
||||
let hasMoreBelow;
|
||||
let needsPagination;
|
||||
let t2;
|
||||
let t3;
|
||||
let t4;
|
||||
if ($[6] !== columns || $[7] !== endIndex || $[8] !== files || $[9] !== selectedIndex || $[10] !== startIndex) {
|
||||
const visibleFiles = files.slice(startIndex, endIndex);
|
||||
const hasMoreAbove = startIndex > 0;
|
||||
hasMoreBelow = endIndex < files.length;
|
||||
needsPagination = files.length > MAX_VISIBLE_FILES;
|
||||
const maxPathWidth = Math.max(20, columns - 16 - 3 - 4);
|
||||
T0 = Box;
|
||||
t2 = "column";
|
||||
if ($[17] !== hasMoreAbove || $[18] !== needsPagination || $[19] !== startIndex) {
|
||||
t3 = needsPagination && <Text dimColor={true}>{hasMoreAbove ? ` ↑ ${startIndex} more ${plural(startIndex, "file")}` : " "}</Text>;
|
||||
$[17] = hasMoreAbove;
|
||||
$[18] = needsPagination;
|
||||
$[19] = startIndex;
|
||||
$[20] = t3;
|
||||
} else {
|
||||
t3 = $[20];
|
||||
}
|
||||
let t5;
|
||||
if ($[21] !== maxPathWidth || $[22] !== selectedIndex || $[23] !== startIndex) {
|
||||
t5 = (file, index) => <FileItem key={file.path} file={file} isSelected={startIndex + index === selectedIndex} maxPathWidth={maxPathWidth} />;
|
||||
$[21] = maxPathWidth;
|
||||
$[22] = selectedIndex;
|
||||
$[23] = startIndex;
|
||||
$[24] = t5;
|
||||
} else {
|
||||
t5 = $[24];
|
||||
}
|
||||
t4 = visibleFiles.map(t5);
|
||||
$[6] = columns;
|
||||
$[7] = endIndex;
|
||||
$[8] = files;
|
||||
$[9] = selectedIndex;
|
||||
$[10] = startIndex;
|
||||
$[11] = T0;
|
||||
$[12] = hasMoreBelow;
|
||||
$[13] = needsPagination;
|
||||
$[14] = t2;
|
||||
$[15] = t3;
|
||||
$[16] = t4;
|
||||
} else {
|
||||
T0 = $[11];
|
||||
hasMoreBelow = $[12];
|
||||
needsPagination = $[13];
|
||||
t2 = $[14];
|
||||
t3 = $[15];
|
||||
t4 = $[16];
|
||||
}
|
||||
let t5;
|
||||
if ($[25] !== endIndex || $[26] !== files.length || $[27] !== hasMoreBelow || $[28] !== needsPagination) {
|
||||
t5 = needsPagination && <Text dimColor={true}>{hasMoreBelow ? ` ↓ ${files.length - endIndex} more ${plural(files.length - endIndex, "file")}` : " "}</Text>;
|
||||
$[25] = endIndex;
|
||||
$[26] = files.length;
|
||||
$[27] = hasMoreBelow;
|
||||
$[28] = needsPagination;
|
||||
$[29] = t5;
|
||||
} else {
|
||||
t5 = $[29];
|
||||
}
|
||||
let t6;
|
||||
if ($[30] !== T0 || $[31] !== t2 || $[32] !== t3 || $[33] !== t4 || $[34] !== t5) {
|
||||
t6 = <T0 flexDirection={t2}>{t3}{t4}{t5}</T0>;
|
||||
$[30] = T0;
|
||||
$[31] = t2;
|
||||
$[32] = t3;
|
||||
$[33] = t4;
|
||||
$[34] = t5;
|
||||
$[35] = t6;
|
||||
} else {
|
||||
t6 = $[35];
|
||||
}
|
||||
return t6;
|
||||
|
||||
const visibleFiles = files.slice(startIndex, endIndex)
|
||||
const hasMoreAbove = startIndex > 0
|
||||
const hasMoreBelow = endIndex < files.length
|
||||
const needsPagination = files.length > MAX_VISIBLE_FILES
|
||||
|
||||
const statsWidth = 16
|
||||
const pointerWidth = 3
|
||||
const maxPathWidth = Math.max(20, columns - statsWidth - pointerWidth - 4)
|
||||
|
||||
return (
|
||||
<Box flexDirection="column">
|
||||
{needsPagination && (
|
||||
<Text dimColor>
|
||||
{hasMoreAbove
|
||||
? ` ↑ ${startIndex} more ${plural(startIndex, 'file')}`
|
||||
: ' '}
|
||||
</Text>
|
||||
)}
|
||||
{visibleFiles.map((file, index) => (
|
||||
<FileItem
|
||||
key={file.path}
|
||||
file={file}
|
||||
isSelected={startIndex + index === selectedIndex}
|
||||
maxPathWidth={maxPathWidth}
|
||||
/>
|
||||
))}
|
||||
{needsPagination && (
|
||||
<Text dimColor>
|
||||
{hasMoreBelow
|
||||
? ` ↓ ${files.length - endIndex} more ${plural(files.length - endIndex, 'file')}`
|
||||
: ' '}
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
function FileItem(t0) {
|
||||
const $ = _c(14);
|
||||
const {
|
||||
file,
|
||||
isSelected,
|
||||
maxPathWidth
|
||||
} = t0;
|
||||
let t1;
|
||||
if ($[0] !== file.path || $[1] !== maxPathWidth) {
|
||||
t1 = truncateStartToWidth(file.path, maxPathWidth);
|
||||
$[0] = file.path;
|
||||
$[1] = maxPathWidth;
|
||||
$[2] = t1;
|
||||
} else {
|
||||
t1 = $[2];
|
||||
}
|
||||
const displayPath = t1;
|
||||
const pointer = isSelected ? figures.pointer + " " : " ";
|
||||
const line = `${pointer}${displayPath}`;
|
||||
const t2 = isSelected ? "background" : undefined;
|
||||
let t3;
|
||||
if ($[3] !== isSelected || $[4] !== line || $[5] !== t2) {
|
||||
t3 = <Text bold={isSelected} color={t2} inverse={isSelected}>{line}</Text>;
|
||||
$[3] = isSelected;
|
||||
$[4] = line;
|
||||
$[5] = t2;
|
||||
$[6] = t3;
|
||||
} else {
|
||||
t3 = $[6];
|
||||
}
|
||||
let t4;
|
||||
if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
|
||||
t4 = <Box flexGrow={1} />;
|
||||
$[7] = t4;
|
||||
} else {
|
||||
t4 = $[7];
|
||||
}
|
||||
let t5;
|
||||
if ($[8] !== file || $[9] !== isSelected) {
|
||||
t5 = <FileStats file={file} isSelected={isSelected} />;
|
||||
$[8] = file;
|
||||
$[9] = isSelected;
|
||||
$[10] = t5;
|
||||
} else {
|
||||
t5 = $[10];
|
||||
}
|
||||
let t6;
|
||||
if ($[11] !== t3 || $[12] !== t5) {
|
||||
t6 = <Box flexDirection="row">{t3}{t4}{t5}</Box>;
|
||||
$[11] = t3;
|
||||
$[12] = t5;
|
||||
$[13] = t6;
|
||||
} else {
|
||||
t6 = $[13];
|
||||
}
|
||||
return t6;
|
||||
|
||||
function FileItem({
|
||||
file,
|
||||
isSelected,
|
||||
maxPathWidth,
|
||||
}: {
|
||||
file: DiffFile
|
||||
isSelected: boolean
|
||||
maxPathWidth: number
|
||||
}): React.ReactNode {
|
||||
const displayPath = truncateStartToWidth(file.path, maxPathWidth)
|
||||
|
||||
const pointer = isSelected ? figures.pointer + ' ' : ' '
|
||||
const line = `${pointer}${displayPath}`
|
||||
|
||||
return (
|
||||
<Box flexDirection="row">
|
||||
<Text
|
||||
bold={isSelected}
|
||||
color={isSelected ? 'background' : undefined}
|
||||
inverse={isSelected}
|
||||
>
|
||||
{line}
|
||||
</Text>
|
||||
<Box flexGrow={1} />
|
||||
<FileStats file={file} isSelected={isSelected} />
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
function FileStats(t0) {
|
||||
const $ = _c(20);
|
||||
const {
|
||||
file,
|
||||
isSelected
|
||||
} = t0;
|
||||
|
||||
function FileStats({
|
||||
file,
|
||||
isSelected,
|
||||
}: {
|
||||
file: DiffFile
|
||||
isSelected: boolean
|
||||
}): React.ReactNode {
|
||||
if (file.isUntracked) {
|
||||
const t1 = !isSelected;
|
||||
let t2;
|
||||
if ($[0] !== t1) {
|
||||
t2 = <Text dimColor={t1} italic={true}>untracked</Text>;
|
||||
$[0] = t1;
|
||||
$[1] = t2;
|
||||
} else {
|
||||
t2 = $[1];
|
||||
}
|
||||
return t2;
|
||||
return (
|
||||
<Text dimColor={!isSelected} italic>
|
||||
untracked
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
if (file.isBinary) {
|
||||
const t1 = !isSelected;
|
||||
let t2;
|
||||
if ($[2] !== t1) {
|
||||
t2 = <Text dimColor={t1} italic={true}>Binary file</Text>;
|
||||
$[2] = t1;
|
||||
$[3] = t2;
|
||||
} else {
|
||||
t2 = $[3];
|
||||
}
|
||||
return t2;
|
||||
return (
|
||||
<Text dimColor={!isSelected} italic>
|
||||
Binary file
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
if (file.isLargeFile) {
|
||||
const t1 = !isSelected;
|
||||
let t2;
|
||||
if ($[4] !== t1) {
|
||||
t2 = <Text dimColor={t1} italic={true}>Large file modified</Text>;
|
||||
$[4] = t1;
|
||||
$[5] = t2;
|
||||
} else {
|
||||
t2 = $[5];
|
||||
}
|
||||
return t2;
|
||||
return (
|
||||
<Text dimColor={!isSelected} italic>
|
||||
Large file modified
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
let t1;
|
||||
if ($[6] !== file.linesAdded || $[7] !== isSelected) {
|
||||
t1 = file.linesAdded > 0 && <Text color="diffAddedWord" bold={isSelected}>+{file.linesAdded}</Text>;
|
||||
$[6] = file.linesAdded;
|
||||
$[7] = isSelected;
|
||||
$[8] = t1;
|
||||
} else {
|
||||
t1 = $[8];
|
||||
}
|
||||
const t2 = file.linesAdded > 0 && file.linesRemoved > 0 && " ";
|
||||
let t3;
|
||||
if ($[9] !== file.linesRemoved || $[10] !== isSelected) {
|
||||
t3 = file.linesRemoved > 0 && <Text color="diffRemovedWord" bold={isSelected}>-{file.linesRemoved}</Text>;
|
||||
$[9] = file.linesRemoved;
|
||||
$[10] = isSelected;
|
||||
$[11] = t3;
|
||||
} else {
|
||||
t3 = $[11];
|
||||
}
|
||||
let t4;
|
||||
if ($[12] !== file.isTruncated || $[13] !== isSelected) {
|
||||
t4 = file.isTruncated && <Text dimColor={!isSelected}> (truncated)</Text>;
|
||||
$[12] = file.isTruncated;
|
||||
$[13] = isSelected;
|
||||
$[14] = t4;
|
||||
} else {
|
||||
t4 = $[14];
|
||||
}
|
||||
let t5;
|
||||
if ($[15] !== t1 || $[16] !== t2 || $[17] !== t3 || $[18] !== t4) {
|
||||
t5 = <Text>{t1}{t2}{t3}{t4}</Text>;
|
||||
$[15] = t1;
|
||||
$[16] = t2;
|
||||
$[17] = t3;
|
||||
$[18] = t4;
|
||||
$[19] = t5;
|
||||
} else {
|
||||
t5 = $[19];
|
||||
}
|
||||
return t5;
|
||||
// Normal or truncated file - show line counts
|
||||
return (
|
||||
<Text>
|
||||
{file.linesAdded > 0 && (
|
||||
<Text color="diffAddedWord" bold={isSelected}>
|
||||
+{file.linesAdded}
|
||||
</Text>
|
||||
)}
|
||||
{file.linesAdded > 0 && file.linesRemoved > 0 && ' '}
|
||||
{file.linesRemoved > 0 && (
|
||||
<Text color="diffRemovedWord" bold={isSelected}>
|
||||
-{file.linesRemoved}
|
||||
</Text>
|
||||
)}
|
||||
{file.isTruncated && <Text dimColor={!isSelected}> (truncated)</Text>}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user