mirror of
https://github.com/claude-code-best/claude-code.git
synced 2026-06-19 06:45:50 +00:00
style: 完成所有文件的lint
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
import * as React from 'react'
|
||||
import { MessageResponse } from '../../components/MessageResponse.js'
|
||||
import { supportsHyperlinks } from '@anthropic/ink'
|
||||
import { Link, Text } from '@anthropic/ink'
|
||||
import { renderToolResultMessage as renderDefaultMCPToolResultMessage } from '@claude-code-best/builtin-tools/tools/MCPTool/UI.js'
|
||||
import type { MCPToolResult } from '../../utils/mcpValidation.js'
|
||||
import { truncateToWidth } from '../format.js'
|
||||
import { trackClaudeInChromeTabId } from './common.js'
|
||||
import * as React from 'react';
|
||||
import { MessageResponse } from '../../components/MessageResponse.js';
|
||||
import { supportsHyperlinks } from '@anthropic/ink';
|
||||
import { Link, Text } from '@anthropic/ink';
|
||||
import { renderToolResultMessage as renderDefaultMCPToolResultMessage } from '@claude-code-best/builtin-tools/tools/MCPTool/UI.js';
|
||||
import type { MCPToolResult } from '../../utils/mcpValidation.js';
|
||||
import { truncateToWidth } from '../format.js';
|
||||
import { trackClaudeInChromeTabId } from './common.js';
|
||||
|
||||
export type { Tool } from '@modelcontextprotocol/sdk/types.js'
|
||||
export type { Tool } from '@modelcontextprotocol/sdk/types.js';
|
||||
|
||||
/**
|
||||
* All tool names from BROWSER_TOOLS in @ant/claude-for-chrome-mcp.
|
||||
@@ -30,44 +30,44 @@ export type ChromeToolName =
|
||||
| 'read_console_messages'
|
||||
| 'read_network_requests'
|
||||
| 'shortcuts_list'
|
||||
| 'shortcuts_execute'
|
||||
| 'shortcuts_execute';
|
||||
|
||||
const CHROME_EXTENSION_FOCUS_TAB_URL_BASE = 'https://clau.de/chrome/tab/'
|
||||
const CHROME_EXTENSION_FOCUS_TAB_URL_BASE = 'https://clau.de/chrome/tab/';
|
||||
|
||||
function renderChromeToolUseMessage(
|
||||
input: Record<string, unknown>,
|
||||
toolName: ChromeToolName,
|
||||
verbose: boolean,
|
||||
): React.ReactNode {
|
||||
const tabId = input.tabId
|
||||
const tabId = input.tabId;
|
||||
if (typeof tabId === 'number') {
|
||||
trackClaudeInChromeTabId(tabId)
|
||||
trackClaudeInChromeTabId(tabId);
|
||||
}
|
||||
|
||||
// Build secondary info based on tool type and input
|
||||
const secondaryInfo: string[] = []
|
||||
const secondaryInfo: string[] = [];
|
||||
|
||||
switch (toolName) {
|
||||
case 'navigate':
|
||||
if (typeof input.url === 'string') {
|
||||
try {
|
||||
const url = new URL(input.url)
|
||||
secondaryInfo.push(url.hostname)
|
||||
const url = new URL(input.url);
|
||||
secondaryInfo.push(url.hostname);
|
||||
} catch {
|
||||
secondaryInfo.push(truncateToWidth(input.url, 30))
|
||||
secondaryInfo.push(truncateToWidth(input.url, 30));
|
||||
}
|
||||
}
|
||||
break
|
||||
break;
|
||||
|
||||
case 'find':
|
||||
if (typeof input.query === 'string') {
|
||||
secondaryInfo.push(`pattern: ${truncateToWidth(input.query, 30)}`)
|
||||
secondaryInfo.push(`pattern: ${truncateToWidth(input.query, 30)}`);
|
||||
}
|
||||
break
|
||||
break;
|
||||
|
||||
case 'computer':
|
||||
if (typeof input.action === 'string') {
|
||||
const action = input.action
|
||||
const action = input.action;
|
||||
if (
|
||||
action === 'left_click' ||
|
||||
action === 'right_click' ||
|
||||
@@ -75,71 +75,68 @@ function renderChromeToolUseMessage(
|
||||
action === 'middle_click'
|
||||
) {
|
||||
if (typeof input.ref === 'string') {
|
||||
secondaryInfo.push(`${action} on ${input.ref}`)
|
||||
secondaryInfo.push(`${action} on ${input.ref}`);
|
||||
} else if (Array.isArray(input.coordinate)) {
|
||||
secondaryInfo.push(`${action} at (${input.coordinate.join(', ')})`)
|
||||
secondaryInfo.push(`${action} at (${input.coordinate.join(', ')})`);
|
||||
} else {
|
||||
secondaryInfo.push(action)
|
||||
secondaryInfo.push(action);
|
||||
}
|
||||
} else if (action === 'type' && typeof input.text === 'string') {
|
||||
secondaryInfo.push(`type "${truncateToWidth(input.text, 15)}"`)
|
||||
secondaryInfo.push(`type "${truncateToWidth(input.text, 15)}"`);
|
||||
} else if (action === 'key' && typeof input.text === 'string') {
|
||||
secondaryInfo.push(`key ${input.text}`)
|
||||
} else if (
|
||||
action === 'scroll' &&
|
||||
typeof input.scroll_direction === 'string'
|
||||
) {
|
||||
secondaryInfo.push(`scroll ${input.scroll_direction}`)
|
||||
secondaryInfo.push(`key ${input.text}`);
|
||||
} else if (action === 'scroll' && typeof input.scroll_direction === 'string') {
|
||||
secondaryInfo.push(`scroll ${input.scroll_direction}`);
|
||||
} else if (action === 'wait' && typeof input.duration === 'number') {
|
||||
secondaryInfo.push(`wait ${input.duration}s`)
|
||||
secondaryInfo.push(`wait ${input.duration}s`);
|
||||
} else if (action === 'left_click_drag') {
|
||||
secondaryInfo.push('drag')
|
||||
secondaryInfo.push('drag');
|
||||
} else {
|
||||
secondaryInfo.push(action)
|
||||
secondaryInfo.push(action);
|
||||
}
|
||||
}
|
||||
break
|
||||
break;
|
||||
|
||||
case 'gif_creator':
|
||||
if (typeof input.action === 'string') {
|
||||
secondaryInfo.push(`${input.action}`)
|
||||
secondaryInfo.push(`${input.action}`);
|
||||
}
|
||||
break
|
||||
break;
|
||||
|
||||
case 'resize_window':
|
||||
if (typeof input.width === 'number' && typeof input.height === 'number') {
|
||||
secondaryInfo.push(`${input.width}x${input.height}`)
|
||||
secondaryInfo.push(`${input.width}x${input.height}`);
|
||||
}
|
||||
break
|
||||
break;
|
||||
|
||||
case 'read_console_messages':
|
||||
if (typeof input.pattern === 'string') {
|
||||
secondaryInfo.push(`pattern: ${truncateToWidth(input.pattern, 20)}`)
|
||||
secondaryInfo.push(`pattern: ${truncateToWidth(input.pattern, 20)}`);
|
||||
}
|
||||
if (input.onlyErrors === true) {
|
||||
secondaryInfo.push('errors only')
|
||||
secondaryInfo.push('errors only');
|
||||
}
|
||||
break
|
||||
break;
|
||||
|
||||
case 'read_network_requests':
|
||||
if (typeof input.urlPattern === 'string') {
|
||||
secondaryInfo.push(`pattern: ${truncateToWidth(input.urlPattern, 20)}`)
|
||||
secondaryInfo.push(`pattern: ${truncateToWidth(input.urlPattern, 20)}`);
|
||||
}
|
||||
break
|
||||
break;
|
||||
|
||||
case 'shortcuts_execute':
|
||||
if (typeof input.shortcutId === 'string') {
|
||||
secondaryInfo.push(`shortcut_id: ${input.shortcutId}`)
|
||||
secondaryInfo.push(`shortcut_id: ${input.shortcutId}`);
|
||||
}
|
||||
break
|
||||
break;
|
||||
|
||||
case 'javascript_tool':
|
||||
// In verbose mode, show the full code
|
||||
if (verbose && typeof input.text === 'string') {
|
||||
return input.text
|
||||
return input.text;
|
||||
}
|
||||
// In non-verbose mode, return empty string to preserve View Tab layout
|
||||
return ''
|
||||
return '';
|
||||
|
||||
case 'tabs_create_mcp':
|
||||
case 'tabs_context_mcp':
|
||||
@@ -151,10 +148,10 @@ function renderChromeToolUseMessage(
|
||||
case 'update_plan':
|
||||
// These tools don't have meaningful secondary info to show inline.
|
||||
// Return empty string (not null) to ensure tool header still renders.
|
||||
return ''
|
||||
return '';
|
||||
}
|
||||
|
||||
return secondaryInfo.join(', ') || null
|
||||
return secondaryInfo.join(', ') || null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -166,21 +163,17 @@ function renderChromeToolUseMessage(
|
||||
*/
|
||||
function renderChromeViewTabLink(input: unknown): React.ReactNode {
|
||||
if (!supportsHyperlinks()) {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
if (typeof input !== 'object' || input === null || !('tabId' in input)) {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
const tabId =
|
||||
typeof input.tabId === 'number'
|
||||
? input.tabId
|
||||
: typeof input.tabId === 'string'
|
||||
? parseInt(input.tabId, 10)
|
||||
: NaN
|
||||
typeof input.tabId === 'number' ? input.tabId : typeof input.tabId === 'string' ? parseInt(input.tabId, 10) : NaN;
|
||||
if (isNaN(tabId)) {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
const linkUrl = `${CHROME_EXTENSION_FOCUS_TAB_URL_BASE}${tabId}`
|
||||
const linkUrl = `${CHROME_EXTENSION_FOCUS_TAB_URL_BASE}${tabId}`;
|
||||
return (
|
||||
<Text>
|
||||
{' '}
|
||||
@@ -188,7 +181,7 @@ function renderChromeViewTabLink(input: unknown): React.ReactNode {
|
||||
<Text color="subtle">[View Tab]</Text>
|
||||
</Link>
|
||||
</Text>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -202,62 +195,62 @@ export function renderChromeToolResultMessage(
|
||||
verbose: boolean,
|
||||
): React.ReactNode {
|
||||
if (verbose) {
|
||||
return renderDefaultMCPToolResultMessage(output, [], { verbose })
|
||||
return renderDefaultMCPToolResultMessage(output, [], { verbose });
|
||||
}
|
||||
|
||||
let summary: string | null = null
|
||||
let summary: string | null = null;
|
||||
switch (toolName) {
|
||||
case 'navigate':
|
||||
summary = 'Navigation completed'
|
||||
break
|
||||
summary = 'Navigation completed';
|
||||
break;
|
||||
case 'tabs_create_mcp':
|
||||
summary = 'Tab created'
|
||||
break
|
||||
summary = 'Tab created';
|
||||
break;
|
||||
case 'tabs_context_mcp':
|
||||
summary = 'Tabs read'
|
||||
break
|
||||
summary = 'Tabs read';
|
||||
break;
|
||||
case 'form_input':
|
||||
summary = 'Input completed'
|
||||
break
|
||||
summary = 'Input completed';
|
||||
break;
|
||||
case 'computer':
|
||||
summary = 'Action completed'
|
||||
break
|
||||
summary = 'Action completed';
|
||||
break;
|
||||
case 'resize_window':
|
||||
summary = 'Window resized'
|
||||
break
|
||||
summary = 'Window resized';
|
||||
break;
|
||||
case 'find':
|
||||
summary = 'Search completed'
|
||||
break
|
||||
summary = 'Search completed';
|
||||
break;
|
||||
case 'gif_creator':
|
||||
summary = 'GIF action completed'
|
||||
break
|
||||
summary = 'GIF action completed';
|
||||
break;
|
||||
case 'read_console_messages':
|
||||
summary = 'Console messages retrieved'
|
||||
break
|
||||
summary = 'Console messages retrieved';
|
||||
break;
|
||||
case 'read_network_requests':
|
||||
summary = 'Network requests retrieved'
|
||||
break
|
||||
summary = 'Network requests retrieved';
|
||||
break;
|
||||
case 'shortcuts_list':
|
||||
summary = 'Shortcuts retrieved'
|
||||
break
|
||||
summary = 'Shortcuts retrieved';
|
||||
break;
|
||||
case 'shortcuts_execute':
|
||||
summary = 'Shortcut executed'
|
||||
break
|
||||
summary = 'Shortcut executed';
|
||||
break;
|
||||
case 'javascript_tool':
|
||||
summary = 'Script executed'
|
||||
break
|
||||
summary = 'Script executed';
|
||||
break;
|
||||
case 'read_page':
|
||||
summary = 'Page read'
|
||||
break
|
||||
summary = 'Page read';
|
||||
break;
|
||||
case 'upload_image':
|
||||
summary = 'Image uploaded'
|
||||
break
|
||||
summary = 'Image uploaded';
|
||||
break;
|
||||
case 'get_page_text':
|
||||
summary = 'Page text retrieved'
|
||||
break
|
||||
summary = 'Page text retrieved';
|
||||
break;
|
||||
case 'update_plan':
|
||||
summary = 'Plan updated'
|
||||
break
|
||||
summary = 'Plan updated';
|
||||
break;
|
||||
}
|
||||
|
||||
if (summary) {
|
||||
@@ -265,10 +258,10 @@ export function renderChromeToolResultMessage(
|
||||
<MessageResponse height={1}>
|
||||
<Text dimColor>{summary}</Text>
|
||||
</MessageResponse>
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -276,36 +269,26 @@ export function renderChromeToolResultMessage(
|
||||
* rendering for chrome tools in a single spread operation.
|
||||
*/
|
||||
export function getClaudeInChromeMCPToolOverrides(toolName: string): {
|
||||
userFacingName: (input?: Record<string, unknown>) => string
|
||||
renderToolUseMessage: (
|
||||
input: Record<string, unknown>,
|
||||
options: { verbose: boolean },
|
||||
) => React.ReactNode
|
||||
renderToolUseTag: (input: Partial<Record<string, unknown>>) => React.ReactNode
|
||||
userFacingName: (input?: Record<string, unknown>) => string;
|
||||
renderToolUseMessage: (input: Record<string, unknown>, options: { verbose: boolean }) => React.ReactNode;
|
||||
renderToolUseTag: (input: Partial<Record<string, unknown>>) => React.ReactNode;
|
||||
renderToolResultMessage: (
|
||||
output: string | MCPToolResult,
|
||||
progressMessagesForMessage: unknown[],
|
||||
options: { verbose: boolean },
|
||||
) => React.ReactNode
|
||||
) => React.ReactNode;
|
||||
} {
|
||||
return {
|
||||
userFacingName(_input?: Record<string, unknown>) {
|
||||
// Trim the _mcp postfix that show up in some of the tool names
|
||||
const displayName = toolName.replace(/_mcp$/, '')
|
||||
return `Claude in Chrome[${displayName}]`
|
||||
const displayName = toolName.replace(/_mcp$/, '');
|
||||
return `Claude in Chrome[${displayName}]`;
|
||||
},
|
||||
renderToolUseMessage(
|
||||
input: Record<string, unknown>,
|
||||
{ verbose }: { verbose: boolean },
|
||||
): React.ReactNode {
|
||||
return renderChromeToolUseMessage(
|
||||
input,
|
||||
toolName as ChromeToolName,
|
||||
verbose,
|
||||
)
|
||||
renderToolUseMessage(input: Record<string, unknown>, { verbose }: { verbose: boolean }): React.ReactNode {
|
||||
return renderChromeToolUseMessage(input, toolName as ChromeToolName, verbose);
|
||||
},
|
||||
renderToolUseTag(input: Partial<Record<string, unknown>>): React.ReactNode {
|
||||
return renderChromeViewTabLink(input)
|
||||
return renderChromeViewTabLink(input);
|
||||
},
|
||||
renderToolResultMessage(
|
||||
output: string | MCPToolResult,
|
||||
@@ -313,19 +296,13 @@ export function getClaudeInChromeMCPToolOverrides(toolName: string): {
|
||||
{ verbose }: { verbose: boolean },
|
||||
): React.ReactNode {
|
||||
if (!isMCPToolResult(output)) {
|
||||
return null
|
||||
return null;
|
||||
}
|
||||
return renderChromeToolResultMessage(
|
||||
output,
|
||||
toolName as ChromeToolName,
|
||||
verbose,
|
||||
)
|
||||
return renderChromeToolResultMessage(output, toolName as ChromeToolName, verbose);
|
||||
},
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function isMCPToolResult(
|
||||
output: string | MCPToolResult,
|
||||
): output is MCPToolResult {
|
||||
return typeof output === 'object' && output !== null
|
||||
function isMCPToolResult(output: string | MCPToolResult): output is MCPToolResult {
|
||||
return typeof output === 'object' && output !== null;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user