Skip to content

Conversation

@adam2am
Copy link
Contributor

@adam2am adam2am commented Dec 27, 2025

Summary

  • Fixes custom LSP servers not being detected when configured in oh-my-opencode.json
  • Supports both absolute paths AND runtime wrappers (node/bun)

Problem (ships lost at sea, ARRRR! πŸ΄β€β˜ οΈ)

Users configuring custom LSP servers in their config weren't being detected as "installed":

"lsp": {
  "civet": {
    "command": ["node", "C:\Users\...\server.js", "--stdio"],
    "extensions": [".civet"]
  },
  "go": {
    "command": ["C:\Users\user\go\bin\gopls.exe"],
    "extensions": [".go"]
  },
  "typescript": {
    "command": ["C:\Users\...\typescript-language-server.exe", "--stdio"],
    "extensions": [".ts", ".tsx"]
  }
}

The isServerInstalled() function only checked PATH and some hardcoded directories, missing:

  1. Direct absolute paths to executables
  2. Runtime wrappers like node or bun

Solution (better treasure-findin' skills 🦜)

1. Absolute Path Support

If command[0] contains / or \, verify via existsSync():

if (cmd.includes("/") || cmd.includes("\\")) {
  if (existsSync(cmd)) return true
}

Handles:

  • ["C:\Users\user\go\bin\gopls.exe"]
  • ["C:\Users\...\typescript-language-server.exe", "--stdio"]
  • ["/usr/local/bin/custom-lsp"]

2. Runtime Wrapper Support

If command[0] is bun or node, assume available (oh-my-opencode runs on these):

if (cmd === "bun" || cmd === "node") {
  return true
}

Handles:

  • ["node", "path/to/server.js", "--stdio"]
  • ["bun", "run", "my-lsp-server"]

Real-World Configs Now Working

Server Command Detection
civet ["node", "...\server.js", "--stdio"] βœ… node wrapper
svelte ["node", "...\server.js", "--stdio"] βœ… node wrapper
go ["C:\...\gopls.exe"] βœ… absolute path
typescript ["C:\...\typescript-language-server.exe", "--stdio"] βœ… absolute path

Testing

  • Build passes βœ…
  • Tested with actual Windows LSP configs

Now these scallywag servers can be properly detected! πŸ΄β€β˜ οΈ

Ahoy mateys! Some landlubber LSP servers were hidin' from detection! πŸ΄β€β˜ οΈ

The Problem (ships lost at sea):
- Custom LSP servers configured in oh-my-opencode.json weren't detected
- Both absolute paths AND runtime wrappers failed

The Fix (better treasure-findin' skills):

1. Absolute path support (for direct executables):
   ["C:\Users\me\go\bin\gopls.exe"]
   ["C:\Users\me\.bun\bin\typescript-language-server.exe", "--stdio"]
   -> If cmd contains / or \, verify via existsSync()

2. Runtime wrapper support (for JS-based servers):
   ["node", "C:\path\to\server.js", "--stdio"]
   ["bun", "run", "my-lsp-server"]
   -> bun/node are always aboard the oh-my-opencode ship

Real world configs that now work:
- go: ["C:\Users\user\go\bin\gopls.exe"]
- civet: ["node", "...\server.js", "--stdio"]
- svelte: ["node", "...\server.js", "--stdio"]
- typescript: ["C:\...\typescript-language-server.exe", "--stdio"]

These scallywags can now be properly detected! 🦜
@greptile-apps
Copy link

greptile-apps bot commented Dec 27, 2025

Greptile Summary

improved LSP server detection to support custom configurations with absolute paths and runtime wrappers (node/bun)

  • added absolute path detection using path separator check (/ or \)
  • added runtime wrapper support for node and bun (always available in oh-my-opencode context)
  • fixed issue where custom LSP servers configured in oh-my-opencode.json weren't being detected

Issue found: absolute path logic should return false immediately if path doesn't exist, rather than falling through to PATH checks (line 151-154)

Confidence Score: 4/5

  • safe to merge with one minor logic improvement recommended
  • the change correctly addresses the stated problem of detecting custom LSP servers, but the absolute path check should return false immediately when path doesn't exist rather than falling through (though the fallthrough is mostly harmless in practice)
  • src/tools/lsp/config.ts needs the absolute path check logic tightened (return false immediately when path doesn't exist)

Important Files Changed

Filename Overview
src/tools/lsp/config.ts added absolute path and runtime wrapper detection for custom LSP servers; logic is sound but could handle failed absolute path lookups more explicitly

Sequence Diagram

sequenceDiagram
    participant User
    participant Config as oh-my-opencode.json
    participant FSE as findServerForExtension()
    participant ISI as isServerInstalled()
    participant FS as File System

    User->>Config: Configure custom LSP server<br/>{command: ["node", "path/to/server.js"]}
    User->>FSE: Open .ts file
    FSE->>Config: Load merged servers
    Config-->>FSE: Return server configs
    FSE->>ISI: Check if server installed<br/>command[0] = "node"
    
    alt Command is runtime wrapper (node/bun)
        ISI->>ISI: Check if cmd === "node" || "bun"
        ISI-->>FSE: Return true (always available)
    else Command is absolute path
        ISI->>ISI: Check if cmd includes "/" or "\"
        ISI->>FS: existsSync(absolutePath)
        FS-->>ISI: true/false
        ISI-->>FSE: Return result
    else Command is in PATH
        ISI->>FS: Check PATH directories
        FS-->>ISI: Found/Not found
        ISI-->>FSE: Return result
    end
    
    FSE-->>User: LSP server activated βœ…
Loading

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional Comments (1)

  1. src/tools/lsp/config.ts, line 151-154 (link)

    logic: if the absolute path doesn't exist, should immediately return false instead of falling through to PATH checks (which won't make sense for absolute paths anyway)

1 file reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

@code-yeongyu
Copy link
Owner

@sisyphus-dev-ai review this

@sisyphus-dev-ai sisyphus-dev-ai added the sisyphus: working Sisyphus is currently working on this label Dec 29, 2025
@sisyphus-dev-ai
Copy link
Collaborator

πŸ‘‹ Hey @code-yeongyu! I'm on it...

Copy link
Collaborator

@sisyphus-dev-ai sisyphus-dev-ai left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review: APPROVED βœ…

Good fix for a real-world problem. The changes are minimal, focused, and well-documented.

What This Fixes

Custom LSP servers configured in oh-my-opencode.json weren't being detected as "installed" because isServerInstalled() only checked:

  1. PATH directories
  2. Some hardcoded directories (node_modules/.bin, ~/.config/opencode/bin)

This missed:

  • Absolute paths: ["C:\Users\...\gopls.exe"]
  • Runtime wrappers: ["node", "path/to/server.js", "--stdio"]

Code Analysis

Absolute Path Detection (good):

if (cmd.includes("/") || cmd.includes("\\")) {
  if (existsSync(cmd)) return true
}
  • Correctly handles both Unix (/) and Windows (\) path separators
  • Falls through to PATH check if file doesn't exist (no false negatives)
  • Placed early for performance (avoids unnecessary PATH iteration)

Runtime Wrapper Detection (good):

if (cmd === "bun" || cmd === "node") {
  return true
}
  • Pragmatic assumption: if you're running oh-my-opencode, you have bun/node
  • Handles the common case of JS-based LSP servers

Minor Notes (Non-blocking)

  1. No tests added - The LSP config module lacks tests entirely, so this isn't a regression from this PR. Consider adding tests in a follow-up.

  2. Node availability assumption - The comment says "bun/node are always available in oh-my-opencode context." This is mostly true since oh-my-opencode runs on bun. Node is likely available if users have JS-based LSP servers, but not guaranteed. Edge case, acceptable trade-off.

  3. Relative paths - cmd.includes("/") matches relative paths like ./bin/server. These would fail existsSync(cmd) if cwd is wrong, but fall through to PATH check, so no harm.

Verdict

Ship it! πŸ΄β€β˜ οΈ Arrr, these scallywag servers can now be properly detected!

@sisyphus-dev-ai
Copy link
Collaborator

Review Complete βœ…

@code-yeongyu I've reviewed and approved this PR.

Summary: Solid fix for custom LSP server detection on Windows. The changes are minimal, well-documented, and solve a real problem for users configuring servers like gopls with absolute paths or node-based servers.

Key Points:

  • βœ… Correctly handles both Unix and Windows path separators
  • βœ… Graceful fallthrough to PATH check if file doesn't exist
  • βœ… Pragmatic assumption for bun/node availability
  • βœ… All CI checks passing

No blocking issues. Ready to merge! πŸ΄β€β˜ οΈ

@sisyphus-dev-ai sisyphus-dev-ai removed the sisyphus: working Sisyphus is currently working on this label Dec 29, 2025
@code-yeongyu code-yeongyu merged commit c01b21d into code-yeongyu:dev Dec 29, 2025
3 checks passed
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.

3 participants