fix: preserve $ in file paths for ClaudeCodeAdd and openFile#291
fix: preserve $ in file paths for ClaudeCodeAdd and openFile#291ThomasK33 wants to merge 2 commits into
$ in file paths for ClaudeCodeAdd and openFile#291Conversation
vim.fn.expand() performs shell-style environment-variable substitution, so a real path segment like `$post` (e.g. TanStack Router's `src/routes/$post/`) was read as the undefined env var `post` and replaced with the empty string -- turning `src/routes/$post/index.tsx` into `src/routes//index.tsx`. The subsequent filereadable()/isdirectory() check then failed and the existing file was reported as missing. Replace vim.fn.expand() with claudecode.utils.expand_tilde() at both affected sites. The helper expands only a leading `~`/`~/` and leaves `$`, globs and everything else untouched: - lua/claudecode/init.lua (:ClaudeCodeAdd command) - lua/claudecode/tools/open_file.lua (openFile MCP tool, invoked by Claude) Add regression tests asserting a `$`-containing path survives the readability gate, plus a self-verifying headless repro (scripts/repro_issue_285.lua) and an interactive fixture (fixtures/issue-285/). Fixes #285 Change-Id: I88afde99ea40bae1e394ddd9070898839857db08 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
@codex review |
|
@claude review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 72b40e6df9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
Fix verification (recorded)Before/after run of the self-verifying repro (
Same recording as a video (webm)issue285_fix_proof.webm🤖 Generated with Claude Code |
The previous commit routed ALL :ClaudeCodeAdd path args through expand_tilde, which also dropped vim.fn.expand's current/alternate-file token expansion -- breaking the documented `:ClaudeCodeAdd %` "add current buffer" keymap (README). Expand Vim's %/#/<...> file tokens via vim.fn.expand and route only plain filesystem paths through expand_tilde, so both real `$` paths and the `%` workflow work. This is strictly better than the pre-PR behaviour: `$` is fixed while %/#/<...> behave exactly as before. Add a `%` regression test and a `%` scenario to the repro script. Addresses codex review feedback on #291. Change-Id: Idbdf3e1bfcd1eeb334acebd66314d386b5d914f0 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Signed-off-by: Thomas Kosiewski <tk@coder.com>
|
Codex Review: Didn't find any major issues. Already looking forward to the next diff. Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
|
Closing in favour of #286, which is the original reporter's PR (@geoff-tw). To preserve their contribution, I rebased this work as a follow-up commit stacked on top of theirs in #286 (token-aware |

Summary
Fixes #285. Adding a file whose path contains a
$(e.g. TanStack Router'ssrc/routes/$post/index.tsx) via:ClaudeCodeAddfailed withFile or directory does not exist, and the same path failedopenFile("File not found") when Claude tried to open it.Root cause: both call sites resolved the path with
vim.fn.expand(), which performs shell-style environment-variable substitution.$postwas read as the undefined env varpostand replaced with the empty string, sosrc/routes/$post/index.tsxbecamesrc/routes//index.tsx— which does not exist, failing thefilereadable()/isdirectory()check even though the file is present on disk.Fix: use the existing
claudecode.utils.expand_tilde()helper instead, at both sites. It expands only a leading~/~/and leaves$, globs and everything else untouched.lua/claudecode/init.lua—:ClaudeCodeAddcommandlua/claudecode/tools/open_file.lua—openFileMCP tool (invoked by Claude itself)The other
vim.fn.expand()usages were reviewed and left as-is:terminal.luauses the special%:ptoken, andcwd.lua/lockfile.luaexpand configuration-supplied directories where$VAR/~expansion is the intended behaviour.Behavioural note
For these two entry points, a typed argument such as
$HOME/fooor a glob likesrc/*.luais no longer expanded. This is deliberate: such inputs are rare for these paths (which usually arrive already-resolved from buffers/explorers), and preserving real$-named files is the more common, higher-impact case.~expansion and absolute/relative paths are unchanged (verified —expand_tildeis identical tovim.fn.expandfor those).Test plan
$-containing path passes the readability gate intests/unit/claudecode_add_command_spec.luaandtests/unit/tools/open_file_spec.lua(existing tilde/relative/absolute cases updated to the new helper; the old mock fictionally absolutized relative paths, which realexpand()never did).mise run all— 660 tests pass, luacheck clean (0 warnings/0 errors across 109 files), formatting stable.scripts/repro_issue_285.lua(exits1before the fix,0after) drives the real:ClaudeCodeAddcommand andopenFilehandler against real on-disk files.fixtures/issue-285/(vv issue-285→:Repro285) verified live in a Neovim TUI.🤖 Generated with Claude Code