({
input,
result,
isError = false,
isRunning = false,
startedAt,
completedAt,
}: ToolGrepProps)
| 83 | } |
| 84 | |
| 85 | export function ToolGrep({ |
| 86 | input, |
| 87 | result, |
| 88 | isError = false, |
| 89 | isRunning = false, |
| 90 | startedAt, |
| 91 | completedAt, |
| 92 | }: ToolGrepProps) { |
| 93 | const groups = result ? parseGrepOutput(result) : []; |
| 94 | const totalMatches = groups.reduce((sum, g) => sum + g.matches.length, 0); |
| 95 | |
| 96 | const flags = [ |
| 97 | input["-i"] && "-i", |
| 98 | input["-n"] !== false && "-n", |
| 99 | input.glob && `--glob ${input.glob}`, |
| 100 | input.type && `--type ${input.type}`, |
| 101 | input.context && `-C ${input.context}`, |
| 102 | ] |
| 103 | .filter(Boolean) |
| 104 | .join(" "); |
| 105 | |
| 106 | return ( |
| 107 | <ToolUseBlock |
| 108 | toolName="grep" |
| 109 | toolInput={input} |
| 110 | toolResult={result} |
| 111 | isError={isError} |
| 112 | isRunning={isRunning} |
| 113 | startedAt={startedAt} |
| 114 | completedAt={completedAt} |
| 115 | > |
| 116 | {/* Search header */} |
| 117 | <div className="flex items-center gap-2 px-3 py-2 bg-surface-850 border-b border-surface-700/50 flex-wrap"> |
| 118 | <code className="font-mono text-xs text-yellow-300">{input.pattern}</code> |
| 119 | {flags && <span className="text-xs text-surface-500 font-mono">{flags}</span>} |
| 120 | {input.path && ( |
| 121 | <span className="text-xs text-surface-500">in {input.path}</span> |
| 122 | )} |
| 123 | {!isRunning && totalMatches > 0 && ( |
| 124 | <span className="ml-auto text-xs text-surface-500"> |
| 125 | {totalMatches} match{totalMatches !== 1 ? "es" : ""} |
| 126 | </span> |
| 127 | )} |
| 128 | </div> |
| 129 | |
| 130 | {/* Results */} |
| 131 | {isRunning ? ( |
| 132 | <div className="px-3 py-4 text-surface-500 text-xs animate-pulse"> |
| 133 | Searching… |
| 134 | </div> |
| 135 | ) : isError ? ( |
| 136 | <div className="px-3 py-3 text-red-400 text-xs font-mono">{result}</div> |
| 137 | ) : groups.length === 0 ? ( |
| 138 | <div className="px-3 py-3 text-surface-500 text-xs">No matches found.</div> |
| 139 | ) : ( |
| 140 | <div className="overflow-auto max-h-[400px]"> |
| 141 | {groups.map((group, gi) => ( |
| 142 | <div key={gi} className="border-b border-surface-700/40 last:border-0"> |
nothing calls this directly
no test coverage detected