Welcome to the final chapter of our Doctor command tutorial!
In Chapter 4: Local JSX Command Handler, we built the "bridge" (doctor.tsx) that connects the CLI system to React. We passed a special function called onDone across that bridge.
Now, we are going to build the destination: The Screen Component.
The Central Use Case: Imagine you are building a video game. You have the console (the CLI) and the controller (the inputs), but you need a Television to actually see the game.
In our project, the Screen Component (<Doctor />) is that television.
It is responsible for:
If we didn't have this component, the command would just hang in empty space, doing nothing.
To build a screen for a CLI, we use React, but with a twist.
In a web browser, you use HTML tags like <div> or <h1>.
In a terminal, those tags don't exist. Instead, we use special components provided by a library called Ink.
<div>, we use <Box>.<span>, we use <Text>.onDone Prop
React components usually run forever until the user closes the browser tab.
But a CLI command needs to exit when it finishes its job. We use a prop called onDone. When our work is finished, we call this function to tell the CLI: "Cut! It's a wrap."
Let's build screens/Doctor.tsx. We will create a simple screen that simulates checking the system health and then exits.
First, we import React and the basic building blocks for Terminal UI.
import React, { useEffect, useState } from 'react';
import { Text, Box } from 'ink'; // Special Terminal components
// We define what props this component accepts
interface DoctorProps {
onDone: () => void; // The "Exit Button"
}
Explanation: We are getting ready to build a UI. We define DoctorProps to ensure we receive the onDone function from the handler we built in Chapter 4.
We need to remember what is happening. Are we loading? Did we find a problem?
export const Doctor: React.FC<DoctorProps> = ({ onDone }) => {
// State to hold the current status message
const [status, setStatus] = useState('Initializing diagnosis...');
// State to determine color (green for good, yellow for working)
const [color, setColor] = useState('yellow');
// ... logic continues below
Explanation: We use useState. status stores the text user sees ("Checking..."), and color makes it look pretty.
We use useEffect to trigger the actual work as soon as the component appears on the screen.
useEffect(() => {
// Simulate a heavy task (like checking a database)
const runChecks = setTimeout(() => {
setStatus('All systems operational! \u2714'); // checkmark symbol
setColor('green');
// Tell the CLI we are finished after a short pause
setTimeout(onDone, 1000);
}, 2000);
return () => clearTimeout(runChecks);
}, [onDone]);
Explanation:
onDone, which shuts down the CLI program.Finally, we draw the UI based on our current state.
return (
<Box flexDirection="column" padding={1}>
<Text color="cyan" bold> CLAUDE DOCTOR </Text>
<Box marginTop={1}>
<Text color={color}> {status} </Text>
</Box>
</Box>
);
};
Explanation:
<Box>: Acts like a container with padding.<Text>: Displays our status string in the requested color.How does React work inside a black-and-white terminal window?
<Doctor />.process.stdout (your terminal screen).setStatus changes, React calculates the difference. It erases the previous line and writes the new line.onDone is called, the CLI stops listening to React and releases the terminal back to the user.
In a real application, you wouldn't just use setTimeout. You would import helper functions to check files, network connections, or API keys.
// Example of real world usage inside useEffect
useEffect(() => {
async function diagnose() {
const isDockerRunning = await checkDocker(); // Import this real function
if (isDockerRunning) {
setStatus("Docker is good.");
} else {
setStatus("Error: Docker is down.");
}
onDone();
}
diagnose();
}, []);
Congratulations! You have successfully built the complete architecture for the doctor command.
Let's review the journey we took through these 5 chapters:
process.env.You now possess the knowledge to add any number of complex, interactive commands to this project. Happy coding!
Generated by Code IQ