feat: eslint lsp (#1744)

This commit is contained in:
Aiden Cline
2025-08-09 11:04:58 -05:00
committed by GitHub
parent e2fac991dc
commit 1954b59167
3 changed files with 65 additions and 3 deletions

View File

@@ -65,6 +65,66 @@ export namespace LSPServer {
},
}
export const ESLint: Info = {
id: "eslint",
root: NearestRoot([
"eslint.config.js",
"eslint.config.mjs",
"eslint.config.cjs",
"eslint.config.ts",
"eslint.config.mts",
"eslint.config.cts",
".eslintrc.js",
".eslintrc.cjs",
".eslintrc.yaml",
".eslintrc.yml",
".eslintrc.json",
"package.json",
]),
extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts"],
async spawn(app, root) {
const eslint = await Bun.resolve("eslint", app.path.cwd).catch(() => {})
if (!eslint) return
const serverPath = path.join(Global.Path.bin, "vscode-eslint", "server", "out", "eslintServer.js")
if (!(await Bun.file(serverPath).exists())) {
log.info("downloading and building VS Code ESLint server")
const response = await fetch("https://github.com/microsoft/vscode-eslint/archive/refs/heads/main.zip")
if (!response.ok) return
const zipPath = path.join(Global.Path.bin, "vscode-eslint.zip")
await Bun.file(zipPath).write(response)
await $`unzip -o -q ${zipPath}`.cwd(Global.Path.bin).nothrow()
await fs.rm(zipPath, { force: true })
const extractedPath = path.join(Global.Path.bin, "vscode-eslint-main")
const finalPath = path.join(Global.Path.bin, "vscode-eslint")
if (await Bun.file(finalPath).exists()) {
await fs.rm(finalPath, { force: true, recursive: true })
}
await fs.rename(extractedPath, finalPath)
await $`npm install`.cwd(finalPath).quiet()
await $`npm run compile`.cwd(finalPath).quiet()
log.info("installed VS Code ESLint server", { serverPath })
}
const proc = spawn(BunProc.which(), ["--max-old-space-size=8192", serverPath, "--stdio"], {
cwd: root,
env: {
...process.env,
BUN_BE_BUN: "1",
},
})
return {
process: proc,
}
},
}
export const Gopls: Info = {
id: "golang",
root: async (file, app) => {

View File

@@ -111,6 +111,7 @@ export const EditTool = Tool.define("edit", {
continue
}
output += `\n<project_diagnostics>\n${file}\n${issues
// TODO: may want to make more leniant for eslint
.filter((item) => item.severity === 1)
.map(LSP.Diagnostic.pretty)
.join("\n")}\n</project_diagnostics>\n`

View File

@@ -11,9 +11,10 @@ opencode integrates with your Language Server Protocol (LSP) to help the LLM int
opencode comes with several built-in LSP servers for popular languages:
| LSP Server | Extensions | Requirements |
| LSP Server | Extensions | Requirements |
| ---------- | -------------------------------------------- | ----------------------------------- |
| typescript | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `typescript` dependency in project |
| eslint | .ts, .tsx, .js, .jsx, .mjs, .cjs, .mts, .cts | `eslint` dependency in project |
| gopls | .go | `go` command available |
| ruby-lsp | .rb, .rake, .gemspec, .ru | `ruby` and `gem` commands available |
| pyright | .py, .pyi | `pyright` dependency installed |
@@ -41,7 +42,7 @@ You can customize LSP servers through the `lsp` section in your opencode config.
```json title="opencode.json"
{
"$schema": "https://opencode.ai/config.json",
"lsp": { }
"lsp": {}
}
```
@@ -49,7 +50,7 @@ Each LSP server supports the following:
| Property | Type | Description |
| ---------------- | -------- | ------------------------------------------------- |
| `disabled` | boolean | Set this to `true` to disable the LSP server |
| `disabled` | boolean | Set this to `true` to disable the LSP server |
| `command` | string[] | The command to start the LSP server |
| `extensions` | string[] | File extensions this LSP server should handle |
| `env` | object | Environment variables to set when starting server |