Welcome back! In Chapter 1: Command Definition & Metadata, we learned how to create an "ID Card" (Metadata) for our cost command so the application knows it exists.
However, having a command is only half the battle. Sometimes, we want the command to behave differently depending on who is typing it.
Imagine a smart electronic lock on a secure office door.
In our CLI application, we have a similar situation with the cost command:
This chapter explains how we use User Context to create this "Smart Lock" logic.
To solve this, we rely on two pieces of information available in our environment.
isClaudeAISubscriber)We don't want to rewrite complex logic every time we check a user. Instead, we import a simple "Yes/No" question function.
true (User is a subscriber) or false (User pays per usage).process.env)
The computer running the code has global variables called "Environment Variables." We look for a specific tag called USER_TYPE.
process.env.USER_TYPE === 'ant', we know the user is an internal employee (an "Ant").
Let's look at how we combine these concepts inside cost.ts to change the text the user sees.
First, we check if the user is a subscriber. If they are, we prepare a friendly message instead of a dollar amount.
// defined in cost.ts
import { isClaudeAISubscriber } from '../../utils/auth.js'
export const call: LocalCommandCall = async () => {
// Check: Is this a subscriber?
if (isClaudeAISubscriber()) {
let value = 'You are using your subscription...'
// ... logic continues
}
// ...
}
Explanation:
If isClaudeAISubscriber() returns true, we enter a special branch of logic. We set the output text (value) to a helpful message about their subscription limits.
This is the "Security Guard" part of our analogy. Even if the logic above runs, we might want to show extra data if the user is an employee.
// inside the if (isClaudeAISubscriber()) block
if (process.env.USER_TYPE === 'ant') {
// Append extra debug info for employees
value += `\n\n[ANT-ONLY] Showing cost anyway:\n ${formatTotalCost()}`
}
return { type: 'text', value }
Explanation:
We check process.env.USER_TYPE. If it equals 'ant', we add (+=) the actual calculated cost to the message. This allows developers to verify that the cost calculator is working, even when testing as a subscriber.
If the user is not a subscriber, we skip the complex logic and just do the math.
// If NOT a subscriber
return { type: 'text', value: formatTotalCost() }
Explanation:
This is the standard behavior. We simply call formatTotalCost(), which calculates the dollars and cents. (We will learn how this calculation works in Cost & Quota Management).
How does the application flow when a user types cost? Let's visualize the decision-making process.
cost.
We also use this logic before the command even runs, inside our Metadata file (index.ts). This controls whether the command appears in the help menu at all.
// defined in index.ts
get isHidden() {
// 1. Employees (Ants) see everything
if (process.env.USER_TYPE === 'ant') {
return false // Not hidden
}
// 2. Hide this command if user is a subscriber
return isClaudeAISubscriber()
}
Explanation:
This getter, isHidden, is accessed by the help menu.
isHidden is false (Show the command).isHidden is true. Why? because subscribers don't need to worry about individual costs, so we hide the clutter from them.
We will explore how the CLI uses this isHidden property in depth in the next chapter, Dynamic Visibility Logic.
In this chapter, we learned how to make our CLI "smart" about who is using it.
isClaudeAISubscriber, process.env) to identify the user.Now that we know how to check who the user is, let's see how the Main Application uses these rules to show or hide commands dynamically in the menu.
Next Chapter: Dynamic Visibility Logic
Generated by Code IQ