mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-19 06:45:50 +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,142 +1,121 @@
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import * as React from 'react';
|
||||
import { Ansi, Box, Text, useAnimationFrame } from '../../ink.js';
|
||||
import { segmentTextByHighlights, type TextHighlight } from '../../utils/textHighlighting.js';
|
||||
import { ShimmerChar } from '../Spinner/ShimmerChar.js';
|
||||
import * as React from 'react'
|
||||
import { Ansi, Box, Text, useAnimationFrame } from '../../ink.js'
|
||||
import {
|
||||
segmentTextByHighlights,
|
||||
type TextHighlight,
|
||||
} from '../../utils/textHighlighting.js'
|
||||
import { ShimmerChar } from '../Spinner/ShimmerChar.js'
|
||||
|
||||
type Props = {
|
||||
text: string;
|
||||
highlights: TextHighlight[];
|
||||
};
|
||||
text: string
|
||||
highlights: TextHighlight[]
|
||||
}
|
||||
|
||||
type LinePart = {
|
||||
text: string;
|
||||
highlight: TextHighlight | undefined;
|
||||
start: number;
|
||||
};
|
||||
export function HighlightedInput(t0) {
|
||||
const $ = _c(23);
|
||||
const {
|
||||
text,
|
||||
highlights
|
||||
} = t0;
|
||||
let lines;
|
||||
if ($[0] !== highlights || $[1] !== text) {
|
||||
const segments = segmentTextByHighlights(text, highlights);
|
||||
lines = [[]];
|
||||
let pos = 0;
|
||||
text: string
|
||||
highlight: TextHighlight | undefined
|
||||
start: number
|
||||
}
|
||||
|
||||
export function HighlightedInput({ text, highlights }: Props): React.ReactNode {
|
||||
// The shimmer animation (below) re-renders this component at 20fps while the
|
||||
// ultrathink keyword is present. text/highlights are referentially stable
|
||||
// across animation ticks (parent doesn't re-render), so memoize everything
|
||||
// that derives from them: segmentTextByHighlights alone is ~85µs/call
|
||||
// (tokenize + sort + O(n²) overlap), which adds up fast at 20fps.
|
||||
const { lines, hasShimmer, sweepStart, cycleLength } = React.useMemo(() => {
|
||||
const segments = segmentTextByHighlights(text, highlights)
|
||||
|
||||
// Split segments by newlines into per-line groups. Ink's row-direction Box
|
||||
// indents continuation lines of a multi-line child to that child's X offset.
|
||||
// By splitting at newlines, each line renders as its own row, avoiding the
|
||||
// incorrect indentation when highlighted text is followed by wrapped content.
|
||||
const lines: LinePart[][] = [[]]
|
||||
let pos = 0
|
||||
for (const segment of segments) {
|
||||
const parts = segment.text.split("\n");
|
||||
const parts = segment.text.split('\n')
|
||||
for (let i = 0; i < parts.length; i++) {
|
||||
if (i > 0) {
|
||||
lines.push([]);
|
||||
pos = pos + 1;
|
||||
lines.push([])
|
||||
pos += 1
|
||||
}
|
||||
const part = parts[i];
|
||||
const part = parts[i]!
|
||||
if (part.length > 0) {
|
||||
lines[lines.length - 1].push({
|
||||
lines[lines.length - 1]!.push({
|
||||
text: part,
|
||||
highlight: segment.highlight,
|
||||
start: pos
|
||||
});
|
||||
start: pos,
|
||||
})
|
||||
}
|
||||
pos = pos + part.length;
|
||||
pos += part.length
|
||||
}
|
||||
}
|
||||
$[0] = highlights;
|
||||
$[1] = text;
|
||||
$[2] = lines;
|
||||
} else {
|
||||
lines = $[2];
|
||||
}
|
||||
let t1;
|
||||
if ($[3] !== highlights) {
|
||||
t1 = highlights.some(_temp);
|
||||
$[3] = highlights;
|
||||
$[4] = t1;
|
||||
} else {
|
||||
t1 = $[4];
|
||||
}
|
||||
const hasShimmer = t1;
|
||||
let sweepStart = 0;
|
||||
let cycleLength = 1;
|
||||
if (hasShimmer) {
|
||||
let lo = Infinity;
|
||||
let hi = -Infinity;
|
||||
if ($[5] !== hi || $[6] !== highlights || $[7] !== lo) {
|
||||
for (const h_0 of highlights) {
|
||||
if (h_0.shimmerColor) {
|
||||
lo = Math.min(lo, h_0.start);
|
||||
hi = Math.max(hi, h_0.end);
|
||||
|
||||
// Scope the sweep to shimmer-highlighted ranges so cycle time doesn't grow
|
||||
// with input length. Padding creates an offscreen pause between sweeps.
|
||||
const hasShimmer = highlights.some(h => h.shimmerColor)
|
||||
let sweepStart = 0
|
||||
let cycleLength = 1
|
||||
if (hasShimmer) {
|
||||
const padding = 10
|
||||
let lo = Infinity
|
||||
let hi = -Infinity
|
||||
for (const h of highlights) {
|
||||
if (h.shimmerColor) {
|
||||
lo = Math.min(lo, h.start)
|
||||
hi = Math.max(hi, h.end)
|
||||
}
|
||||
}
|
||||
$[5] = hi;
|
||||
$[6] = highlights;
|
||||
$[7] = lo;
|
||||
$[8] = lo;
|
||||
$[9] = hi;
|
||||
} else {
|
||||
lo = $[8] as number;
|
||||
hi = $[9] as number;
|
||||
sweepStart = lo - padding
|
||||
cycleLength = hi - lo + padding * 2
|
||||
}
|
||||
sweepStart = lo - 10;
|
||||
cycleLength = hi - lo + 20;
|
||||
}
|
||||
let t2;
|
||||
if ($[10] !== cycleLength || $[11] !== hasShimmer || $[12] !== lines || $[13] !== sweepStart) {
|
||||
t2 = {
|
||||
lines,
|
||||
hasShimmer,
|
||||
sweepStart,
|
||||
cycleLength
|
||||
};
|
||||
$[10] = cycleLength;
|
||||
$[11] = hasShimmer;
|
||||
$[12] = lines;
|
||||
$[13] = sweepStart;
|
||||
$[14] = t2;
|
||||
} else {
|
||||
t2 = $[14];
|
||||
}
|
||||
const {
|
||||
lines: lines_0,
|
||||
hasShimmer: hasShimmer_0,
|
||||
sweepStart: sweepStart_0,
|
||||
cycleLength: cycleLength_0
|
||||
} = t2;
|
||||
const [ref, time] = useAnimationFrame(hasShimmer_0 ? 50 : null);
|
||||
const glimmerIndex = hasShimmer_0 ? sweepStart_0 + Math.floor(time / 50) % cycleLength_0 : -100;
|
||||
let t3;
|
||||
if ($[15] !== glimmerIndex || $[16] !== lines_0) {
|
||||
let t4;
|
||||
if ($[18] !== glimmerIndex) {
|
||||
t4 = (lineParts, lineIndex) => <Box key={lineIndex}>{lineParts.length === 0 ? <Text> </Text> : lineParts.map((part_0, partIndex) => {
|
||||
if (part_0.highlight?.shimmerColor && part_0.highlight.color) {
|
||||
return <Text key={partIndex}>{part_0.text.split("").map((char, charIndex) => <ShimmerChar key={charIndex} char={char} index={part_0.start + charIndex} glimmerIndex={glimmerIndex} messageColor={part_0.highlight.color} shimmerColor={part_0.highlight.shimmerColor} />)}</Text>;
|
||||
}
|
||||
return <Text key={partIndex} color={part_0.highlight?.color} dimColor={part_0.highlight?.dimColor} inverse={part_0.highlight?.inverse}><Ansi>{part_0.text}</Ansi></Text>;
|
||||
})}</Box>;
|
||||
$[18] = glimmerIndex;
|
||||
$[19] = t4;
|
||||
} else {
|
||||
t4 = $[19];
|
||||
}
|
||||
t3 = lines_0.map(t4);
|
||||
$[15] = glimmerIndex;
|
||||
$[16] = lines_0;
|
||||
$[17] = t3;
|
||||
} else {
|
||||
t3 = $[17];
|
||||
}
|
||||
let t4;
|
||||
if ($[20] !== ref || $[21] !== t3) {
|
||||
t4 = <Box ref={ref} flexDirection="column">{t3}</Box>;
|
||||
$[20] = ref;
|
||||
$[21] = t3;
|
||||
$[22] = t4;
|
||||
} else {
|
||||
t4 = $[22];
|
||||
}
|
||||
return t4;
|
||||
}
|
||||
function _temp(h) {
|
||||
return h.shimmerColor;
|
||||
|
||||
return { lines, hasShimmer, sweepStart, cycleLength }
|
||||
}, [text, highlights])
|
||||
|
||||
const [ref, time] = useAnimationFrame(hasShimmer ? 50 : null)
|
||||
const glimmerIndex = hasShimmer
|
||||
? sweepStart + (Math.floor(time / 50) % cycleLength)
|
||||
: -100
|
||||
|
||||
return (
|
||||
<Box ref={ref} flexDirection="column">
|
||||
{lines.map((lineParts, lineIndex) => (
|
||||
<Box key={lineIndex}>
|
||||
{lineParts.length === 0 ? (
|
||||
<Text> </Text>
|
||||
) : (
|
||||
lineParts.map((part, partIndex) => {
|
||||
if (part.highlight?.shimmerColor && part.highlight.color) {
|
||||
return (
|
||||
<Text key={partIndex}>
|
||||
{part.text.split('').map((char, charIndex) => (
|
||||
<ShimmerChar
|
||||
key={charIndex}
|
||||
char={char}
|
||||
index={part.start + charIndex}
|
||||
glimmerIndex={glimmerIndex}
|
||||
messageColor={part.highlight!.color!}
|
||||
shimmerColor={part.highlight!.shimmerColor!}
|
||||
/>
|
||||
))}
|
||||
</Text>
|
||||
)
|
||||
}
|
||||
return (
|
||||
<Text
|
||||
key={partIndex}
|
||||
color={part.highlight?.color}
|
||||
dimColor={part.highlight?.dimColor}
|
||||
inverse={part.highlight?.inverse}
|
||||
>
|
||||
<Ansi>{part.text}</Ansi>
|
||||
</Text>
|
||||
)
|
||||
})
|
||||
)}
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user