πŸ“ commands/upgrade/ Β· 02_hybrid_browser_cli_workflow.md

Chapter 2: Hybrid Browser-CLI Workflow

πŸ“„ commands/upgrade/02_hybrid_browser_cli_workflow.md

Chapter 2: Hybrid Browser-CLI Workflow

Welcome back! In the previous chapter, Command Registration & Metadata, we added the "Upgrade" item to our application's menu. We defined who can see it and where it lives.

Now, we need to define what happens when the user actually clicks that button. This introduces a tricky problem: How do you accept a credit card payment inside a text-based terminal?

The answer is: You don't.

This chapter introduces the Hybrid Browser-CLI Workflow, a pattern that bridges the gap between the text-based terminal and the rich visual interface of a web browser.


The Motivation: The "Clerk and the Cashier"

Think of the CLI (Command Line Interface) like a store clerk who helps you find items on the shelf. The clerk is very fast and efficient. However, the clerk does not carry a credit card machine.

When you want to buy something (Upgrade):

  1. The Handoff: The clerk (CLI) points you to the cashier counter (The Web Browser).
  2. The Pause: The clerk waits patiently while you walk over there.
  3. The Return: You pay the cashier, get a receipt, and return to the clerk. The clerk checks your receipt (Re-authentication) and hands you the goods.

In our code, we need to manage this exact flow.


Step 1: The Safety Check (The Guard)

Before we send the user to the browser, we need to make sure they actually need to go. Sending a user to pay for something they already own is a bad user experience.

We open upgrade.tsx and start with a check.

// Inside upgrade.tsx logic
if (isClaudeAISubscriber()) {
  // Check if user is already on the Max plan
  if (isMax20x) {
    // Stop the process immediately
    setTimeout(onDone, 0, 'You are already on the highest plan.');
    return null;
  }
}

Explanation:


Step 2: Opening the Portal

If the user does need to upgrade, we need to open the "door" to the web. We use a utility called openBrowser.

const url = 'https://claude.ai/upgrade/max';

// This acts like a remote control for the user's OS
await openBrowser(url);

Explanation:


Step 3: The Wait (Transitioning State)

This is the most critical part of the Hybrid Workflow. The CLI cannot "see" what is happening in the browser. It doesn't know if the user paid successfully or just closed the tab.

To solve this, we don't just exit. We transition the CLI into a Login State.

return (
  <Login
    startingMessage={'Starting new login... Exit with Ctrl-C to cancel.'}
    onDone={(success) => {
      // Logic when user returns
      context.onChangeAPIKey(); 
      onDone(success ? 'Login successful' : 'Login interrupted');
    }}
  />
);

Explanation:


Under the Hood: The Sequence

Let's visualize how the control passes between the User, the CLI, and the Web.

sequenceDiagram participant User participant CLI as CLI App participant Web as Web Browser User->>CLI: Runs "upgrade" command CLI->>CLI: Checks current plan (Guard) CLI->>Web: Opens https://claude.ai/upgrade CLI->>User: Displays "Login" prompt Note over User, Web: User enters credit card info on Web User->>CLI: Returns to terminal & completes Login CLI->>CLI: Refreshes Account State CLI->>User: "Upgrade Complete"

Handling Failures

What if the browser refuses to open? Perhaps the user is on a server without a screen (headless mode). We must handle this gracefully.

} catch (error) {
  // If automation fails, give manual instructions
  logError(error as Error);
  setTimeout(
    onDone, 
    0, 
    'Failed to open browser. Please visit https://claude.ai/upgrade/max'
  );
}

Explanation:


Why this Architecture?

You might ask: Why not just wait for a "Payment Success" signal from the server?

  1. Complexity: Setting up a real-time WebSocket or polling mechanism to listen for a payment event is complex.
  2. Security: The CLI runs locally on a user's machine. Minimizing open connections is safer.
  3. Reliability: By forcing a re-login (The <Login /> component), we verify the state in the most robust way possible. It ensures we aren't guessing if the payment worked; we are fetching the fresh account status directly.

Conclusion

In this chapter, we learned how to implement a Hybrid Browser-CLI Workflow. We built a bridge that allows our terminal application to leverage the secure payment processing of a web browser.

We learned to:

  1. Guard against unnecessary actions.
  2. Handoff control to the browser.
  3. Wait and refresh state using a Login component.

But waitβ€”in Step 3, we returned a piece of code that looked like HTML (<Login />) inside a function called call. How does a text-based terminal understand and render visual components?

We will answer that in the next chapter: LocalJSX Command Execution.


Generated by Code IQ