mirror of
https://github.com/anomalyco/opencode.git
synced 2026-08-14 23:43:27 +00:00
refactor(flags): migrate lsp download flag (#27699)
This commit is contained in:
parent
202cc863b4
commit
7b370406a9
5 changed files with 102 additions and 52 deletions
|
|
@ -24,7 +24,6 @@ export const Flag = {
|
|||
OPENCODE_SHOW_TTFD: truthy("OPENCODE_SHOW_TTFD"),
|
||||
OPENCODE_PERMISSION: process.env["OPENCODE_PERMISSION"],
|
||||
OPENCODE_DISABLE_DEFAULT_PLUGINS: truthy("OPENCODE_DISABLE_DEFAULT_PLUGINS"),
|
||||
OPENCODE_DISABLE_LSP_DOWNLOAD: truthy("OPENCODE_DISABLE_LSP_DOWNLOAD"),
|
||||
OPENCODE_DISABLE_AUTOCOMPACT: truthy("OPENCODE_DISABLE_AUTOCOMPACT"),
|
||||
OPENCODE_DISABLE_MODELS_FETCH: truthy("OPENCODE_DISABLE_MODELS_FETCH"),
|
||||
OPENCODE_DISABLE_MOUSE: truthy("OPENCODE_DISABLE_MOUSE"),
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ export class Service extends ConfigService.Service<Service>()("@opencode/Runtime
|
|||
disableChannelDb: bool("OPENCODE_DISABLE_CHANNEL_DB"),
|
||||
disableEmbeddedWebUi: bool("OPENCODE_DISABLE_EMBEDDED_WEB_UI"),
|
||||
disableExternalSkills: bool("OPENCODE_DISABLE_EXTERNAL_SKILLS"),
|
||||
disableLspDownload: bool("OPENCODE_DISABLE_LSP_DOWNLOAD"),
|
||||
disableClaudeCodePrompt: Config.all({
|
||||
broad: bool("OPENCODE_DISABLE_CLAUDE_CODE"),
|
||||
direct: bool("OPENCODE_DISABLE_CLAUDE_CODE_PROMPT"),
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@ import { text } from "node:stream/consumers"
|
|||
import fs from "fs/promises"
|
||||
import { Filesystem } from "@/util/filesystem"
|
||||
import type { InstanceContext } from "../project/instance"
|
||||
import { Flag } from "@opencode-ai/core/flag/flag"
|
||||
import { Archive } from "@/util/archive"
|
||||
import { Process } from "@/util/process"
|
||||
import { which } from "../util/which"
|
||||
|
|
@ -126,11 +125,11 @@ export const Vue: Info = {
|
|||
id: "vue",
|
||||
extensions: [".vue"],
|
||||
root: NearestRoot(["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"]),
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let binary = which("vue-language-server")
|
||||
const args: string[] = []
|
||||
if (!binary) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
const resolved = await Npm.which("@vue/language-server")
|
||||
if (!resolved) return
|
||||
binary = resolved
|
||||
|
|
@ -155,13 +154,13 @@ export const ESLint: Info = {
|
|||
id: "eslint",
|
||||
root: NearestRoot(["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"]),
|
||||
extensions: [".ts", ".tsx", ".js", ".jsx", ".mjs", ".cjs", ".mts", ".cts", ".vue"],
|
||||
async spawn(root, ctx) {
|
||||
async spawn(root, ctx, flags) {
|
||||
const eslint = Module.resolve("eslint", ctx.directory)
|
||||
if (!eslint) return
|
||||
log.info("spawning eslint server")
|
||||
const serverPath = path.join(Global.Path.bin, "vscode-eslint", "server", "out", "eslintServer.js")
|
||||
if (!(await Filesystem.exists(serverPath))) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
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
|
||||
|
|
@ -351,11 +350,11 @@ export const Gopls: Info = {
|
|||
return NearestRoot(["go.mod", "go.sum"])(file, ctx)
|
||||
},
|
||||
extensions: [".go"],
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let bin = which("gopls")
|
||||
if (!bin) {
|
||||
if (!which("go")) return
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
|
||||
log.info("installing gopls")
|
||||
const proc = Process.spawn(["go", "install", "golang.org/x/tools/gopls@latest"], {
|
||||
|
|
@ -386,7 +385,7 @@ export const Rubocop: Info = {
|
|||
id: "ruby-lsp",
|
||||
root: NearestRoot(["Gemfile"]),
|
||||
extensions: [".rb", ".rake", ".gemspec", ".ru"],
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let bin = which("rubocop")
|
||||
if (!bin) {
|
||||
const ruby = which("ruby")
|
||||
|
|
@ -395,7 +394,7 @@ export const Rubocop: Info = {
|
|||
log.info("Ruby not found, please install Ruby first")
|
||||
return
|
||||
}
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
log.info("installing rubocop")
|
||||
const proc = Process.spawn(["gem", "install", "rubocop", "--bindir", Global.Path.bin], {
|
||||
stdout: "pipe",
|
||||
|
|
@ -486,11 +485,11 @@ export const Pyright: Info = {
|
|||
id: "pyright",
|
||||
extensions: [".py", ".pyi"],
|
||||
root: NearestRoot(["pyproject.toml", "setup.py", "setup.cfg", "requirements.txt", "Pipfile", "pyrightconfig.json"]),
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let binary = which("pyright-langserver")
|
||||
const args = []
|
||||
if (!binary) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
const resolved = await Npm.which("pyright", "pyright-langserver")
|
||||
if (!resolved) return
|
||||
binary = resolved
|
||||
|
|
@ -530,7 +529,7 @@ export const ElixirLS: Info = {
|
|||
id: "elixir-ls",
|
||||
extensions: [".ex", ".exs"],
|
||||
root: NearestRoot(["mix.exs", "mix.lock"]),
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let binary = which("elixir-ls")
|
||||
if (!binary) {
|
||||
const elixirLsPath = path.join(Global.Path.bin, "elixir-ls")
|
||||
|
|
@ -548,7 +547,7 @@ export const ElixirLS: Info = {
|
|||
return
|
||||
}
|
||||
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
log.info("downloading elixir-ls from GitHub releases")
|
||||
|
||||
const response = await fetch("https://github.com/elixir-lsp/elixir-ls/archive/refs/heads/master.zip")
|
||||
|
|
@ -593,7 +592,7 @@ export const Zls: Info = {
|
|||
id: "zls",
|
||||
extensions: [".zig", ".zon"],
|
||||
root: NearestRoot(["build.zig"]),
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let bin = which("zls")
|
||||
|
||||
if (!bin) {
|
||||
|
|
@ -603,7 +602,7 @@ export const Zls: Info = {
|
|||
return
|
||||
}
|
||||
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
log.info("downloading zls from GitHub releases")
|
||||
|
||||
const releaseResponse = await fetch("https://api.github.com/repos/zigtools/zls/releases/latest")
|
||||
|
|
@ -705,8 +704,8 @@ export const CSharp: Info = {
|
|||
id: "csharp",
|
||||
root: NearestRoot([".slnx", ".sln", ".csproj", "global.json"]),
|
||||
extensions: [".cs", ".csx"],
|
||||
async spawn(root) {
|
||||
const bin = await getRoslynLanguageServer()
|
||||
async spawn(root, _ctx, flags) {
|
||||
const bin = await getRoslynLanguageServer(flags.disableLspDownload)
|
||||
if (!bin) return
|
||||
|
||||
return {
|
||||
|
|
@ -721,8 +720,8 @@ export const Razor: Info = {
|
|||
id: "razor",
|
||||
root: NearestRoot([".slnx", ".sln", ".csproj", "global.json"]),
|
||||
extensions: [".razor", ".cshtml"],
|
||||
async spawn(root) {
|
||||
const bin = await getRoslynLanguageServer()
|
||||
async spawn(root, _ctx, flags) {
|
||||
const bin = await getRoslynLanguageServer(flags.disableLspDownload)
|
||||
if (!bin) return
|
||||
|
||||
const razor = await findVscodeRazorExtension()
|
||||
|
|
@ -753,26 +752,26 @@ export const Razor: Info = {
|
|||
|
||||
let roslynLanguageServerInstall: Promise<string | undefined> | undefined
|
||||
|
||||
async function getRoslynLanguageServer() {
|
||||
async function getRoslynLanguageServer(disableLspDownload: boolean) {
|
||||
const existing = which("roslyn-language-server")
|
||||
if (existing) return existing
|
||||
|
||||
const global = await roslynLanguageServerGlobalPath()
|
||||
if (global) return global
|
||||
|
||||
roslynLanguageServerInstall ||= installRoslynLanguageServer().finally(() => {
|
||||
roslynLanguageServerInstall ||= installRoslynLanguageServer(disableLspDownload).finally(() => {
|
||||
roslynLanguageServerInstall = undefined
|
||||
})
|
||||
return roslynLanguageServerInstall
|
||||
}
|
||||
|
||||
async function installRoslynLanguageServer() {
|
||||
async function installRoslynLanguageServer(disableLspDownload: boolean) {
|
||||
if (!which("dotnet")) {
|
||||
log.error(".NET SDK is required to install roslyn-language-server")
|
||||
return
|
||||
}
|
||||
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (disableLspDownload) return
|
||||
log.info("installing roslyn-language-server via dotnet tool")
|
||||
const proc = Process.spawn(["dotnet", "tool", "install", "--global", "roslyn-language-server", "--prerelease"], {
|
||||
stdout: "pipe",
|
||||
|
|
@ -850,7 +849,7 @@ export const FSharp: Info = {
|
|||
id: "fsharp",
|
||||
root: NearestRoot([".slnx", ".sln", ".fsproj", "global.json"]),
|
||||
extensions: [".fs", ".fsi", ".fsx", ".fsscript"],
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let bin = which("fsautocomplete")
|
||||
if (!bin) {
|
||||
if (!which("dotnet")) {
|
||||
|
|
@ -858,7 +857,7 @@ export const FSharp: Info = {
|
|||
return
|
||||
}
|
||||
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
log.info("installing fsautocomplete via dotnet tool")
|
||||
const proc = Process.spawn(["dotnet", "tool", "install", "fsautocomplete", "--tool-path", Global.Path.bin], {
|
||||
stdout: "pipe",
|
||||
|
|
@ -967,7 +966,7 @@ export const Clangd: Info = {
|
|||
id: "clangd",
|
||||
root: NearestRoot(["compile_commands.json", "compile_flags.txt", ".clangd"]),
|
||||
extensions: [".c", ".cpp", ".cc", ".cxx", ".c++", ".h", ".hpp", ".hh", ".hxx", ".h++"],
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
const args = ["--background-index", "--clang-tidy"]
|
||||
const fromPath = which("clangd")
|
||||
if (fromPath) {
|
||||
|
|
@ -1002,7 +1001,7 @@ export const Clangd: Info = {
|
|||
}
|
||||
}
|
||||
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
log.info("downloading clangd from GitHub releases")
|
||||
|
||||
const releaseResponse = await fetch("https://api.github.com/repos/clangd/clangd/releases/latest")
|
||||
|
|
@ -1113,11 +1112,11 @@ export const Svelte: Info = {
|
|||
id: "svelte",
|
||||
extensions: [".svelte"],
|
||||
root: NearestRoot(["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"]),
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let binary = which("svelteserver")
|
||||
const args: string[] = []
|
||||
if (!binary) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
const resolved = await Npm.which("svelte-language-server")
|
||||
if (!resolved) return
|
||||
binary = resolved
|
||||
|
|
@ -1140,7 +1139,7 @@ export const Astro: Info = {
|
|||
id: "astro",
|
||||
extensions: [".astro"],
|
||||
root: NearestRoot(["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"]),
|
||||
async spawn(root, ctx) {
|
||||
async spawn(root, ctx, flags) {
|
||||
const tsserver = Module.resolve("typescript/lib/tsserver.js", ctx.directory)
|
||||
if (!tsserver) {
|
||||
log.info("typescript not found, required for Astro language server")
|
||||
|
|
@ -1151,7 +1150,7 @@ export const Astro: Info = {
|
|||
let binary = which("astro-ls")
|
||||
const args: string[] = []
|
||||
if (!binary) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
const resolved = await Npm.which("@astrojs/language-server")
|
||||
if (!resolved) return
|
||||
binary = resolved
|
||||
|
|
@ -1201,7 +1200,7 @@ export const JDTLS: Info = {
|
|||
if (settingsRoot) return settingsRoot
|
||||
},
|
||||
extensions: [".java"],
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
const java = which("java")
|
||||
if (!java) {
|
||||
log.error("Java 21 or newer is required to run the JDTLS. Please install it first.")
|
||||
|
|
@ -1219,7 +1218,7 @@ export const JDTLS: Info = {
|
|||
const launcherDir = path.join(distPath, "plugins")
|
||||
const installed = await pathExists(launcherDir)
|
||||
if (!installed) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
log.info("Downloading JDTLS LSP server.")
|
||||
await fs.mkdir(distPath, { recursive: true })
|
||||
const releaseURL =
|
||||
|
|
@ -1311,13 +1310,13 @@ export const KotlinLS: Info = {
|
|||
// 4) Maven fallback
|
||||
return NearestRoot(["pom.xml"])(file, ctx)
|
||||
},
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
const distPath = path.join(Global.Path.bin, "kotlin-ls")
|
||||
const launcherScript =
|
||||
process.platform === "win32" ? path.join(distPath, "kotlin-lsp.cmd") : path.join(distPath, "kotlin-lsp.sh")
|
||||
const installed = await Filesystem.exists(launcherScript)
|
||||
if (!installed) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
log.info("Downloading Kotlin Language Server from GitHub.")
|
||||
|
||||
const releaseResponse = await fetch("https://api.github.com/repos/Kotlin/kotlin-lsp/releases/latest")
|
||||
|
|
@ -1398,11 +1397,11 @@ export const YamlLS: Info = {
|
|||
id: "yaml-ls",
|
||||
extensions: [".yaml", ".yml"],
|
||||
root: NearestRoot(["package-lock.json", "bun.lockb", "bun.lock", "pnpm-lock.yaml", "yarn.lock"]),
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let binary = which("yaml-language-server")
|
||||
const args: string[] = []
|
||||
if (!binary) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
const resolved = await Npm.which("yaml-language-server")
|
||||
if (!resolved) return
|
||||
binary = resolved
|
||||
|
|
@ -1432,11 +1431,11 @@ export const LuaLS: Info = {
|
|||
"selene.yml",
|
||||
]),
|
||||
extensions: [".lua"],
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let bin = which("lua-language-server")
|
||||
|
||||
if (!bin) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
log.info("downloading lua-language-server from GitHub releases")
|
||||
|
||||
const releaseResponse = await fetch("https://api.github.com/repos/LuaLS/lua-language-server/releases/latest")
|
||||
|
|
@ -1565,11 +1564,11 @@ export const PHPIntelephense: Info = {
|
|||
id: "php intelephense",
|
||||
extensions: [".php"],
|
||||
root: NearestRoot(["composer.json", "composer.lock", ".php-version"]),
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let binary = which("intelephense")
|
||||
const args: string[] = []
|
||||
if (!binary) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
const resolved = await Npm.which("intelephense")
|
||||
if (!resolved) return
|
||||
binary = resolved
|
||||
|
|
@ -1649,11 +1648,11 @@ export const BashLS: Info = {
|
|||
id: "bash",
|
||||
extensions: [".sh", ".bash", ".zsh", ".ksh"],
|
||||
root: async (_file, ctx) => ctx.directory,
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let binary = which("bash-language-server")
|
||||
const args: string[] = []
|
||||
if (!binary) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
const resolved = await Npm.which("bash-language-server")
|
||||
if (!resolved) return
|
||||
binary = resolved
|
||||
|
|
@ -1675,11 +1674,11 @@ export const TerraformLS: Info = {
|
|||
id: "terraform",
|
||||
extensions: [".tf", ".tfvars"],
|
||||
root: NearestRoot([".terraform.lock.hcl", "terraform.tfstate", "*.tf"]),
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let bin = which("terraform-ls")
|
||||
|
||||
if (!bin) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
log.info("downloading terraform-ls from HashiCorp releases")
|
||||
|
||||
const releaseResponse = await fetch("https://api.releases.hashicorp.com/v1/releases/terraform-ls/latest")
|
||||
|
|
@ -1756,11 +1755,11 @@ export const TexLab: Info = {
|
|||
id: "texlab",
|
||||
extensions: [".tex", ".bib"],
|
||||
root: NearestRoot([".latexmkrc", "latexmkrc", ".texlabroot", "texlabroot"]),
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let bin = which("texlab")
|
||||
|
||||
if (!bin) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
log.info("downloading texlab from GitHub releases")
|
||||
|
||||
const response = await fetch("https://api.github.com/repos/latex-lsp/texlab/releases/latest")
|
||||
|
|
@ -1844,11 +1843,11 @@ export const DockerfileLS: Info = {
|
|||
id: "dockerfile",
|
||||
extensions: [".dockerfile", "Dockerfile"],
|
||||
root: async (_file, ctx) => ctx.directory,
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let binary = which("docker-langserver")
|
||||
const args: string[] = []
|
||||
if (!binary) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
const resolved = await Npm.which("dockerfile-language-server-nodejs")
|
||||
if (!resolved) return
|
||||
binary = resolved
|
||||
|
|
@ -1940,11 +1939,11 @@ export const Tinymist: Info = {
|
|||
id: "tinymist",
|
||||
extensions: [".typ", ".typc"],
|
||||
root: NearestRoot(["typst.toml"]),
|
||||
async spawn(root) {
|
||||
async spawn(root, _ctx, flags) {
|
||||
let bin = which("tinymist")
|
||||
|
||||
if (!bin) {
|
||||
if (Flag.OPENCODE_DISABLE_LSP_DOWNLOAD) return
|
||||
if (flags.disableLspDownload) return
|
||||
log.info("downloading tinymist from GitHub releases")
|
||||
|
||||
const response = await fetch("https://api.github.com/repos/Myriad-Dreamin/tinymist/releases/latest")
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ describe("RuntimeFlags", () => {
|
|||
OPENCODE_AUTO_SHARE: "true",
|
||||
OPENCODE_DISABLE_EMBEDDED_WEB_UI: "true",
|
||||
OPENCODE_DISABLE_EXTERNAL_SKILLS: "true",
|
||||
OPENCODE_DISABLE_LSP_DOWNLOAD: "true",
|
||||
OPENCODE_EXPERIMENTAL: "true",
|
||||
OPENCODE_ENABLE_EXA: "true",
|
||||
OPENCODE_ENABLE_PARALLEL: "true",
|
||||
|
|
@ -44,6 +45,7 @@ describe("RuntimeFlags", () => {
|
|||
expect(flags.disableChannelDb).toBe(true)
|
||||
expect(flags.disableEmbeddedWebUi).toBe(true)
|
||||
expect(flags.disableExternalSkills).toBe(true)
|
||||
expect(flags.disableLspDownload).toBe(true)
|
||||
expect(flags.disableClaudeCodePrompt).toBe(false)
|
||||
expect(flags.enableExa).toBe(true)
|
||||
expect(flags.enableParallel).toBe(true)
|
||||
|
|
@ -88,6 +90,7 @@ describe("RuntimeFlags", () => {
|
|||
expect(flags.disableChannelDb).toBe(false)
|
||||
expect(flags.disableEmbeddedWebUi).toBe(false)
|
||||
expect(flags.disableExternalSkills).toBe(false)
|
||||
expect(flags.disableLspDownload).toBe(false)
|
||||
expect(flags.disableClaudeCodePrompt).toBe(false)
|
||||
expect(flags.disableClaudeCodeSkills).toBe(false)
|
||||
expect(flags.enableExa).toBe(false)
|
||||
|
|
@ -124,6 +127,22 @@ describe("RuntimeFlags", () => {
|
|||
}),
|
||||
)
|
||||
|
||||
it.effect("disableLspDownload defaults to false", () =>
|
||||
Effect.gen(function* () {
|
||||
const flags = yield* readFlags.pipe(Effect.provide(fromConfig({})))
|
||||
|
||||
expect(flags.disableLspDownload).toBe(false)
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("disableLspDownload reads OPENCODE_DISABLE_LSP_DOWNLOAD", () =>
|
||||
Effect.gen(function* () {
|
||||
const flags = yield* readFlags.pipe(Effect.provide(fromConfig({ OPENCODE_DISABLE_LSP_DOWNLOAD: "true" })))
|
||||
|
||||
expect(flags.disableLspDownload).toBe(true)
|
||||
}),
|
||||
)
|
||||
|
||||
it.effect("disableClaudeCodePrompt defaults to false", () =>
|
||||
Effect.gen(function* () {
|
||||
const flags = yield* readFlags.pipe(Effect.provide(fromConfig({})))
|
||||
|
|
@ -268,6 +287,7 @@ describe("RuntimeFlags", () => {
|
|||
OPENCODE_PURE: "true",
|
||||
OPENCODE_DISABLE_DEFAULT_PLUGINS: "true",
|
||||
OPENCODE_DISABLE_EXTERNAL_SKILLS: "true",
|
||||
OPENCODE_DISABLE_LSP_DOWNLOAD: "true",
|
||||
OPENCODE_EXPERIMENTAL: "true",
|
||||
OPENCODE_ENABLE_EXA: "true",
|
||||
OPENCODE_EXPERIMENTAL_BASH_DEFAULT_TIMEOUT_MS: "1234",
|
||||
|
|
@ -282,6 +302,7 @@ describe("RuntimeFlags", () => {
|
|||
expect(flags.disableChannelDb).toBe(false)
|
||||
expect(flags.disableEmbeddedWebUi).toBe(false)
|
||||
expect(flags.disableExternalSkills).toBe(false)
|
||||
expect(flags.disableLspDownload).toBe(false)
|
||||
expect(flags.disableClaudeCodePrompt).toBe(false)
|
||||
expect(flags.disableClaudeCodeSkills).toBe(false)
|
||||
expect(flags.enableExa).toBe(false)
|
||||
|
|
|
|||
|
|
@ -16,6 +16,12 @@ const experimentalTyIt = testEffect(
|
|||
CrossSpawnSpawner.defaultLayer,
|
||||
),
|
||||
)
|
||||
const disabledDownloadIt = testEffect(
|
||||
Layer.mergeAll(
|
||||
LSP.layer.pipe(Layer.provide(Config.defaultLayer), Layer.provide(RuntimeFlags.layer({ disableLspDownload: true }))),
|
||||
CrossSpawnSpawner.defaultLayer,
|
||||
),
|
||||
)
|
||||
|
||||
describe("lsp.spawn", () => {
|
||||
it.live("does not spawn builtin LSP for files outside instance", () =>
|
||||
|
|
@ -166,4 +172,28 @@ describe("lsp.spawn", () => {
|
|||
{ config: { lsp: true } },
|
||||
),
|
||||
)
|
||||
|
||||
disabledDownloadIt.live("passes disableLspDownload to builtin LSP spawn", () =>
|
||||
provideTmpdirInstance(
|
||||
(dir) =>
|
||||
LSP.Service.use((lsp) =>
|
||||
Effect.gen(function* () {
|
||||
const pyright = spyOn(LSPServer.Pyright, "spawn").mockResolvedValue(undefined)
|
||||
|
||||
try {
|
||||
yield* lsp.hover({
|
||||
file: path.join(dir, "src", "inside.py"),
|
||||
line: 0,
|
||||
character: 0,
|
||||
})
|
||||
expect(pyright).toHaveBeenCalledTimes(1)
|
||||
expect(pyright.mock.calls[0]?.[2]).toMatchObject({ disableLspDownload: true })
|
||||
} finally {
|
||||
pyright.mockRestore()
|
||||
}
|
||||
}),
|
||||
),
|
||||
{ config: { lsp: true } },
|
||||
),
|
||||
)
|
||||
})
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue