mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-18 22:35: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,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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user