CommandTool.tsx 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950
  1. import { Box, Text } from "ink"
  2. import * as theme from "../../theme.js"
  3. import { Icon } from "../Icon.js"
  4. import type { ToolRendererProps } from "./types.js"
  5. import { truncateText, sanitizeContent, getToolIconName } from "./utils.js"
  6. const MAX_OUTPUT_LINES = 10
  7. export function CommandTool({ toolData }: ToolRendererProps) {
  8. const iconName = getToolIconName(toolData.tool)
  9. const command = toolData.command || ""
  10. const output = toolData.output ? sanitizeContent(toolData.output) : ""
  11. const content = toolData.content ? sanitizeContent(toolData.content) : ""
  12. const displayOutput = output || content
  13. const { text: previewOutput, truncated, hiddenLines } = truncateText(displayOutput, MAX_OUTPUT_LINES)
  14. return (
  15. <Box flexDirection="column" paddingX={1} marginBottom={1}>
  16. <Box>
  17. <Icon name={iconName} color={theme.toolHeader} />
  18. {command && (
  19. <Box marginLeft={1}>
  20. <Text color={theme.successColor}>$ </Text>
  21. <Text color={theme.text} bold>
  22. {command}
  23. </Text>
  24. </Box>
  25. )}
  26. </Box>
  27. {previewOutput && (
  28. <Box flexDirection="column">
  29. <Box flexDirection="column" borderStyle="single" borderColor={theme.borderColor} paddingX={1}>
  30. {previewOutput.split("\n").map((line, i) => (
  31. <Text key={i} color={theme.toolText}>
  32. {line}
  33. </Text>
  34. ))}
  35. </Box>
  36. {truncated && (
  37. <Text color={theme.dimText} dimColor>
  38. ... ({hiddenLines} more lines)
  39. </Text>
  40. )}
  41. </Box>
  42. )}
  43. </Box>
  44. )
  45. }