(entry: MakaPiToolEntry)
| 238 | } |
| 239 | |
| 240 | function compactToolSummary(entry: MakaPiToolEntry): CompactToolSummary | undefined { |
| 241 | const result = entry.result; |
| 242 | if (result?.kind === 'shell_run') { |
| 243 | if (entry.toolName === 'WriteStdin') { |
| 244 | return { text: formatPtyControlOperation(result.operation, entry.input) }; |
| 245 | } |
| 246 | // A settled background run reports its outcome, not its output: the status |
| 247 | // and exit code are the signal, the stream body lives in the expanded card. |
| 248 | if (!isActiveShellRunStatus(result.status) && result.status !== 'completed') { |
| 249 | const parts: string[] = [result.status]; |
| 250 | if (result.exitCode !== undefined) parts.push(`exit ${result.exitCode}`); |
| 251 | return { text: ansi.red(parts.join(' · ')), protect: true }; |
| 252 | } |
| 253 | if (result.output?.mode === 'pty') { |
| 254 | const rows = ptyTuiTerminalRows(result.output).length; |
| 255 | return rows > 0 ? { text: linesText(rows), protect: true } : noOutput(); |
| 256 | } |
| 257 | if (result.output?.mode === 'pipes') { |
| 258 | const lines = pipeOutputLineCount(result.output); |
| 259 | if (lines > 0) return { text: linesText(lines), protect: true }; |
| 260 | } |
| 261 | return noOutput(); |
| 262 | } |
| 263 | |
| 264 | if (result?.kind === 'terminal') return compactTerminalSummary(result); |
| 265 | if (result?.kind === 'file_diff') return compactDiffSummary(result); |
| 266 | if (result?.kind === 'file_write') { |
| 267 | // The path is already the card's input summary; the result adds only size. |
| 268 | return { text: `${result.bytes} bytes`, protect: true }; |
| 269 | } |
| 270 | |
| 271 | if (entry.toolName === 'Grep') { |
| 272 | const count = jsonArrayCount(entry, 'matches'); |
| 273 | if (count !== undefined) |
| 274 | return { text: `${count} match${count === 1 ? '' : 'es'}`, protect: true }; |
| 275 | } |
| 276 | |
| 277 | if (entry.toolName === 'Glob') { |
| 278 | const count = jsonArrayCount(entry, 'files'); |
| 279 | if (count !== undefined) |
| 280 | return { text: `${count} file${count === 1 ? '' : 's'}`, protect: true }; |
| 281 | } |
| 282 | |
| 283 | if (result?.kind === 'archived_tool_result') { |
| 284 | return { text: `archived: ${result.status}`, protect: true }; |
| 285 | } |
| 286 | |
| 287 | const text = plainResultText(entry); |
| 288 | if (!text) return result ? noOutput() : undefined; |
| 289 | // Only a successful filesystem Read that carries real file content gets the |
| 290 | // line summary — the same guard the expanded card uses. A runtime |
| 291 | // resource or errored Read uses the generic fixed-shape summary instead of a |
| 292 | // fabricated file count. |
| 293 | if ( |
| 294 | entry.toolName === 'Read' && |
| 295 | entry.status !== 'error' && |
| 296 | isFilesystemReadPath(entry) && |
| 297 | isReadBodyResult(result) |
no test coverage detected