Welcome to the final chapter of our tutorial series!
In the previous chapter, Admin Request State Machine, we learned how to help employees politely ask for more usage limits.
But what about the Managers? Remember in Core Workflow Engine that if a user has billing access, we send them to the web browser to pay for more credits.
Here is the problem: The user pays in the browser, but the CLI doesn't know about it.
The CLI is holding an old "ID Card" (Authentication Token) that says "This user has $0 credits." Even if the user adds $50 in the browser, the CLI's local ID card is outdated.
This chapter introduces the Session Refresh Strategy: How to force the CLI to tear up the old ID card and get a fresh one immediately.
Imagine you are at a theme park.
If the scanner (the CLI) remembers your status from 5 minutes ago, it will still beep red. You would have to leave the park and re-enter for the scanner to recognize your new pass. That is a terrible user experience.
In our CLI, we want the user to pay in the browser and immediately continue working in the terminal, without having to quit and restart.
To solve this, we use a simple but powerful trick.
When the logic determines the user needs to visit the browser (extra-usage-core), the Interactive Command (extra-usage.tsx) doesn't just exit. Instead, it transitions directly into a Login Screen.
By forcing the user to log in again, we guarantee that:
Let's look at extra-usage.tsx again. This is where the strategy is implemented.
First, we run the brain of our operation.
// extra-usage.tsx
export async function call(onDone, context) {
// 1. Run the core engine
const result = await runExtraUsage()
// ... check result ...
}
Explanation: We wait for the Core Engine to decide what to do. (See Core Workflow Engine).
If the engine returns a simple message (like "Request Sent"), we print it and exit. We don't need to refresh the session for this.
// 2. If it's just a text message, we are done.
if (result.type === 'message') {
onDone(result.value)
return null
}
Explanation: onDone tells the CLI "We are finished here." Returning null means "Don't render any more UI."
If the result was not a message (meaning it was browser-opened), we assume the user might change something in the browser. We immediately render the Login component.
// 3. Render the Login component to refresh the session
return (
<Login
startingMessage={'Starting new login...'}
onDone={(success) => {
context.onChangeAPIKey() // Update global state
onDone(success ? 'Login successful' : 'Login interrupted')
}}
/>
)
}
Explanation:
<Login />: We import the existing Login screen component.startingMessage: We explain to the user why they are logging in again.context.onChangeAPIKey(): This is the crucial step. It updates the CLI's internal memory with the new key.Here is what happens when a Manager runs this command. Notice how the CLI keeps running while the user is in the browser.
By embedding <Login /> directly in the return statement, the CLI doesn't exit. It stays alive, waiting for the user to complete the authentication loop. This makes the experience feel like one continuous flow rather than two separate commands.
context.onChangeAPIKey()You might notice this specific line in the code:
context.onChangeAPIKey();
This is a method provided by the CLI framework's context.
This ensures that any subsequent command the user runs (immediately after this one finishes) uses the fresh permissions.
In this final chapter, we learned:
<Login /> component to force a fresh authentication handshake.onChangeAPIKey() to ensure the running application adopts the new credentials immediately.
Congratulations! You have navigated the entire architecture of the extra-usage command.
You now possess the knowledge to build robust, user-friendly, and secure CLI commands that bridge the gap between terminal inputs and web-based settings!
Generated by Code IQ