( item: ToolInvocationInput, locale: UiLocale = 'zh', )
| 206 | * pretty-printed args object. |
| 207 | */ |
| 208 | export function formatToolInvocationLine( |
| 209 | item: ToolInvocationInput, |
| 210 | locale: UiLocale = 'zh', |
| 211 | ): string | undefined { |
| 212 | const s = strings(locale); |
| 213 | const args = asRecord(item.args); |
| 214 | if (!args) { |
| 215 | if (typeof item.args === 'string' && item.args.trim()) return redactSecrets(item.args); |
| 216 | return undefined; |
| 217 | } |
| 218 | |
| 219 | const command = extractToolCommand(item.args); |
| 220 | if (command) return redactSecrets(command); |
| 221 | |
| 222 | const path = stringField(args, 'path') ?? stringField(args, 'file'); |
| 223 | const pattern = stringField(args, 'pattern'); |
| 224 | const query = stringField(args, 'query'); |
| 225 | const name = item.toolName; |
| 226 | |
| 227 | if (name === 'WriteStdin') { |
| 228 | const parts: string[] = [s.backgroundTerminal]; |
| 229 | const input = readWriteStdinInputPreview(args); |
| 230 | if (input) |
| 231 | parts.push(input.truncated ? `${input.text}… · ${s.bytes(input.bytes)}` : input.text); |
| 232 | const size = asRecord(args.size); |
| 233 | const cols = size ? numberField(size, 'cols') : undefined; |
| 234 | const rows = size ? numberField(size, 'rows') : undefined; |
| 235 | if (cols !== undefined && rows !== undefined) parts.push(`${cols}x${rows}`); |
| 236 | return parts.join(' · '); |
| 237 | } |
| 238 | |
| 239 | if (name === 'Grep' || (pattern && (name === 'Glob' || path))) { |
| 240 | if (pattern) { |
| 241 | const scope = path ? ` in ${path}` : ''; |
| 242 | const glob = stringField(args, 'glob'); |
| 243 | const cwd = stringField(args, 'cwd'); |
| 244 | const where = scope || (cwd ? ` in ${cwd}` : ''); |
| 245 | const globSuffix = glob ? ` (${glob})` : ''; |
| 246 | return redactSecrets(`${pattern}${where}${globSuffix}`); |
| 247 | } |
| 248 | } |
| 249 | |
| 250 | if (path) { |
| 251 | return redactSecrets(`${path}${formatRangeSuffix(args)}`); |
| 252 | } |
| 253 | |
| 254 | if (pattern) { |
| 255 | const cwd = stringField(args, 'cwd'); |
| 256 | return redactSecrets(cwd ? `${pattern} in ${cwd}` : pattern); |
| 257 | } |
| 258 | |
| 259 | if (query) return redactSecrets(query); |
| 260 | |
| 261 | for (const key of HEADLINE_KEYS) { |
| 262 | if (isSensitiveKey(key)) continue; |
| 263 | const value = stringField(args, key); |
| 264 | if (value) return redactSecrets(value); |
| 265 | } |
no test coverage detected