fix(settings): expand $HOME/${HOME}/~ in env values during settings m…#1422
Open
ChernyshovSergiy wants to merge 1 commit into
Open
fix(settings): expand $HOME/${HOME}/~ in env values during settings m…#1422ChernyshovSergiy wants to merge 1 commit into
ChernyshovSergiy wants to merge 1 commit into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
settings.system.jsonships env values that use a literal$HOME, e.g.:The Claude Code harness shell-expands
$HOMEin hookcommandfields (they run through a shell), but injectsenvvalues verbatim. Soprocess.env.LIFEOS_DIRends up as the literal string
"$HOME/.claude/LIFEOS"— a non-absolute path.Any tool/hook that resolves a path from that env var and writes to it (memory state, observability gates, freshness cache, learning captures) then writes to a path that
resolves against the current working directory. In practice this creates a stray directory literally named
$HOME/inside whatever project the session is running in:— silently littering user project roots, and (worse) redirecting memory/learning writes away from the real
~/.claudetree.Root cause
The merge stage (
MergeSettings.ts) copies env values through untouched, and the harness never expands$HOMEin env. Hardcoding an absolute path intosettings.system.jsonis not an option — the template intentionally uses
$HOMEeverywhere (including allcommandfields) so it stays portable across installs and home directories.Fix
Expand home references in
settings.envvalues at merge time, keeping the template portable:expandHomeReference(value, home)— resolves a leading~/~/,${HOME}, and bare$HOME(token-bounded, so$HOMERis left alone). Non-path values (e.g.http://localhost:...) are untouched.expandEnvHomeReferences(settings, home = os.homedir())— walkssettings.envstring values in place.runCliafter the merge, so a user override (which wins and is typically already absolute) is seen as-is; only remaining$HOME-style system defaults expand.Scoped to
envonly —commandfields keep$HOMEliteral so the harness's own shell expansion continues to make them portable. Pure addition (no lines removed). Idempotent:values that are already absolute pass through unchanged.
Verification
Merging
settings.system.jsonwith an empty user overlay (no override) now yields absoluteLIFEOS_DIR/LIFEOS_CONFIG_DIR/PROJECTS_DIRwith no literal$HOMEremaining. The existing
--checkinvariant (merge(system, user) === settings.json) holds after regeneration.