Giving Claude Code a map of your projects
A coding agent rooted at project A has no idea project B exists, so you paste absolute paths forever. One map file fixes that — and unlike a path written into a config file, the map can check itself and admit when it is wrong.
github.com/mihai-valentin/cc-whereis · Claude Code plugin, MIT
the thirty-second problem you have every day
You are in a session rooted at one repository. You ask about something in another — "how does the dashboard do auth", "is that fixed in the API repo yet". The agent has never heard of either. So you paste an absolute path, and then you paste it again tomorrow, because nothing about that exchange persisted.
The paths are stable facts about your machine. The session is the wrong place to keep re-teaching them.
"just put them in your agent config"
This is the first objection, it is a reasonable one, and it is worth answering properly because three of the four reasons are obvious and the fourth is the interesting one.
- It pollutes every project's context with unrelated paths. Project A's context should not carry the filesystem layout of thirty repositories it will never touch. Context hygiene is the whole point of the exercise.
- Projects move. They get renamed, archived, shifted to another disk. A hard-coded path is wrong the moment anything shifts.
- It is an N-way sync problem. One map per project, all drifting independently, all needing the same edit.
- A stale line cannot know it is stale. It just quietly lies.
The first three are fixed by construction: one file, outside every project, read only when a lookup actually happens.
The fourth is not fixed by moving the file. A single map rots exactly like thirty copies do — centralised rot is easier to repair, but it is still rot. So that reason is the one that has to be answered with behaviour rather than with architecture.
the part that earns the tool
A resolved path gets checked before it is used. If the directory is gone, you are told — "known label, missing directory" — rather than having the problem worked around.
Two refusals matter as much as the check:
- It never substitutes a plausible neighbour. Finding a similarly-named sibling directory and quietly using it is the worst available outcome, because the work looks like it succeeded and you have no reason to inspect a path you were never shown.
- An ambiguous name is an error naming both candidates, not a coin flip resolved silently in favour of whichever was parsed first.
Which is the whole design in one line: if it isn't sure, you find out. A config-file line can do none of this. That is the difference between a map and a tool that reads one.
aliases, because names aren't stable either
The same project is "dashboard" in your head on Monday and "explore" in the conversation on Thursday — internal codename, repository name, the name the team actually says. Forcing one canonical label means remembering which one you chose.
[dashboard]
path = ~/code/acme-dashboard
aliases = explore, analytics-ui
Aliases are peers of the name for matching, so all three resolve. The format has no quoting and no escapes, which makes a Windows path like C:\Users\you\proj simply a value rather than a problem.
the design bet: no runtime
There is no binary here, and no Node or Python process. The plugin is markdown plus one config file; resolution is string-matching against something around two kilobytes, and verification is an ls. The agent already has excellent tools for both.
That buys portability — it works anywhere the agent works, native Windows included, with no per-platform builds — but the constraint that actually mattered is this one: it must cost nothing until it is used. A plugin whose pitch is "stop filling your context with things you don't need" has lost its own argument if it sits in every session's context. So the skill loads on demand, and the map is read only when a lookup genuinely happens.
Most of the time you never invoke it. You name a project, and it resolves.