Support non-ASCII project paths (Claude session listing + Codex header crash)#207
Open
bbsngg wants to merge 2 commits into
Open
Support non-ASCII project paths (Claude session listing + Codex header crash)#207bbsngg wants to merge 2 commits into
bbsngg wants to merge 2 commits into
Conversation
8fb8f78 to
460704b
Compare
Two independent fixes for projects whose filesystem path contains non-ASCII characters (e.g. a Chinese path). Fix 1 — Claude sessions could not be opened. dr-claw located session jsonl by joining ~/.claude/projects/<encodeProjectPath(path)>, but the Claude CLI names those directories with a different, lossy scheme (every non-alphanumeric char -> '-'). For non-ASCII paths the two never matched, so getSessions() hit ENOENT and /session/<id> rendered blank. Rather than replicate the CLI's undocumented encoding (which would break on any CLI change and need a config/DB migration), discover the directories by the cwd recorded inside their jsonl files. New resolveClaudeProjectDirs() builds a reverse index (real path -> dir names) and is used by every consumer that previously joined the directory by name: getSessions / getSessionMessages / deleteSession / renameSession / deleteTrashedProject / reconcileClaudeSessionIndex (server/projects.js), getClaudeProjectDirs (server/project-token-usage.js), and the session token-usage route (server/index.js, which also drops a buggy inline encoder missing '.'). reconcileClaudeSessionIndex retries with a fresh index when the CLI just created a new directory; the index is invalidated together with the existing projectDirectoryCache. encodeProjectPath, the config file, the database and the frontend are unchanged; no migration. Fix 2 — Codex crashed with "failed to convert header to a str for header name 'x-codex-turn-metadata'". codex-cli embeds the workspace path verbatim into an HTTP header, and header values must be ASCII/ISO-8859-1 (codex-cli 0.139.0 is latest, so no version bump fixes it). codex-cli keeps the -C/--cd value verbatim and does not canonicalize symlinks, so we run Codex inside an ASCII-only symlink under ~/.dr-claw/codex-cwd/<slug>-<hash> that points at the real project dir. New resolveCodexWorkingDirectory() (server/utils/codexWorkingDir.js): ASCII paths pass through unchanged (zero behaviour change); non-ASCII paths get a stable, idempotent ASCII symlink; any failure falls back to the real path. queryCodex hands the SDK the shadow path but keeps the real path for session indexing and stage tags. normalizeComparablePath now resolves symlinks (best-effort realpath) so Codex sessions recorded under the shadow cwd still associate to the real project in getCodexSessions. Tests: server/__tests__/claude-dir-resolve.test.mjs and server/__tests__/codex-nonascii-path.test.mjs cover non-ASCII resolution, ASCII no-regression, multi-dir merge, cache invalidation, reconcile retry, Codex ASCII passthrough, symlink mapping, idempotence, and end-to-end session association. Full suite: 104 passing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
460704b to
ff87595
Compare
…laude-session-dir-resolution
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.
Two independent fixes for projects whose filesystem path contains non-ASCII characters (e.g. a Chinese path like
/Users/you/Documents/项目/demo).Fix 1 — Claude sessions could not be opened
Problem:
/session/<id>rendered blank. dr-claw located Claude session jsonl by joining~/.claude/projects/<encodeProjectPath(path)>, but the Claude CLI names those directories with a different, lossy scheme (every non-alphanumeric char →-). For non-ASCII paths the two never matched →getSessions()hitENOENT→ empty list.Approach: Rather than replicate the CLI's undocumented encoding (would break on any CLI change and need a config/DB migration), discover the directories by the
cwdrecorded inside their jsonl files — a data fact independent of any naming convention.New
resolveClaudeProjectDirs()builds a reverse index (real path → directory names), used by every consumer that previously joined the dir by name:getSessions/getSessionMessages/deleteSession/renameSession/deleteTrashedProject/reconcileClaudeSessionIndex(server/projects.js),getClaudeProjectDirs(server/project-token-usage.js), and the session token-usage route (server/index.js, which also drops a buggy inline encoder missing.).encodeProjectPath, the config file, the DB and the frontend are unchanged; no migration.Fix 2 — Codex crashed:
x-codex-turn-metadataheaderProblem: Starting a Codex turn failed with
UTF-8 encoding error: failed to convert header to a str for header name 'x-codex-turn-metadata'→Reconnecting... 5/5. codex-cli embeds the workspace path verbatim into an HTTP header, and HTTP header values must be ASCII/ISO-8859-1. (codex-cli 0.139.0 is the latest, so no version bump fixes it.)Approach: Verified that codex-cli keeps the
-C/--cdvalue verbatim and does not canonicalize symlinks (its rendered<cwd>/<workspace_roots>keep the symlink path). So we run Codex inside an ASCII-only symlink under~/.dr-claw/codex-cwd/<slug>-<hash>→ real project dir. The header stays ASCII; file ops still resolve to the real directory.resolveCodexWorkingDirectory()(server/utils/codexWorkingDir.js): ASCII paths pass through unchanged (zero behaviour change); non-ASCII paths get a stable, idempotent ASCII symlink; any failure falls back to the real path.queryCodexhands the SDK the shadow path but keeps the real path for session indexing and stage tags.normalizeComparablePathnow resolves symlinks (best-effort realpath) so Codex sessions recorded under the shadow cwd still associate to the real project.Trade-off: for non-ASCII projects, Codex's
environment_contextand tool output show the shadow path instead of the real path. The slug keeps it recognizable; dr-claw's own project association is unaffected.Note on Gemini
The Gemini CLI does not have this class of bug: it sends workspace/cwd context in the request JSON body (UTF-8), not in any HTTP header, so non-ASCII paths are fine. No change needed.
Tests
server/__tests__/claude-dir-resolve.test.mjsandserver/__tests__/codex-nonascii-path.test.mjscover both fixes (non-ASCII resolution, ASCII no-regression, multi-dir merge, cache invalidation, reconcile retry; Codex ASCII passthrough, symlink mapping, idempotence, end-to-end session association). Full suite: 104 passing.🤖 Generated with Claude Code