Repository navigation
fix(core): stop instruction walk at case-variant Windows project roots - #53349
Merged
Merged
Conversation
A location directory keeps the client's spelling (a CWD such as c:\repo from cmd or an IDE-spawned process) while the project root comes from git as C:\repo. FSUtil.contains accepts the pair because path.relative is case-insensitive on Windows, but ancestorDirectories compared with ===, never reached stop, and recursed at the drive root until the stack overflowed. Instruction activation then failed and every prompt in that location was blocked by InitializationBlocked. Compare the stop boundary with sameDirectory in ancestorDirectories and in FSUtil.up/globUp, so the walk ends at the project root instead of continuing to the drive root and reading AGENTS.md files outside it.
3 tasks done
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.
Issue for this PR
Closes #52874
Closes #50296
Closes #50750
Closes #50857
Type of change
What does this PR do?
On Windows, a location's directory keeps whatever spelling the client's CWD had, while the project root comes from
git rev-parse --show-toplevel. Starting opencode from cmd aftercd /d c:\repo, from a process spawned with ac:\cwd (IDE terminals, scripts), or viaopencode c:\repogivesc:\repovsC:\repo. PowerShell and Git Bash normalize the drive, which is why this is intermittent across users.FSUtil.contains(root, start)accepts the pair (path.relativeis case-insensitive on win32), butancestorDirectoriescompared with===, never reachedstop, and recursed at the drive root (dirname("c:\\") === "c:\\") until the stack overflowed. The plugin's activation guard then markedcore/instructionsunavailable, so every prompt in that location failed withInitializationBlocked. Non-git directories aren't affected because both sides come from the samefs.resolve.The fix compares the stop boundary with the existing
sameDirectoryhelper from@opencode/util/path(case-insensitive for Windows drive/UNC paths, unchanged on POSIX):ancestorDirectoriesin the instruction plugin, which fixes the crash.FSUtil.up/globUp. Without this, the instruction source'sfs.upwalk also missesstopand readsAGENTS.mdfiles above the project root, up toc:\. The sameupboundary is used by the formatter config lookup (findUp(target, directory, worktree)).Compared to #50544, which bounds the walk at the filesystem root: that also stops the overflow, but the walk then continues past the project root, so instruction watchers and
AGENTS.mdreads extend to the drive root.This doesn't address the duplicate-Location side of the casing problem (#47839). The server still keys
c:\repoandC:\repoas separate locations.How did you verify your code works?
instruction-discovery.test.ts(locationc:\...\repo, projectC:\...\repo, plus anAGENTS.mdabove the project). It runs only on win32, which the unit CI matrix covers.Instructions.InitializationBlocked: ... core/instructions.ancestorDirectorieschange: fails because theAGENTS.mdabove the project root is included.bun testfor instruction, project, formatter, git, read-tool, config and skill-discovery tests inpackages/core, andbun testinpackages/util. The only failures (Config > excludes home-level claude...,Config > deduplicates global ecosystem...,global > ... canonicalizes it) fail identically onv2without this change on this Windows machine.bun run checkpasses, and prettier reports the changed files as formatted.Screenshots / recordings
Not a UI change.
Checklist