mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-21 15:55: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,177 +1,151 @@
|
||||
import { c as _c } from "react/compiler-runtime";
|
||||
import figures from 'figures';
|
||||
import React, { useMemo } from 'react';
|
||||
import { useTerminalSize } from '../../../hooks/useTerminalSize.js';
|
||||
import { stringWidth } from '../../../ink/stringWidth.js';
|
||||
import { Box, Text } from '../../../ink.js';
|
||||
import type { Question } from '../../../tools/AskUserQuestionTool/AskUserQuestionTool.js';
|
||||
import { truncateToWidth } from '../../../utils/format.js';
|
||||
import figures from 'figures'
|
||||
import React, { useMemo } from 'react'
|
||||
import { useTerminalSize } from '../../../hooks/useTerminalSize.js'
|
||||
import { stringWidth } from '../../../ink/stringWidth.js'
|
||||
import { Box, Text } from '../../../ink.js'
|
||||
import type { Question } from '../../../tools/AskUserQuestionTool/AskUserQuestionTool.js'
|
||||
import { truncateToWidth } from '../../../utils/format.js'
|
||||
|
||||
type Props = {
|
||||
questions: Question[];
|
||||
currentQuestionIndex: number;
|
||||
answers: Record<string, string>;
|
||||
hideSubmitTab?: boolean;
|
||||
};
|
||||
export function QuestionNavigationBar(t0) {
|
||||
const $ = _c(39);
|
||||
const {
|
||||
questions,
|
||||
currentQuestionIndex,
|
||||
answers,
|
||||
hideSubmitTab: t1
|
||||
} = t0;
|
||||
const hideSubmitTab = t1 === undefined ? false : t1;
|
||||
const {
|
||||
columns
|
||||
} = useTerminalSize();
|
||||
let t2;
|
||||
if ($[0] !== columns || $[1] !== currentQuestionIndex || $[2] !== hideSubmitTab || $[3] !== questions) {
|
||||
bb0: {
|
||||
const submitText = hideSubmitTab ? "" : ` ${figures.tick} Submit `;
|
||||
const fixedWidth = stringWidth("\u2190 ") + stringWidth(" \u2192") + stringWidth(submitText);
|
||||
const availableForTabs = columns - fixedWidth;
|
||||
if (availableForTabs <= 0) {
|
||||
let t3;
|
||||
if ($[5] !== currentQuestionIndex || $[6] !== questions) {
|
||||
let t4;
|
||||
if ($[8] !== currentQuestionIndex) {
|
||||
t4 = (q, index) => {
|
||||
const header = q?.header || `Q${index + 1}`;
|
||||
return index === currentQuestionIndex ? header.slice(0, 3) : "";
|
||||
};
|
||||
$[8] = currentQuestionIndex;
|
||||
$[9] = t4;
|
||||
} else {
|
||||
t4 = $[9];
|
||||
}
|
||||
t3 = questions.map(t4);
|
||||
$[5] = currentQuestionIndex;
|
||||
$[6] = questions;
|
||||
$[7] = t3;
|
||||
} else {
|
||||
t3 = $[7];
|
||||
}
|
||||
t2 = t3;
|
||||
break bb0;
|
||||
}
|
||||
const tabHeaders = questions.map(_temp);
|
||||
const idealWidths = tabHeaders.map(_temp2);
|
||||
const totalIdealWidth = idealWidths.reduce(_temp3, 0);
|
||||
if (totalIdealWidth <= availableForTabs) {
|
||||
t2 = tabHeaders;
|
||||
break bb0;
|
||||
}
|
||||
const currentHeader = tabHeaders[currentQuestionIndex] || "";
|
||||
const currentIdealWidth = 4 + stringWidth(currentHeader);
|
||||
const currentTabWidth = Math.min(currentIdealWidth, availableForTabs / 2);
|
||||
const remainingWidth = availableForTabs - currentTabWidth;
|
||||
const otherTabCount = questions.length - 1;
|
||||
const widthPerOtherTab = Math.max(6, Math.floor(remainingWidth / Math.max(otherTabCount, 1)));
|
||||
let t3;
|
||||
if ($[10] !== currentQuestionIndex || $[11] !== currentTabWidth || $[12] !== widthPerOtherTab) {
|
||||
t3 = (header_1, index_1) => {
|
||||
if (index_1 === currentQuestionIndex) {
|
||||
const maxTextWidth = currentTabWidth - 2 - 2;
|
||||
return truncateToWidth(header_1, maxTextWidth);
|
||||
} else {
|
||||
const maxTextWidth_0 = widthPerOtherTab - 2 - 2;
|
||||
return truncateToWidth(header_1, maxTextWidth_0);
|
||||
}
|
||||
};
|
||||
$[10] = currentQuestionIndex;
|
||||
$[11] = currentTabWidth;
|
||||
$[12] = widthPerOtherTab;
|
||||
$[13] = t3;
|
||||
questions: Question[]
|
||||
currentQuestionIndex: number
|
||||
answers: Record<string, string>
|
||||
hideSubmitTab?: boolean
|
||||
}
|
||||
|
||||
export function QuestionNavigationBar({
|
||||
questions,
|
||||
currentQuestionIndex,
|
||||
answers,
|
||||
hideSubmitTab = false,
|
||||
}: Props): React.ReactNode {
|
||||
const { columns } = useTerminalSize()
|
||||
|
||||
// Calculate the display text for each tab based on available width
|
||||
const tabDisplayTexts = useMemo(() => {
|
||||
// Calculate fixed width elements
|
||||
const leftArrow = '← '
|
||||
const rightArrow = ' →'
|
||||
const submitText = hideSubmitTab ? '' : ` ${figures.tick} Submit `
|
||||
const checkboxWidth = 2 // checkbox + space
|
||||
const paddingPerTab = 2 // space before and after each tab text
|
||||
|
||||
const fixedWidth =
|
||||
stringWidth(leftArrow) + stringWidth(rightArrow) + stringWidth(submitText)
|
||||
|
||||
// Available width for all question tabs
|
||||
const availableForTabs = columns - fixedWidth
|
||||
|
||||
if (availableForTabs <= 0) {
|
||||
// Terminal too narrow, fallback to minimal display
|
||||
return questions.map((q: Question, index: number) => {
|
||||
const header = q?.header || `Q${index + 1}`
|
||||
return index === currentQuestionIndex ? header.slice(0, 3) : ''
|
||||
})
|
||||
}
|
||||
|
||||
// Calculate ideal width for each tab (checkbox + padding + text)
|
||||
const tabHeaders = questions.map(
|
||||
(q: Question, index: number) => q?.header || `Q${index + 1}`,
|
||||
)
|
||||
const idealWidths = tabHeaders.map(
|
||||
header => checkboxWidth + paddingPerTab + stringWidth(header),
|
||||
)
|
||||
|
||||
// Calculate total ideal width
|
||||
const totalIdealWidth = idealWidths.reduce((sum, w) => sum + w, 0)
|
||||
|
||||
// If everything fits, use full headers
|
||||
if (totalIdealWidth <= availableForTabs) {
|
||||
return tabHeaders
|
||||
}
|
||||
|
||||
// Need to truncate - prioritize current tab
|
||||
const currentHeader = tabHeaders[currentQuestionIndex] || ''
|
||||
const currentIdealWidth =
|
||||
checkboxWidth + paddingPerTab + stringWidth(currentHeader)
|
||||
|
||||
// Minimum width for other tabs (checkbox + padding + 1 char + ellipsis)
|
||||
const minWidthPerTab = checkboxWidth + paddingPerTab + 2 // "X…"
|
||||
|
||||
// Calculate space for current tab (try to show full text)
|
||||
const currentTabWidth = Math.min(currentIdealWidth, availableForTabs / 2)
|
||||
const remainingWidth = availableForTabs - currentTabWidth
|
||||
|
||||
// Calculate space for other tabs
|
||||
const otherTabCount = questions.length - 1
|
||||
const widthPerOtherTab = Math.max(
|
||||
minWidthPerTab,
|
||||
Math.floor(remainingWidth / Math.max(otherTabCount, 1)),
|
||||
)
|
||||
|
||||
return tabHeaders.map((header, index) => {
|
||||
if (index === currentQuestionIndex) {
|
||||
// Current tab - show as much as possible
|
||||
const maxTextWidth = currentTabWidth - checkboxWidth - paddingPerTab
|
||||
return truncateToWidth(header, maxTextWidth)
|
||||
} else {
|
||||
t3 = $[13];
|
||||
// Other tabs - truncate to fit
|
||||
const maxTextWidth = widthPerOtherTab - checkboxWidth - paddingPerTab
|
||||
return truncateToWidth(header, maxTextWidth)
|
||||
}
|
||||
t2 = tabHeaders.map(t3);
|
||||
}
|
||||
$[0] = columns;
|
||||
$[1] = currentQuestionIndex;
|
||||
$[2] = hideSubmitTab;
|
||||
$[3] = questions;
|
||||
$[4] = t2;
|
||||
} else {
|
||||
t2 = $[4];
|
||||
}
|
||||
const tabDisplayTexts = t2;
|
||||
const hideArrows = questions.length === 1 && hideSubmitTab;
|
||||
let t3;
|
||||
if ($[14] !== currentQuestionIndex || $[15] !== hideArrows) {
|
||||
t3 = !hideArrows && <Text color={currentQuestionIndex === 0 ? "inactive" : undefined}>←{" "}</Text>;
|
||||
$[14] = currentQuestionIndex;
|
||||
$[15] = hideArrows;
|
||||
$[16] = t3;
|
||||
} else {
|
||||
t3 = $[16];
|
||||
}
|
||||
let t4;
|
||||
if ($[17] !== answers || $[18] !== currentQuestionIndex || $[19] !== questions || $[20] !== tabDisplayTexts) {
|
||||
let t5;
|
||||
if ($[22] !== answers || $[23] !== currentQuestionIndex || $[24] !== tabDisplayTexts) {
|
||||
t5 = (q_1, index_2) => {
|
||||
const isSelected = index_2 === currentQuestionIndex;
|
||||
const isAnswered = q_1?.question && !!answers[q_1.question];
|
||||
const checkbox = isAnswered ? figures.checkboxOn : figures.checkboxOff;
|
||||
const displayText = tabDisplayTexts[index_2] || q_1?.header || `Q${index_2 + 1}`;
|
||||
return <Box key={q_1?.question || `question-${index_2}`}>{isSelected ? <Text backgroundColor="permission" color="inverseText">{" "}{checkbox} {displayText}{" "}</Text> : <Text>{" "}{checkbox} {displayText}{" "}</Text>}</Box>;
|
||||
};
|
||||
$[22] = answers;
|
||||
$[23] = currentQuestionIndex;
|
||||
$[24] = tabDisplayTexts;
|
||||
$[25] = t5;
|
||||
} else {
|
||||
t5 = $[25];
|
||||
}
|
||||
t4 = questions.map(t5);
|
||||
$[17] = answers;
|
||||
$[18] = currentQuestionIndex;
|
||||
$[19] = questions;
|
||||
$[20] = tabDisplayTexts;
|
||||
$[21] = t4;
|
||||
} else {
|
||||
t4 = $[21];
|
||||
}
|
||||
let t5;
|
||||
if ($[26] !== currentQuestionIndex || $[27] !== hideSubmitTab || $[28] !== questions.length) {
|
||||
t5 = !hideSubmitTab && <Box key="submit">{currentQuestionIndex === questions.length ? <Text backgroundColor="permission" color="inverseText">{" "}{figures.tick} Submit{" "}</Text> : <Text> {figures.tick} Submit </Text>}</Box>;
|
||||
$[26] = currentQuestionIndex;
|
||||
$[27] = hideSubmitTab;
|
||||
$[28] = questions.length;
|
||||
$[29] = t5;
|
||||
} else {
|
||||
t5 = $[29];
|
||||
}
|
||||
let t6;
|
||||
if ($[30] !== currentQuestionIndex || $[31] !== hideArrows || $[32] !== questions.length) {
|
||||
t6 = !hideArrows && <Text color={currentQuestionIndex === questions.length ? "inactive" : undefined}>{" "}→</Text>;
|
||||
$[30] = currentQuestionIndex;
|
||||
$[31] = hideArrows;
|
||||
$[32] = questions.length;
|
||||
$[33] = t6;
|
||||
} else {
|
||||
t6 = $[33];
|
||||
}
|
||||
let t7;
|
||||
if ($[34] !== t3 || $[35] !== t4 || $[36] !== t5 || $[37] !== t6) {
|
||||
t7 = <Box flexDirection="row" marginBottom={1}>{t3}{t4}{t5}{t6}</Box>;
|
||||
$[34] = t3;
|
||||
$[35] = t4;
|
||||
$[36] = t5;
|
||||
$[37] = t6;
|
||||
$[38] = t7;
|
||||
} else {
|
||||
t7 = $[38];
|
||||
}
|
||||
return t7;
|
||||
}
|
||||
function _temp3(sum, w) {
|
||||
return sum + w;
|
||||
}
|
||||
function _temp2(header_0) {
|
||||
return 4 + stringWidth(header_0);
|
||||
}
|
||||
function _temp(q_0, index_0) {
|
||||
return q_0?.header || `Q${index_0 + 1}`;
|
||||
})
|
||||
}, [questions, currentQuestionIndex, columns, hideSubmitTab])
|
||||
|
||||
const hideArrows = questions.length === 1 && hideSubmitTab
|
||||
|
||||
return (
|
||||
<Box flexDirection="row" marginBottom={1}>
|
||||
{!hideArrows && (
|
||||
<Text color={currentQuestionIndex === 0 ? 'inactive' : undefined}>
|
||||
←{' '}
|
||||
</Text>
|
||||
)}
|
||||
{questions.map((q: Question, index: number) => {
|
||||
const isSelected = index === currentQuestionIndex
|
||||
const isAnswered = q?.question && !!answers[q.question]
|
||||
const checkbox = isAnswered ? figures.checkboxOn : figures.checkboxOff
|
||||
const displayText =
|
||||
tabDisplayTexts[index] || q?.header || `Q${index + 1}`
|
||||
|
||||
return (
|
||||
<Box key={q?.question || `question-${index}`}>
|
||||
{isSelected ? (
|
||||
<Text backgroundColor="permission" color="inverseText">
|
||||
{' '}
|
||||
{checkbox} {displayText}{' '}
|
||||
</Text>
|
||||
) : (
|
||||
<Text>
|
||||
{' '}
|
||||
{checkbox} {displayText}{' '}
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
)
|
||||
})}
|
||||
{!hideSubmitTab && (
|
||||
<Box key="submit">
|
||||
{currentQuestionIndex === questions.length ? (
|
||||
<Text backgroundColor="permission" color="inverseText">
|
||||
{' '}
|
||||
{figures.tick} Submit{' '}
|
||||
</Text>
|
||||
) : (
|
||||
<Text> {figures.tick} Submit </Text>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
{!hideArrows && (
|
||||
<Text
|
||||
color={
|
||||
currentQuestionIndex === questions.length ? 'inactive' : undefined
|
||||
}
|
||||
>
|
||||
{' '}
|
||||
→
|
||||
</Text>
|
||||
)}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user