Welcome back!
In the previous chapter, Capability Inspection Utilities, we learned how our application uses "X-Ray Scanners" to find risky settings like Bash access or API keys.
We saw code that looked like this:
const projectSettings = getSettingsForSource('projectSettings');
const localSettings = getSettingsForSource('localSettings');
But what are these two sources? Why do we need two different ways to configure the same project? And which one wins if they disagree?
This chapter introduces the Configuration Source Hierarchy.
Imagine you are moving into a shared house with roommates. There are two types of rules:
In TrustDialog, we use this exact model for configuration:
projectSettings).claude/settings.jsonlocalSettings).claude/settings.local.jsonWhen checking for safety, we don't just pick one file and ignore the other. We check both.
If either the Project Settings OR the Local Settings enable a dangerous feature (like Bash), the Trust Dialog considers the project "Risky."
The Rule of Danger:
You are only safe if neither file contains dangerous settings.
| Feature | Project Settings | Local Settings | Result |
|---|---|---|---|
| Bash Access | โ Disabled | โ Disabled | โ Safe |
| Bash Access | โ Enabled | โ Disabled | โ ๏ธ Risky (Needs Trust) |
| Bash Access | โ Disabled | โ Enabled | โ ๏ธ Risky (Needs Trust) |
Even if the project owner disabled Bash (Project Settings), if you enabled it locally to debug something, the tool must still warn you (or treat it as a trusted action).
As a developer using this system, you rarely check the files manually. You use the helper function getSettingsForSource.
Let's say we want to check if the user has defined any "Hooks" (automatic scripts). We need to check both layers.
import { getSettingsForSource } from './settings';
function checkForHooks() {
// 1. Check House Rules
const publicConfig = getSettingsForSource('projectSettings');
// 2. Check Personal Rules
const privateConfig = getSettingsForSource('localSettings');
// Logic: Do hooks exist in EITHER?
return hasHooks(publicConfig) || hasHooks(privateConfig);
}
Explanation:
getSettingsForSource with the specific string ID of the source we want.null if the file doesn't exist.How does the application actually find these files? The logic is straightforward but robust.
When you ask for 'projectSettings', the system looks for the file on your hard drive.
Here is a simplified look at how settings.ts implements this.
// settings.ts (Simplified)
import fs from 'fs';
import path from 'path';
export function getSettingsForSource(sourceType: string) {
// 1. Determine the filename based on the source type
let filename = '';
if (sourceType === 'projectSettings') {
filename = '.claude/settings.json';
} else if (sourceType === 'localSettings') {
filename = '.claude/settings.local.json';
}
// 2. Build the full path
const fullPath = path.resolve(process.cwd(), filename);
// 3. Try to read and parse it
if (fs.existsSync(fullPath)) {
const content = fs.readFileSync(fullPath, 'utf-8');
return JSON.parse(content);
}
return null; // File doesn't exist
}
Step-by-Step Explanation:
.json and the .local.json based on the argument.cwd (Current Working Directory) to find exactly where the file should be.null so the rest of the app knows there are no settings there.This separation is crucial for the Trust Verification UI we built in Chapter 1.
Imagine if we combined everything into one big file.
settings.json with dangerous settings.If there were only one file, you would have to edit the dangerous file to add your key. This makes it hard to distinguish between "Rules I downloaded" (potentially untrusted) and "Rules I wrote" (trusted).
By keeping them separate:
settings.json (the file you downloaded)."settings.local.json without accidentally uploading them to the internet.In this chapter, we learned:
getSettingsForSource function reads the specific file from the disk and parses it.Now we have a fully functioning Trust System:
But what happens if the user says "No"?
If the user denies trust, we need to shut down the application instantly but safely. We can't just crash the program. We need a Graceful Exit.
Next up: Graceful Exit Management
Generated by Code IQ