In the previous chapter, Command Definition, we created the "menu item" for our tool. We told the system that the resume command exists.
Now, users can finally click that button (or type the command). But what happens next?
This brings us to the Command Execution Flow. This is the brain of our operation. It decides whether to show a list of options or jump straight into a specific conversation.
Think of the call function as a Hotel Receptionist. When a guest (the user) walks in, one of two things happens:
Without this logic, our tool wouldn't know if the user wants to search for something specific or browse everything.
call Function
In our code, this "Receptionist" is a function named call. It receives the arguments the user typed after the command name.
Let's break down how this function handles traffic.
If the user types just > resume, they provided no arguments. They want to see a list of recent conversations.
// --- File: resume.tsx ---
export const call: LocalJSXCommandCall = async (onDone, context, args) => {
const arg = args?.trim();
// No argument provided? Show the interactive picker!
if (!arg) {
// We render a UI component called ResumeCommand
return <ResumeCommand key={Date.now()} onDone={onDone} onResume={onResume} />;
}
What is happening?
!arg (is the argument empty?).<ResumeCommand />. This acts as our "Brochure." It launches the visual interface (which we will build in Interactive Session UI).
If the user types > resume 8f3a2b, they are looking for a specific session ID. We need to check if that ID exists.
// ... inside the call function ...
// Check if the user typed a valid UUID (unique ID)
const maybeSessionId = validateUuid(arg);
if (maybeSessionId) {
// Look through our logs to find a match
const matchingLogs = logs.filter(l => getSessionIdFromLog(l) === maybeSessionId);
// If found, start the specific session immediately
if (matchingLogs.length > 0) {
void onResume(maybeSessionId, matchingLogs[0], 'slash_command_session_id');
return null; // Exit, we are done!
}
}
What is happening?
validateUuid to see if the text looks like an ID.onResume. This sends the user straight to their "room" (the conversation) without showing the UI picker.
Sometimes users don't remember the ID, but they remember the title, e.g., > resume "Project Alpha".
// ... if it wasn't a UUID ...
// Try to find a session with this exact custom title
const titleMatches = await searchSessionsByCustomTitle(arg, { exact: true });
if (titleMatches.length === 1) {
// We found exactly one match! Resume it.
const log = titleMatches[0];
const sessionId = getSessionIdFromLog(log);
void onResume(sessionId, log, 'slash_command_title');
return null;
}
What is happening?
Here is the sequence of events when the call function runs. Notice how the decision acts like a fork in the road.
onResume Helper
You might have noticed a function called onResume being used in the code snippets above. This is a helper defined inside call that handles the actual work of restarting the AI context.
It wraps the complex logic so our main flow stays clean.
// Defined at the top of the call function
const onResume = async (sessionId: UUID, log: LogOption, entrypoint: string) => {
try {
// Access the core application context to resume
await context.resume?.(sessionId, log, entrypoint);
// Tell the CLI we finished successfully
onDone(undefined, { display: 'skip' });
} catch (error) {
onDone(`Failed to resume: ${error.message}`);
}
};
Why do we do this?
try/catch block. If loading the session fails, it doesn't crash the whole CLI; it just prints a nice error message.context.resume. This comes from Cross-Project Context Handling, which allows our command to talk to the core application system.In this chapter, we built the Traffic Controller. We learned:
If the user provided no arguments, we decided to show them the Interactive Picker. But what does that look like? How do we build a UI inside a terminal?
Let's build the visual interface in the next chapter: Interactive Session UI.
Generated by Code IQ