Skip to content

fix(lsp): match wildcard root markers like *.cabal - #41169

Open
LinHoMo wants to merge 1 commit into
anomalyco:devfrom
LinHoMo:fix-lsp-glob-root
Open

fix(lsp): match wildcard root markers like *.cabal#41169
LinHoMo wants to merge 1 commit into
anomalyco:devfrom
LinHoMo:fix-lsp-glob-root

Conversation

@LinHoMo

@LinHoMo LinHoMo commented Aug 8, 2026

Copy link
Copy Markdown

Issue for this PR

Closes #41168

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Filesystem.up() in packages/opencode/src/util/filesystem.ts walks up the directory tree and yields any target it finds, but it only ever does a literal exists(join(current, target)) probe. Four language servers declare their root with glob markers, so that probe can never match them:

  • HLS -> *.cabal
  • TerraformLS -> *.tf
  • JuliaLS -> *.jl
  • SourceKit -> *.xcodeproj, *.xcworkspace

exists("/repo/pkg-a/*.cabal") is always false, so NearestRoot yields nothing and silently falls back to the workspace root. In a multi-package Haskell repo every package ends up with the repo root as its LSP root, and the same happens for Terraform submodules, Julia packages and Xcode projects.

Fix: when a target contains *, scan the directory with Glob.scan instead of probing an exact path. include: "all" is required rather than "file", because *.xcodeproj and *.xcworkspace are directory bundles, not files.

Literal targets keep the existing exists path, so their behaviour is unchanged. Filesystem.up is only consumed by lsp/server.ts, so the blast radius is limited to root detection.

How did you verify your code works?

Added packages/opencode/test/lsp/glob-root.test.ts. It builds temp workspaces containing *.cabal, *.tf, *.jl and an *.xcodeproj directory, and asserts each server resolves the nested package directory instead of the workspace root, plus one literal-marker case as a control.

  • With the fix: 5 pass.
  • Reverting only the up() change: 4 fail, 1 pass (the literal control still passes). So the test genuinely guards this behaviour rather than passing either way.

Run with bun test test/lsp/glob-root.test.ts from packages/opencode. oxlint reports no new errors on the two touched files.

Caveat: I don't have the Haskell/Swift/Julia toolchains installed, so this verifies root resolution only, not a live language server session.

Screenshots / recordings

Not a UI change.

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions github-actions Bot added needs:compliance This means the issue will auto-close after 2 hours. and removed needs:compliance This means the issue will auto-close after 2 hours. labels Aug 8, 2026
@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Thanks for updating your PR! It now meets our contributing guidelines. 👍

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.

LSP root detection silently falls back to workspace root for wildcard markers

1 participant