Welcome to the final chapter of our tutorial!
In Environment & State Context, we gave our CLI "awareness" of its surroundings. It knows if the user is a subscriber or if the environment is valid.
However, our application currently suffers from Amnesia.
Imagine the following scenario:
The application forgot your choice! This happens because React state (useState) only lives in memory while the program is running. As soon as the program closes, that memory is wiped.
To fix this, we need Configuration Persistence. We need to write your choices to a physical file on your hard drive, so the application remembers them the next time it wakes up.
Think of Configuration Persistence as a Notebook that the CLI keeps in its pocket.
In our project, this "Notebook" is a JSON file stored on your computer (usually in ~/.claude/config.json).
To see what the user chose in the past, we use a function called getGlobalConfig. This function opens the notebook and reads the current settings.
// utils/config.ts (Usage Example)
import { getGlobalConfig } from '../../utils/config.js';
const config = getGlobalConfig();
console.log(config.claudeInChromeDefaultEnabled);
// Output: true (or false/undefined)
Explanation: This function is synchronous. It reads the file immediately and returns a simple JavaScript object containing all the user's settings.
To change a setting, we use saveGlobalConfig. We don't just overwrite the whole file (which might erase other important settings); instead, we use an Updater Function.
import { saveGlobalConfig } from '../../utils/config.js';
saveGlobalConfig(currentConfig => {
// We return a NEW object with our changes
return {
...currentConfig, // Keep all old settings (copy them)
claudeInChromeDefaultEnabled: true // Change only this one
};
});
Explanation:
saveGlobalConfig gives us the currentConfig (the current page of the notebook)....currentConfig).
Let's apply this to our chrome.tsx file. We need to do two things:
We do this in the call function (our entry point), just like we did for environment checks in Environment & State Context.
// chrome.tsx - The call() function
export const call = async function(onDone) {
// 1. Read the notebook from disk
const config = getGlobalConfig();
// 2. Pass the specific setting to the Menu
return (
<ClaudeInChromeMenu
configEnabled={config.claudeInChromeDefaultEnabled}
// ... other props ...
/>
);
};
What happens: Before the UI even draws the first pixel, we check the hard drive to see if the user previously enabled this feature.
Now we update the handleAction inside our component to save to disk whenever the user changes the value.
// chrome.tsx - Inside the component
const handleAction = (action) => {
if (action === 'toggle-default') {
const newValue = !enabledByDefault;
// 1. Update the UI immediately (Visual feedback)
setEnabledByDefault(newValue);
// 2. Write to the Notebook (Persistence)
saveGlobalConfig(current => ({
...current,
claudeInChromeDefaultEnabled: newValue
}));
}
};
What happens:
setEnabledByDefault updates the React state, so the text on screen changes from "No" to "Yes" instantly.saveGlobalConfig runs in the background to ensure that if you quit right now, "Yes" is remembered.
What actually happens when you call saveGlobalConfig?
config.json file.
You might have noticed this strange syntax: ...current.
// The "Spread" operator
...current
This is crucial for safety. The configuration file holds settings for everything in the CLI (login tokens, themes, font sizes).
If we did this:
// BAD CODE - DO NOT DO THIS
return { claudeInChromeDefaultEnabled: true };
We would be creating a new object with only one property. We would accidentally delete the user's login token and log them out!
By doing { ...current, ...changes }, we are saying: "Take everything that was already there, and only overwrite the one thing I changed."
Congratulations! You have successfully built the Claude in Chrome feature integration.
Let's review the journey you took:
You have gone from a blank file to a fully functional, state-aware, persistent CLI feature. You are now ready to build your own commands!
Generated by Code IQ