feat(sync): resolve symlinked path prefixes to their real target - #74
Open
marioparaschiv wants to merge 6 commits into
Open
marioparaschiv wants to merge 6 commits into
marioparaschiv wants to merge 6 commits into
Conversation
known_marketplaces.json and installed_plugins.json record absolute install locations, but content translation only covered history.jsonl and projects/, so a pull left them pointing at the pushing device and Claude Code rejected the marketplace. Both go through the path mapper now, decoded as JSON rather than replaced as raw bytes: a Windows path is escaped in the file, so byte replacement would eat an escape and leave the document invalid.
…ResolveFile Fold the parallel JSON path API (NormalizeJSONContent/ResolveJSONContent, IsPortableJSONPath, mapJSONStrings) into NormalizeFile/ResolveFile, which pick JSON-aware vs byte translation internally. Call sites drop the two-way branch and the ordering dependency between the two path predicates. Also scope SplitConflictPath's marker match to the final path segment so a parent directory containing ".conflict." no longer triggers a false match or a wrong original path.
The JSON round-trip re-encoded with default settings, which HTML-escaped &, < and > (mangling marketplace repo URLs) and widened integers via float64 decoding. Decode with UseNumber and encode with SetEscapeHTML(false) so only translated path prefixes change.
ResolveContent spliced local paths into session content with raw byte replacement, producing invalid JSON escapes and mixed separators on Windows (e.g. C:\Users\bob/foo). Route .jsonl (per line) and .json content through JSON-aware translation so inserted paths stay escaped and follow the local separator convention.
Claude Code records a session's cwd under the path the user cd'd through, but `claude --resume` looks it up under the resolved real path. When a mapped prefix (HOME or a path_map entry) is a symlink, sessions recorded through it never matched on resume. Resolve symlinks when building each mapping so the token maps to the real path, and keep the unresolved spelling as an alias so paths recorded through the symlink still normalize to the same token. A prefix absent on a device is left unchanged so mapping never breaks.
Canonicalizing symlinked prefixes is not always wanted. Add a resolve_symlinks config flag (default enabled) and thread it through NewPathMapper so a device can keep the literal symlink path with resolve_symlinks: false.
This branch has not been deployed
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.
Depends on #73 (merge that first).
Resolves symlinked path prefixes (HOME and
path_mapentries) to their real target, so sessions recorded through a symlink resume under the pathclaude --resumelooks them up by.Example:
~/Developersymlinked to~/Documents/Projects. Sessions stored underDevelopernow resolve toDocuments/Projectson pull.Can be toggled off with
resolve_symlinks: falsein the config.