Welcome to the Remote Setup project tutorial! Since this is the first chapter, we are going to start at the very beginning: The Front Door.
Imagine you are building a secret clubhouse. You want people to enter, but not just anyone and not at any time.
In our software, a Command is like that clubhouse. We want to create a command called web-setup. However, we only want this command to work if:
This chapter teaches you how to register a command and set up these "gates" so features are only accessible when appropriate.
We will break this down into three simple parts:
name) and what it does (description).isEnabled and isHidden to check rules before running.
Let's build our web-setup command configuration. We are working in index.ts.
First, we tell the system the name of our command. This allows the user to run it by typing web-setup.
const web = {
type: 'local-jsx', // Defines the UI style
name: 'web-setup', // The command the user types
description:
'Setup Claude Code on the web (requires GitHub)',
availability: ['claude-ai'], // Where is this available?
// ... more logic coming next
}
We don't want to show this command if the feature isn't ready. We use a Feature Flag (like a light switch). Here, we check the flag named tengu_cobalt_lantern.
import { getFeatureValue_CACHED_MAY_BE_STALE } from '../../services/analytics/growthbook.js'
// Inside the object:
isEnabled: () =>
// Check if the "tengu_cobalt_lantern" flag is ON
getFeatureValue_CACHED_MAY_BE_STALE('tengu_cobalt_lantern', false)
// We will add more checks here next...
getFeatureValue looks up the flag. If it returns false, the command is disabled.
Even if the feature is ON, the user's company might forbid it. We check the allow_remote_sessions policy.
import { isPolicyAllowed } from '../../services/policyLimits/index.js'
// Updating isEnabled to check BOTH flag and policy:
isEnabled: () =>
getFeatureValue_CACHED_MAY_BE_STALE('tengu_cobalt_lantern', false) &&
isPolicyAllowed('allow_remote_sessions'),
&& means BOTH must be true. If the policy forbids remote sessions, isEnabled becomes false.
Finally, if the gates open, we need to decide what code to run. We use import() inside a function. This ensures we don't load the heavy logic until the command actually starts.
// Inside the object:
load: () => import('./remote-setup.js'),
./remote-setup.js contains the actual logic (which we will cover in the next chapter).What happens when a user types a command? The system acts like a bouncer at a club.
load() (Step 4).Here is a simple diagram of that conversation:
Let's look at the final assembled code in index.ts. This combines everything we just discussed.
We import the tools we need to check the "Gate".
// File: index.ts
import type { Command } from '../../commands.js'
// Tool to check feature flags
import { getFeatureValue_CACHED_MAY_BE_STALE } from '../../services/analytics/growthbook.js'
// Tool to check company policies
import { isPolicyAllowed } from '../../services/policyLimits/index.js'
This is the object that ties it all together. Notice the isHidden propertyβthis completely hides the command from the help menu if the policy forbids it.
const web = {
type: 'local-jsx',
name: 'web-setup',
// ... description ...
isEnabled: () =>
getFeatureValue_CACHED_MAY_BE_STALE('tengu_cobalt_lantern', false) &&
isPolicyAllowed('allow_remote_sessions'),
get isHidden() {
// Hide entirely if policy says no
return !isPolicyAllowed('allow_remote_sessions')
},
load: () => import('./remote-setup.js'),
} satisfies Command
satisfies Command: This is a TypeScript feature ensuring our object has all the required parts of a "Command".import('./remote-setup.js'): This points to the code that handles the visual interface.
You have successfully defined the Registration & Gating for the web-setup command!
Now that the command is registered and the gates are open, what happens when the user successfully runs it? We need to show them a user interface.
Next Chapter: Interactive Setup UI
Generated by Code IQ