In the previous chapter, Prompt Strategy, we taught the AI when and how to use our tool. We gave it the logic to create worktrees and the rules to do so safely.
But there is one person we haven't talked to yet: You (the human user).
Welcome to UI Presentation.
Imagine you order a coffee at a cafe.
We need a display board. We need to tell the user:
The Scenario: The AI decides to run EnterWorktree. This might take a few seconds to run git commands and switch directories.
The Goal:
We use a library called Ink. It allows us to build user interfaces for the command line using React. If you have ever built a website with components (like <div> or <span>), this will feel very familiar.
This is a simple message displayed while the call() function from Worktree Session Logic is running. It should be short and active.
This runs after the tool finishes successfully. It receives the data defined in our Input Validation Schema output (path, branch, etc.) and formats it into a pretty status box.
Let's look at UI.tsx. This file contains two specific functions that our tool system looks for.
When the AI starts the tool, we want immediate feedback.
import * as React from 'react';
// This function renders while the tool is running
export function renderToolUseMessage(): React.ReactNode {
return 'Creating worktreeβ¦';
}
Explanation: We return a simple string. The system automatically adds a spinner icon next to this text, so the user sees "β Creating worktreeβ¦".
When the tool finishes, we want to show the details. We use Box (like a layout container) and Text (for styling words) from the ink library.
import { Box, Text } from '../../ink.js';
import type { Output } from './EnterWorktreeTool.js';
// This function renders when the tool finishes successfully
export function renderToolResultMessage(output: Output) {
return (
<Box flexDirection="column">
{/* Content goes here */}
</Box>
);
}
Explanation: output contains the data returned by our logic (path and branch). Box acts like a <div> in HTML. flexDirection="column" stacks items on top of each other.
Now, let's put the actual data inside that Box. We want the branch name to pop out, and the path to be subtle.
<Box flexDirection="column">
<Text>
Switched to worktree on branch{' '}
<Text bold>{output.worktreeBranch}</Text>
</Text>
<Text dimColor>{output.worktreePath}</Text>
</Box>
Explanation:
<Text bold> makes the branch name bright and heavy.<Text dimColor> makes the file path grey/subtle, so it's readable but doesn't distract from the main success message.How does the system know when to switch from "Loading" to "Success"? Let's watch the flow.
Finally, we need to link these functions back to our main definition file, EnterWorktreeTool.ts, which we created in Tool Definition.
// In EnterWorktreeTool.ts
import {
renderToolUseMessage,
renderToolResultMessage
} from './UI.js'
export const EnterWorktreeTool = buildTool({
name: ENTER_WORKTREE_TOOL_NAME,
// ...
renderToolUseMessage,
renderToolResultMessage,
});
Explanation: By importing and assigning these functions to the tool object, we tell the system: "Use these React components to represent this tool."
In this final chapter, we gave our tool a face. We learned:
Box and Text to create pretty CLI outputs.bold for important info (Branch) and dimColor for technical info (Path).Congratulations! You have built a complete, safe, and user-friendly AI tool.
Your AI agent can now safely create isolated sandboxes to experiment with code, keeping your main branch clean and secure. Happy coding!
Generated by Code IQ