更新大量 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:
claude-code-best
2026-04-04 23:24:27 +08:00
committed by GitHub
parent 02694918b5
commit 5b1a52b8e0
559 changed files with 103807 additions and 101817 deletions

View File

@@ -1,367 +1,326 @@
import { c as _c } from "react/compiler-runtime";
import type { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs';
import React, { useMemo } from 'react';
import { useTerminalSize } from 'src/hooks/useTerminalSize.js';
import type { ThemeName } from 'src/utils/theme.js';
import type { Command } from '../../commands.js';
import { BLACK_CIRCLE } from '../../constants/figures.js';
import { stringWidth } from '../../ink/stringWidth.js';
import { Box, Text, useTheme } from '../../ink.js';
import { useAppStateMaybeOutsideOfProvider } from '../../state/AppState.js';
import { findToolByName, type Tool, type ToolProgressData, type Tools } from '../../Tool.js';
import type { ProgressMessage } from '../../types/message.js';
import { useIsClassifierChecking } from '../../utils/classifierApprovalsHook.js';
import { logError } from '../../utils/log.js';
import type { buildMessageLookups } from '../../utils/messages.js';
import { MessageResponse } from '../MessageResponse.js';
import { useSelectedMessageBg } from '../messageActions.js';
import { SentryErrorBoundary } from '../SentryErrorBoundary.js';
import { ToolUseLoader } from '../ToolUseLoader.js';
import { HookProgressMessage } from './HookProgressMessage.js';
import type { ToolUseBlockParam } from '@anthropic-ai/sdk/resources/index.mjs'
import React, { useMemo } from 'react'
import { useTerminalSize } from 'src/hooks/useTerminalSize.js'
import type { ThemeName } from 'src/utils/theme.js'
import type { Command } from '../../commands.js'
import { BLACK_CIRCLE } from '../../constants/figures.js'
import { stringWidth } from '../../ink/stringWidth.js'
import { Box, Text, useTheme } from '../../ink.js'
import { useAppStateMaybeOutsideOfProvider } from '../../state/AppState.js'
import {
findToolByName,
type Tool,
type ToolProgressData,
type Tools,
} from '../../Tool.js'
import type { ProgressMessage } from '../../types/message.js'
import { useIsClassifierChecking } from '../../utils/classifierApprovalsHook.js'
import { logError } from '../../utils/log.js'
import type { buildMessageLookups } from '../../utils/messages.js'
import { MessageResponse } from '../MessageResponse.js'
import { useSelectedMessageBg } from '../messageActions.js'
import { SentryErrorBoundary } from '../SentryErrorBoundary.js'
import { ToolUseLoader } from '../ToolUseLoader.js'
import { HookProgressMessage } from './HookProgressMessage.js'
type Props = {
param: ToolUseBlockParam;
addMargin: boolean;
tools: Tools;
commands: Command[];
verbose: boolean;
inProgressToolUseIDs: Set<string>;
progressMessagesForMessage: ProgressMessage[];
shouldAnimate: boolean;
shouldShowDot: boolean;
inProgressToolCallCount?: number;
lookups: ReturnType<typeof buildMessageLookups>;
isTranscriptMode?: boolean;
};
export function AssistantToolUseMessage(t0) {
const $ = _c(81);
const {
param,
addMargin,
tools,
commands,
verbose,
inProgressToolUseIDs,
progressMessagesForMessage,
shouldAnimate,
shouldShowDot,
inProgressToolCallCount,
lookups,
isTranscriptMode
} = t0;
const terminalSize = useTerminalSize();
const [theme] = useTheme();
const bg = useSelectedMessageBg();
const pendingWorkerRequest = useAppStateMaybeOutsideOfProvider(_temp);
const isClassifierCheckingRaw = useIsClassifierChecking(param.id);
const permissionMode = useAppStateMaybeOutsideOfProvider(_temp2);
const hasStrippedRules = useAppStateMaybeOutsideOfProvider(_temp3);
const isAutoClassifier = permissionMode === "auto" || permissionMode === "plan" && hasStrippedRules;
const isClassifierChecking = false && isClassifierCheckingRaw && permissionMode !== "auto";
let t1;
if ($[0] !== param.input || $[1] !== param.name || $[2] !== tools) {
bb0: {
if (!tools) {
t1 = null;
break bb0;
}
const tool = findToolByName(tools, param.name);
if (!tool) {
t1 = null;
break bb0;
}
const input = tool.inputSchema.safeParse(param.input);
const data = input.success ? input.data : undefined;
t1 = {
tool,
input,
userFacingToolName: tool.userFacingName(data),
userFacingToolNameBackgroundColor: tool.userFacingNameBackgroundColor?.(data),
isTransparentWrapper: tool.isTransparentWrapper?.() ?? false
};
param: ToolUseBlockParam
addMargin: boolean
tools: Tools
commands: Command[]
verbose: boolean
inProgressToolUseIDs: Set<string>
progressMessagesForMessage: ProgressMessage[]
shouldAnimate: boolean
shouldShowDot: boolean
inProgressToolCallCount?: number
lookups: ReturnType<typeof buildMessageLookups>
isTranscriptMode?: boolean
}
export function AssistantToolUseMessage({
param,
addMargin,
tools,
commands,
verbose,
inProgressToolUseIDs,
progressMessagesForMessage,
shouldAnimate,
shouldShowDot,
inProgressToolCallCount,
lookups,
isTranscriptMode,
}: Props): React.ReactNode {
const terminalSize = useTerminalSize()
const [theme] = useTheme()
const bg = useSelectedMessageBg()
const pendingWorkerRequest = useAppStateMaybeOutsideOfProvider(
state => state.pendingWorkerRequest,
)
const isClassifierCheckingRaw = useIsClassifierChecking(param.id)
const permissionMode = useAppStateMaybeOutsideOfProvider(
state => state.toolPermissionContext.mode,
)
// strippedDangerousRules is set by stripDangerousPermissionsForAutoMode
// (even to {}) whenever auto is active, and cleared by restoreDangerousPermissions
// on deactivation — a reliable proxy for isAutoModeActive() during plan.
// prePlanMode would be stale after transitionPlanAutoMode deactivates mid-plan.
const hasStrippedRules = useAppStateMaybeOutsideOfProvider(
state => !!state.toolPermissionContext.strippedDangerousRules,
)
const isAutoClassifier =
permissionMode === 'auto' || (permissionMode === 'plan' && hasStrippedRules)
const isClassifierChecking =
process.env.USER_TYPE === 'ant' &&
isClassifierCheckingRaw &&
permissionMode !== 'auto'
// Memoize on param identity (stable — from the persisted message object).
// Zod safeParse allocates per call, and some tools' userFacingName()
// (BashTool → shouldUseSandbox → shell-quote parse) are expensive. Without
// this, ~50 bash messages × shell-quote-per-render pushed transition
// render past the shimmer tick → abort → infinite retry (#21605).
const parsed = useMemo(() => {
if (!tools) return null
const tool = findToolByName(tools, param.name)
if (!tool) return null
const input = tool.inputSchema.safeParse(param.input)
const data = input.success ? input.data : undefined
return {
tool,
input,
userFacingToolName: tool.userFacingName(data),
userFacingToolNameBackgroundColor:
tool.userFacingNameBackgroundColor?.(data),
isTransparentWrapper: tool.isTransparentWrapper?.() ?? false,
}
$[0] = param.input;
$[1] = param.name;
$[2] = tools;
$[3] = t1;
} else {
t1 = $[3];
}
const parsed = t1;
}, [tools, param])
if (!parsed) {
logError(new Error(tools ? `Tool ${param.name} not found` : `Tools array is undefined for tool ${param.name}`));
return null;
// Guard against undefined tools (required prop) or unknown tool name
logError(
new Error(
tools
? `Tool ${param.name} not found`
: `Tools array is undefined for tool ${param.name}`,
),
)
return null
}
const {
tool: tool_0,
input: input_0,
tool,
input,
userFacingToolName,
userFacingToolNameBackgroundColor,
isTransparentWrapper
} = parsed;
let t2;
if ($[4] !== lookups.resolvedToolUseIDs || $[5] !== param.id) {
t2 = lookups.resolvedToolUseIDs.has(param.id);
$[4] = lookups.resolvedToolUseIDs;
$[5] = param.id;
$[6] = t2;
} else {
t2 = $[6];
}
const isResolved = t2;
let t3;
if ($[7] !== inProgressToolUseIDs || $[8] !== isResolved || $[9] !== param.id) {
t3 = !inProgressToolUseIDs.has(param.id) && !isResolved;
$[7] = inProgressToolUseIDs;
$[8] = isResolved;
$[9] = param.id;
$[10] = t3;
} else {
t3 = $[10];
}
const isQueued = t3;
const isWaitingForPermission = pendingWorkerRequest?.toolUseId === param.id;
isTransparentWrapper,
} = parsed
const isResolved = lookups.resolvedToolUseIDs.has(param.id)
const isQueued = !inProgressToolUseIDs.has(param.id) && !isResolved
const isWaitingForPermission = pendingWorkerRequest?.toolUseId === param.id
if (isTransparentWrapper) {
if (isQueued || isResolved) {
return null;
}
let t4;
if ($[11] !== inProgressToolCallCount || $[12] !== isTranscriptMode || $[13] !== lookups || $[14] !== param.id || $[15] !== progressMessagesForMessage || $[16] !== terminalSize || $[17] !== tool_0 || $[18] !== tools || $[19] !== verbose) {
t4 = renderToolUseProgressMessage(tool_0, tools, lookups, param.id, progressMessagesForMessage, {
verbose,
inProgressToolCallCount,
isTranscriptMode
}, terminalSize);
$[11] = inProgressToolCallCount;
$[12] = isTranscriptMode;
$[13] = lookups;
$[14] = param.id;
$[15] = progressMessagesForMessage;
$[16] = terminalSize;
$[17] = tool_0;
$[18] = tools;
$[19] = verbose;
$[20] = t4;
} else {
t4 = $[20];
}
let t5;
if ($[21] !== bg || $[22] !== t4) {
t5 = <Box flexDirection="column" width="100%" backgroundColor={bg}>{t4}</Box>;
$[21] = bg;
$[22] = t4;
$[23] = t5;
} else {
t5 = $[23];
}
return t5;
if (isQueued || isResolved) return null
return (
<Box flexDirection="column" width="100%" backgroundColor={bg}>
{renderToolUseProgressMessage(
tool,
tools,
lookups,
param.id,
progressMessagesForMessage,
{ verbose, inProgressToolCallCount, isTranscriptMode },
terminalSize,
)}
</Box>
)
}
if (userFacingToolName === "") {
return null;
if (userFacingToolName === '') {
return null
}
let t4;
if ($[24] !== commands || $[25] !== input_0.data || $[26] !== input_0.success || $[27] !== theme || $[28] !== tool_0 || $[29] !== verbose) {
t4 = input_0.success ? renderToolUseMessage(tool_0, input_0.data, {
theme,
verbose,
commands
}) : null;
$[24] = commands;
$[25] = input_0.data;
$[26] = input_0.success;
$[27] = theme;
$[28] = tool_0;
$[29] = verbose;
$[30] = t4;
} else {
t4 = $[30];
}
const renderedToolUseMessage = t4;
const renderedToolUseMessage = input.success
? renderToolUseMessage(tool, input.data, { theme, verbose, commands })
: null
if (renderedToolUseMessage === null) {
return null;
return null
}
const t5 = addMargin ? 1 : 0;
const t6 = stringWidth(userFacingToolName) + (shouldShowDot ? 2 : 0);
let t7;
if ($[31] !== isQueued || $[32] !== isResolved || $[33] !== lookups.erroredToolUseIDs || $[34] !== param.id || $[35] !== shouldAnimate || $[36] !== shouldShowDot) {
t7 = shouldShowDot && (isQueued ? <Box minWidth={2}><Text dimColor={isQueued}>{BLACK_CIRCLE}</Text></Box> : <ToolUseLoader shouldAnimate={shouldAnimate} isUnresolved={!isResolved} isError={lookups.erroredToolUseIDs.has(param.id)} />);
$[31] = isQueued;
$[32] = isResolved;
$[33] = lookups.erroredToolUseIDs;
$[34] = param.id;
$[35] = shouldAnimate;
$[36] = shouldShowDot;
$[37] = t7;
} else {
t7 = $[37];
}
const t8 = userFacingToolNameBackgroundColor ? "inverseText" : undefined;
let t9;
if ($[38] !== t8 || $[39] !== userFacingToolName || $[40] !== userFacingToolNameBackgroundColor) {
t9 = <Box flexShrink={0}><Text bold={true} wrap="truncate-end" backgroundColor={userFacingToolNameBackgroundColor} color={t8}>{userFacingToolName}</Text></Box>;
$[38] = t8;
$[39] = userFacingToolName;
$[40] = userFacingToolNameBackgroundColor;
$[41] = t9;
} else {
t9 = $[41];
}
let t10;
if ($[42] !== renderedToolUseMessage) {
t10 = renderedToolUseMessage !== "" && <Box flexWrap="nowrap"><Text>({renderedToolUseMessage})</Text></Box>;
$[42] = renderedToolUseMessage;
$[43] = t10;
} else {
t10 = $[43];
}
let t11;
if ($[44] !== input_0.data || $[45] !== input_0.success || $[46] !== tool_0) {
t11 = input_0.success && tool_0.renderToolUseTag && tool_0.renderToolUseTag(input_0.data);
$[44] = input_0.data;
$[45] = input_0.success;
$[46] = tool_0;
$[47] = t11;
} else {
t11 = $[47];
}
let t12;
if ($[48] !== t10 || $[49] !== t11 || $[50] !== t6 || $[51] !== t7 || $[52] !== t9) {
t12 = <Box flexDirection="row" flexWrap="nowrap" minWidth={t6}>{t7}{t9}{t10}{t11}</Box>;
$[48] = t10;
$[49] = t11;
$[50] = t6;
$[51] = t7;
$[52] = t9;
$[53] = t12;
} else {
t12 = $[53];
}
let t13;
if ($[54] !== inProgressToolCallCount || $[55] !== isAutoClassifier || $[56] !== isClassifierChecking || $[57] !== isQueued || $[58] !== isResolved || $[59] !== isTranscriptMode || $[60] !== isWaitingForPermission || $[61] !== lookups || $[62] !== param.id || $[63] !== progressMessagesForMessage || $[64] !== terminalSize || $[65] !== tool_0 || $[66] !== tools || $[67] !== verbose) {
t13 = !isResolved && !isQueued && (isClassifierChecking ? <MessageResponse height={1}><Text dimColor={true}>{isAutoClassifier ? "Auto classifier checking\u2026" : "Bash classifier checking\u2026"}</Text></MessageResponse> : isWaitingForPermission ? <MessageResponse height={1}><Text dimColor={true}>Waiting for permission</Text></MessageResponse> : renderToolUseProgressMessage(tool_0, tools, lookups, param.id, progressMessagesForMessage, {
verbose,
inProgressToolCallCount,
isTranscriptMode
}, terminalSize));
$[54] = inProgressToolCallCount;
$[55] = isAutoClassifier;
$[56] = isClassifierChecking;
$[57] = isQueued;
$[58] = isResolved;
$[59] = isTranscriptMode;
$[60] = isWaitingForPermission;
$[61] = lookups;
$[62] = param.id;
$[63] = progressMessagesForMessage;
$[64] = terminalSize;
$[65] = tool_0;
$[66] = tools;
$[67] = verbose;
$[68] = t13;
} else {
t13 = $[68];
}
let t14;
if ($[69] !== isQueued || $[70] !== isResolved || $[71] !== tool_0) {
t14 = !isResolved && isQueued && renderToolUseQueuedMessage(tool_0);
$[69] = isQueued;
$[70] = isResolved;
$[71] = tool_0;
$[72] = t14;
} else {
t14 = $[72];
}
let t15;
if ($[73] !== t12 || $[74] !== t13 || $[75] !== t14) {
t15 = <Box flexDirection="column">{t12}{t13}{t14}</Box>;
$[73] = t12;
$[74] = t13;
$[75] = t14;
$[76] = t15;
} else {
t15 = $[76];
}
let t16;
if ($[77] !== bg || $[78] !== t15 || $[79] !== t5) {
t16 = <Box flexDirection="row" justifyContent="space-between" marginTop={t5} width="100%" backgroundColor={bg}>{t15}</Box>;
$[77] = bg;
$[78] = t15;
$[79] = t5;
$[80] = t16;
} else {
t16 = $[80];
}
return t16;
return (
<Box
flexDirection="row"
justifyContent="space-between"
marginTop={addMargin ? 1 : 0}
width="100%"
backgroundColor={bg}
>
<Box flexDirection="column">
<Box
flexDirection="row"
flexWrap="nowrap"
minWidth={stringWidth(userFacingToolName) + (shouldShowDot ? 2 : 0)}
>
{shouldShowDot &&
(isQueued ? (
<Box minWidth={2}>
<Text dimColor={isQueued}>{BLACK_CIRCLE}</Text>
</Box>
) : (
// WARNING: The code here and in ToolUseLoader is particularly
// sensitive to what *should* just be trivial refactorings. See
// the comment in ToolUseLoader for more details.
<ToolUseLoader
shouldAnimate={shouldAnimate}
isUnresolved={!isResolved}
isError={lookups.erroredToolUseIDs.has(param.id)}
/>
))}
<Box flexShrink={0}>
<Text
bold
wrap="truncate-end"
backgroundColor={userFacingToolNameBackgroundColor}
color={
userFacingToolNameBackgroundColor ? 'inverseText' : undefined
}
>
{userFacingToolName}
</Text>
</Box>
{renderedToolUseMessage !== '' && (
<Box flexWrap="nowrap">
<Text>({renderedToolUseMessage})</Text>
</Box>
)}
{/* Render tool-specific tags (timeout, model, resume ID, etc.) */}
{input.success &&
tool.renderToolUseTag &&
tool.renderToolUseTag(input.data)}
</Box>
{!isResolved &&
!isQueued &&
(isClassifierChecking ? (
<MessageResponse height={1}>
<Text dimColor>
{isAutoClassifier
? 'Auto classifier checking\u2026'
: 'Bash classifier checking\u2026'}
</Text>
</MessageResponse>
) : isWaitingForPermission ? (
<MessageResponse height={1}>
<Text dimColor>Waiting for permission</Text>
</MessageResponse>
) : (
renderToolUseProgressMessage(
tool,
tools,
lookups,
param.id,
progressMessagesForMessage,
{
verbose,
inProgressToolCallCount,
isTranscriptMode,
},
terminalSize,
)
))}
{!isResolved && isQueued && renderToolUseQueuedMessage(tool)}
</Box>
</Box>
)
}
function _temp3(state_1) {
return !!state_1.toolPermissionContext.strippedDangerousRules;
}
function _temp2(state_0) {
return state_0.toolPermissionContext.mode;
}
function _temp(state) {
return state.pendingWorkerRequest;
}
function renderToolUseMessage(tool: Tool, input: unknown, {
theme,
verbose,
commands
}: {
theme: ThemeName;
verbose: boolean;
commands: Command[];
}): React.ReactNode {
function renderToolUseMessage(
tool: Tool,
input: unknown,
{
theme,
verbose,
commands,
}: { theme: ThemeName; verbose: boolean; commands: Command[] },
): React.ReactNode {
try {
const parsed = tool.inputSchema.safeParse(input);
const parsed = tool.inputSchema.safeParse(input)
if (!parsed.success) {
return '';
return ''
}
return tool.renderToolUseMessage(parsed.data, {
theme,
verbose,
commands
});
return tool.renderToolUseMessage(parsed.data, { theme, verbose, commands })
} catch (error) {
logError(new Error(`Error rendering tool use message for ${tool.name}: ${error}`));
return '';
logError(
new Error(`Error rendering tool use message for ${tool.name}: ${error}`),
)
return ''
}
}
function renderToolUseProgressMessage(tool: Tool, tools: Tools, lookups: ReturnType<typeof buildMessageLookups>, toolUseID: string, progressMessagesForMessage: ProgressMessage[], {
verbose,
inProgressToolCallCount,
isTranscriptMode
}: {
verbose: boolean;
inProgressToolCallCount?: number;
isTranscriptMode?: boolean;
}, terminalSize: {
columns: number;
rows: number;
}): React.ReactNode {
const toolProgressMessages = progressMessagesForMessage.filter((msg): msg is ProgressMessage<ToolProgressData> => (msg.data as { type?: string }).type !== 'hook_progress');
function renderToolUseProgressMessage(
tool: Tool,
tools: Tools,
lookups: ReturnType<typeof buildMessageLookups>,
toolUseID: string,
progressMessagesForMessage: ProgressMessage[],
{
verbose,
inProgressToolCallCount,
isTranscriptMode,
}: {
verbose: boolean
inProgressToolCallCount?: number
isTranscriptMode?: boolean
},
terminalSize: { columns: number; rows: number },
): React.ReactNode {
const toolProgressMessages = progressMessagesForMessage.filter(
(msg): msg is ProgressMessage<ToolProgressData> =>
msg.data.type !== 'hook_progress',
)
try {
const toolMessages = tool.renderToolUseProgressMessage?.(toolProgressMessages, {
tools,
verbose,
terminalSize,
inProgressToolCallCount: inProgressToolCallCount ?? 1,
isTranscriptMode
}) ?? null;
return <>
const toolMessages =
tool.renderToolUseProgressMessage?.(toolProgressMessages, {
tools,
verbose,
terminalSize,
inProgressToolCallCount: inProgressToolCallCount ?? 1,
isTranscriptMode,
}) ?? null
return (
<>
<SentryErrorBoundary>
<HookProgressMessage hookEvent="PreToolUse" lookups={lookups} toolUseID={toolUseID} verbose={verbose} isTranscriptMode={isTranscriptMode} />
<HookProgressMessage
hookEvent="PreToolUse"
lookups={lookups}
toolUseID={toolUseID}
verbose={verbose}
isTranscriptMode={isTranscriptMode}
/>
</SentryErrorBoundary>
{toolMessages}
</>;
</>
)
} catch (error) {
logError(new Error(`Error rendering tool use progress message for ${tool.name}: ${error}`));
return null;
logError(
new Error(
`Error rendering tool use progress message for ${tool.name}: ${error}`,
),
)
return null
}
}
function renderToolUseQueuedMessage(tool: Tool): React.ReactNode {
try {
return tool.renderToolUseQueuedMessage?.();
return tool.renderToolUseQueuedMessage?.()
} catch (error) {
logError(new Error(`Error rendering tool use queued message for ${tool.name}: ${error}`));
return null;
logError(
new Error(
`Error rendering tool use queued message for ${tool.name}: ${error}`,
),
)
return null
}
}