Skip to content

Fix workspace name resolution for paths containing underscores - #270

Open
mostafaseyedan wants to merge 1 commit into
microsoft:mainfrom
mostafaseyedan:fix/underscore-workspace-resolution
Open

mostafaseyedan wants to merge 1 commit into
microsoft:mainfrom
mostafaseyedan:fix/underscore-workspace-resolution

Conversation

@mostafaseyedan

Copy link
Copy Markdown

Problem

Claude Code encodes underscores as hyphens when building the project directory name under ~/.claude/projects, but encodeComponentForMatch in src/core/parser-claude.ts only normalized whitespace:

return name.replace(/\s/g, '-');

A path component containing an underscore can therefore never match a readdirSync entry. projectNameFromEncoded stops resolving at the first such level and falls through to resolved = path.join(resolved, rest), which takes the entire unresolved remainder as one segment.

Impact

For a home directory of /home/my_name, the encoded directory -home-my-name-AIOps fails to match the real folder my_name, so resolution dies at /home and every Claude workspace is labeled my-name-AIOps instead of AIOps.

Beyond the cosmetic mislabeling, this breaks cross-harness aggregation: the Codex and OpenCode parsers derive the plain basename, so the same project is counted as two separate workspaces and never reconciles. On one real log set (1010 sessions), this split AIOps into 330 + 40 and cendien-website into 201 + 50 + 7, and inflated the distinct workspace count from 30 to 38.

This affects any user whose username or project path contains an underscore.

Fix

Normalize underscores alongside whitespace:

return name.replace(/[\s_]/g, '-');

Ambiguity between sibling directories differing only by _ vs - is already mitigated by the existing longest-encoded-form-first sort.

Testing

Adds a regression test mirroring the existing spaces test, covering a path component with underscores. Verified it fails on main (expected 'my-home-dir-proj' to be 'proj') and passes with the fix.

parser-claude.test.ts passes 22/22. npm run typecheck and npm run lint are clean (0 errors). The 7 failures in github-app-analytics.test.ts are pre-existing on main and unrelated.

Claude Code encodes underscores as hyphens when building the project
directory name under ~/.claude/projects, but encodeComponentForMatch only
normalized whitespace. Any path component containing an underscore could
therefore never match a readdirSync entry, so resolution stopped at the
first such level and the fallback used the entire unresolved tail as the
workspace name.

A user whose home directory is /home/my_name saw every Claude workspace
labeled "my-name-AIOps" instead of "AIOps", which also prevents sessions
from aggregating with the same project recorded by other harnesses.

Normalize underscores alongside whitespace, and add a regression test
covering a path component with underscores.
@mostafaseyedan

mostafaseyedan commented Sep 21, 2026 via email

Copy link
Copy Markdown
Author

@mostafaseyedan

mostafaseyedan commented Sep 21, 2026 via email

Copy link
Copy Markdown
Author

@mostafaseyedan

mostafaseyedan commented Sep 21, 2026 via email

Copy link
Copy Markdown
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant