style: 完成所有文件的lint

This commit is contained in:
claude-code-best
2026-05-01 21:39:30 +08:00
parent d136872cc9
commit 6182015005
1333 changed files with 68255 additions and 77882 deletions

View File

@@ -1,41 +1,36 @@
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 { Box, Text, stringWidth, useTheme } from '@anthropic/ink'
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 { Box, Text, stringWidth, useTheme } from '@anthropic/ink';
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
}
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,
@@ -51,29 +46,21 @@ export function AssistantToolUseMessage({
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,
)
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'
);
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()
@@ -81,47 +68,34 @@ export function AssistantToolUseMessage({
// 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
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),
userFacingToolNameBackgroundColor: tool.userFacingNameBackgroundColor?.(data),
isTransparentWrapper: tool.isTransparentWrapper?.() ?? false,
}
}, [tools, param])
};
}, [tools, param]);
if (!parsed) {
// 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
logError(new Error(tools ? `Tool ${param.name} not found` : `Tools array is undefined for tool ${param.name}`));
return null;
}
const {
tool,
input,
userFacingToolName,
userFacingToolNameBackgroundColor,
isTransparentWrapper,
} = parsed
const { tool, input, userFacingToolName, userFacingToolNameBackgroundColor, isTransparentWrapper } = parsed;
const isResolved = lookups.resolvedToolUseIDs.has(param.id)
const isQueued = !inProgressToolUseIDs.has(param.id) && !isResolved
const isWaitingForPermission = pendingWorkerRequest?.toolUseId === param.id
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
if (isQueued || isResolved) return null;
return (
<Box flexDirection="column" width="100%" backgroundColor={bg}>
{renderToolUseProgressMessage(
@@ -134,18 +108,18 @@ export function AssistantToolUseMessage({
terminalSize,
)}
</Box>
)
);
}
if (userFacingToolName === '') {
return null
return null;
}
const renderedToolUseMessage = input.success
? renderToolUseMessage(tool, input.data, { theme, verbose, commands })
: null
: null;
if (renderedToolUseMessage === null) {
return null
return null;
}
return (
@@ -157,11 +131,7 @@ export function AssistantToolUseMessage({
backgroundColor={bg}
>
<Box flexDirection="column">
<Box
flexDirection="row"
flexWrap="nowrap"
minWidth={stringWidth(userFacingToolName) + (shouldShowDot ? 2 : 0)}
>
<Box flexDirection="row" flexWrap="nowrap" minWidth={stringWidth(userFacingToolName) + (shouldShowDot ? 2 : 0)}>
{shouldShowDot &&
(isQueued ? (
<Box minWidth={2}>
@@ -182,9 +152,7 @@ export function AssistantToolUseMessage({
bold
wrap="truncate-end"
backgroundColor={userFacingToolNameBackgroundColor}
color={
userFacingToolNameBackgroundColor ? 'inverseText' : undefined
}
color={userFacingToolNameBackgroundColor ? 'inverseText' : undefined}
>
{userFacingToolName}
</Text>
@@ -195,18 +163,14 @@ export function AssistantToolUseMessage({
</Box>
)}
{/* Render tool-specific tags (timeout, model, resume ID, etc.) */}
{input.success &&
tool.renderToolUseTag &&
tool.renderToolUseTag(input.data)}
{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'}
{isAutoClassifier ? 'Auto classifier checking\u2026' : 'Bash classifier checking\u2026'}
</Text>
</MessageResponse>
) : isWaitingForPermission ? (
@@ -231,29 +195,23 @@ export function AssistantToolUseMessage({
{!isResolved && isQueued && renderToolUseQueuedMessage(tool)}
</Box>
</Box>
)
);
}
function renderToolUseMessage(
tool: Tool,
input: unknown,
{
theme,
verbose,
commands,
}: { theme: ThemeName; verbose: boolean; commands: Command[] },
{ 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 '';
}
}
@@ -268,16 +226,15 @@ function renderToolUseProgressMessage(
inProgressToolCallCount,
isTranscriptMode,
}: {
verbose: boolean
inProgressToolCallCount?: number
isTranscriptMode?: boolean
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 Record<string, unknown>).type !== 'hook_progress',
)
(msg): msg is ProgressMessage<ToolProgressData> => (msg.data as Record<string, unknown>).type !== 'hook_progress',
);
try {
const toolMessages =
tool.renderToolUseProgressMessage?.(toolProgressMessages, {
@@ -286,7 +243,7 @@ function renderToolUseProgressMessage(
terminalSize,
inProgressToolCallCount: inProgressToolCallCount ?? 1,
isTranscriptMode,
}) ?? null
}) ?? null;
return (
<>
<SentryErrorBoundary>
@@ -300,26 +257,18 @@ function renderToolUseProgressMessage(
</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;
}
}