How Claude HUD Handles Config Migration for Legacy Upgrades
Claude HUD automatically migrates legacy configuration formats by detecting obsolete layout properties in config.json and transforming them into the current HudConfig schema during the initialization process.
The jarrodwatts/claude-hud repository maintains backward compatibility through a robust migration system that ensures user preferences persist across schema changes. When the plugin initializes, it reads the user's config.json file and seamlessly upgrades outdated structures without manual intervention. This Claude HUD config migration process handles both string-based and object-based legacy layouts while preserving valid modern settings.
Understanding the Configuration Schema Evolution
Early versions of Claude HUD stored display preferences in a single layout property within config.json. This legacy field accepted either string values like "separators" or complex objects written by third-party tools.
Modern releases use a structured HudConfig interface defined in src/config.ts. This schema separates concerns into distinct properties including lineLayout, showSeparators, and pathLevels, providing granular control over the heads-up display appearance.
The migration bridge between these formats occurs within the mergeConfig function, which delegates legacy transformation to migrateConfig before applying defaults and validation.
The Migration Pipeline: From Load to Validation
When loadConfig reads the user's configuration file, it immediately passes the parsed object through mergeConfig. This function orchestrates a four-step Claude HUD config migration workflow:
Step 1: Detecting Legacy Layout Formats
The migrateConfig function (lines 182–206 in src/config.ts) first checks for the presence of a layout property in the loaded configuration. If found, the function determines whether the legacy field contains a string primitive or a complex object, applying different transformation logic for each type.
Step 2: Transforming String-Based Layouts
If the legacy layout property is a string, the migration maps specific values to new boolean and enum fields:
- When
layoutequals"separators", the migration setslineLayout: "compact"andshowSeparators: true - For any other string value, it assigns
lineLayout: "compact"andshowSeparators: false
This logic occupies lines 185–194 in src/config.ts.
Step 3: Handling Object-Based Legacy Layouts
Third-party tools or advanced users may have written layout as an object containing nested configuration. When migrateConfig detects an object type (lines 195–200), it extracts any existing lineLayout, showSeparators, and pathLevels properties from within that object and hoists them to the top-level configuration structure.
Step 4: Cleanup and Default Merging
After extracting values, the migration explicitly deletes the obsolete layout key at line 202 to prevent confusion. The resulting partial configuration then merges with DEFAULT_CONFIG (lines 218–235), filling any missing properties with sensible defaults. Validation helpers like validateLineLayout and validatePathLevels ensure the final HudConfig object conforms to expected types before the plugin uses it.
Implementation Details in src/config.ts
The core migration logic resides in src/config.ts, which also defines the default configuration constants and type guards. The loadConfig function in this file determines the configuration directory via src/claude-config-dir.ts, reads the JSON file, and triggers the migration chain.
Key functions involved in the process:
migrateConfig– Detects and transforms legacylayoutfields into modern propertiesmergeConfig– Orchestrates migration, validation, and default value applicationvalidateLineLayout– Ensures migrated layout values match allowed enum variantsvalidatePathLevels– Confirms numeric path depth settings are within acceptable ranges
Practical Examples
The following pattern demonstrates automatic migration during initialization:
import { loadConfig } from './config.js';
async function initHud() {
const cfg = await loadConfig(); // ← migration happens inside
console.log('Effective config:', cfg);
}
initHud();
For debugging or manual upgrade scenarios, you can invoke the merger directly:
import { mergeConfig } from './config.js';
// Example of an old config file
const oldConfig = {
layout: 'separators', // legacy string
// other future‑proof fields may be present
};
const newConfig = mergeConfig(oldConfig);
console.log(newConfig.lineLayout); // "compact"
console.log(newConfig.showSeparators); // true
Summary
- Claude HUD config migration occurs automatically when
loadConfigparsesconfig.json, requiring no user intervention. - The system handles both string-based legacy layouts (converting
"separators"to boolean flags) and object-based layouts (extracting nested properties). - After migration, the obsolete
layoutfield is deleted to prevent schema conflicts. - Validation functions ensure migrated values conform to the current
HudConfiginterface before merging with defaults. - All logic is centralized in
src/config.ts, with configuration paths resolved viasrc/claude-config-dir.ts.
Frequently Asked Questions
What triggers config migration in Claude HUD?
Migration triggers automatically during the loadConfig execution whenever the system detects a layout property in the user's config.json. This occurs every time the plugin initializes, ensuring legacy files are upgraded transparently before the HUD renders.
What happens if my legacy config uses a custom layout object?
If your existing configuration stores layout as an object rather than a string, the migrateConfig function extracts any valid lineLayout, showSeparators, or pathLevels properties from within that object. These values are promoted to top-level fields, and the original nested structure is discarded after extraction.
Is the original config.json file modified during migration?
The migration process transforms the configuration in memory during the merge phase. While the raw file on disk remains unchanged during reading, Claude HUD typically writes the validated and merged configuration back to config.json, effectively persisting the modernized schema for future launches.
Which validation functions ensure migrated configs are valid?
After migration, mergeConfig invokes validateLineLayout to confirm the layout string matches allowed values like "compact" or "expanded", and validatePathLevels to verify numeric settings are valid. These guards prevent malformed legacy data from crashing the plugin.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →