8
3w
9

The quick guide to installing LSPs on Crush

Recently I installed some LSPs (Language Server Protocols) on Crush. Crush supports LSPs it just doesn't come with any natively.

It's actually not so hard, it's just a bit convoluted to figure out if you don't know how because the repo doesn't have any help about it. Actually that's not so true, a friend found this documentation for me once: https://deepwiki.com/charmbracelet/crush/6.4-lsp-integration (which is not linked anywhere that I can tell, but here you go for reference).

What the LSP does

LSPs precede AI, it's what's in IDEs to tell you as you type if there's a syntax error in your code, or helps you autocomplete functions. As natural language processors, LLMs don't really have knowledge of a programming language, they just wing it (just like me fr). With an LSP to communicate with, the LLM has documentation: it knows that sum() takes in integers and will add them up together. It knows when it starts typing object.s what functions are available to it in context (like autocomplete in your current editor).

LSPs also catch errors before runtime, which makes the code more reliable on the first try.

To be honest in my usage with and without LSPs I didn't really notice a huge difference. Maybe fewer input tokens required. In practice, it won't make the agent output tokens faster, it'll make it have fewer bugs on the first try. However, it's basically free to do and has no downsides, so go for it.

Step 0: Ask deepseek

I will die on this hill lol. If you get stuck at any step or get an error during installation, send the output and your specs to deepseek and chances are it'll figure it out. I had two problems with LSPs and it fixed them for me without taking hours.

Step 1: installing LSPs

You need to install the LSPs on your machine. This varies between the programming language, but we'll take pylsp for python as an example (https://github.com/python-lsp/python-lsp-server)

Follow the install instructions, in this case pip install python-lsp-server[all]. For python, that's about it. For stuff to do with node.js, it was more complicated and OS-dependent.

Step 2: Enable the LSP

You need to create a crush.json file. This will depend on OS; On Windows, type %LOCALAPPDATA% in the search bar to go to AppData > Local, then find the crush folder, and inside create a crush.json file. On (some?) Linux, go into home/.config and create a folder named 'crush' there and then the json file.

There should be a providers.json file in that folder by the way, don't touch it: crush recreates it every time you load up the engine, you'll use crush.json for every custom addition to crush. If there isn't providers.json it's fine, it's probably just somewhere else on your machine.

Here's a basic template for pylsp:

{
    "$schema": "https://charm.land/crush.json",
    "lsp": {
        "python": {
            "command": "python",
           "args": ["-m", "pylsp"],
            "extensions": [
                ".py",
                ".pyo",
                ".pyw",
                ".pyi",
                ".pyc",
                ".pyz",
                ".pyd",
                ".pkl",
                ".ipynb",
                ".pyw",
                ".pxd",
                ".pyx"
            ]
        }[, next lsp here]
} [end document]

JSON absolutely sucks to write so use https://jsonlint.com/ to validate and format your json after you're done making changes.

What this code does is run the command 'python -m pylsp', it's just broken up in different lines due to how crush wants their LSP config to look. With extensions (which should be implemented), I can make it so it doesn't try to run the LSP on the wrong file extensions that there is no point in trying to parse since they're not python. On Linux they use the python3 command now. If you get an error try to specify the full path to python first in "command", it'll probably fix it.

Save this file and then open crush in your shell interface. Wait for a bit and you should hopefully see a green light:

(It takes the python name from the JSON file btw, so you can rename each LSP whatever you want).

If the light is red, it will show an error but the problem is it's unreadable. This is where I would use deepseek to debug. For python it should be pretty straightforward as long as pylsp installed correctly, but other LSPs might be more OS-specific:

Node.js

I had the great idea of installing the node.js HTML/CSS/JS LSPs too, which is a whole mess on Windows. You need the visual studio build tools which is a whole thing, then you can download the packages... it's a mess. I'm ditching Microsoft soon. But anyway, this is where deepseek was helpful. It guided me through the steps and found out the exact packages I needed to install too. I had problems with the JS LSP, it wouldn't start, but with enough diagnostics commands we figured out one of my packages for it was too old and needed to be updated.

What this would look like in crush.json:

        "html": {
            "command": "vscode-html-language-server.cmd",
            "args": [
                "--stdio"
            ],
            "extensions": [
                ".html",
                ".wxml"
            ]
        }

On Windows, you need that .cmd at the end because of course you do lol. And of course you need to install the vscode-html-language-server package. Like with python a common error is not specifying the full path.

These are basically all the LSPs I have and it's slightly different for each LSP, but yeah it's basically these two steps: install package, enable in config. It's much easier with hindsight but there's basically 0 documentation on this online (well, until now) so you kinda have to stumble your way around until you figure it out.

In conclusion: go install your LSPs before you code.

loathsome dongeater - 3w

Why do you need a language server if you are having an agent write the code? I thought the point of using agents was to not have to write the code yourself.

2
CriticalResist8 - 3w

In crush specifically, as the LLM generates code token-by-token, Crush’s software layer intercepts partial outputs and triggers LSP requests, such as requesting completion suggestions when it detects a dot after an object, functions, variables, etc - basically anything the LSP in an IDE would catch already. The LSP server responds with context-aware symbols, methods, or completions based on the actual project code and dependencies.

So the software intercepts the generation and communicates with the LSP, then through some magic merges the LSP results with the LLM's token generation to output a real function/variable 100% of the time (whereas the LLM by itself may have a chance to output a hallucination, which will throw an error when it runs the code, which it will attempt to fix, which might repeat the process, and you waste tokens on it while it does that). This happens in real time and 100s of warnings pile up rapidly in my interface while I use crush lol.

Agentic AI is very, very different from the User prompt -> Assistant reply model and I'm barely just dipping my toes in it, but it's nothing like we're used to in computing because of the neural networks being able to process natural language... for example agents expose some tools to the AI (such as web browsing, viewing a file, editing a file at a certain place) by just... telling it about it. "If you want to edit a file run the [tool:edit-file] command which works like so and so". And when the AI generates the command by generating "Okay, let's edit the file: [tool:edit-file "Script.py" --line 50"], it calls the tool and parameters for it and the agent executes the command. It's basically tricking the AI into thinking it has agency and then giving it that agency. You don't see any of this while it runs, but... it's basically just like talking to someone and it's both scary and incredible at the same time.

2
RedWizard [he/him, comrade/them] - 3w

It allows the agent to get diagnostic information about the code and get symbol information about the code as well. For large projects its faster then the llm greping and searching files manually. It tells it which file and which line of the file to look at.

So as it makes changes it can call the lsp to find warnings and errors. Then hunt those down and fix them without you needing to tell it.

2
RedWizard [he/him, comrade/them] - 3w

I finally got godot lsp working. Because the lsp is tcp based you need to use something like ncat to act as a bridge. On windows that's also a nightmare, but i only use windows for work now.

{
    "$schema": "https://charm.land/crush.json",
    "lsp": {
        "Godot LSP": {
            "command": "ncat",
            "args": [
                "localhost",
                "6008"
            ],
            "disabled": false,
            "extensions": [
                ".gd"
            ]
        }
    }
}

You have to run godot in editor mode, and you have to enable all the language server options. Then you can run crush. The debug adapter/server isn't useful in this context.

2
CriticalResist8 - 2w

Really cool! I was wondering how good agentic ai could be with these kinds of game files, if they could edit the files directly or what. Some years ago I tried chatgpt (back when it was the only one lol) on game maker code but through the web interface, it was very powerful.

Yeah in terms of debug the LLM can't see what's happening in the game, it can only read outputs. So if the game launches, it will say success we added the function (and then the function doesn't work) . Hope you've already gitted your project haha it's a lifesaver.

2
RedWizard [he/him, comrade/them] - 2w

Yeah UI is the worst because it obviously cant see. I think with godot there is middle ground somewhere though. If i can create the UI in the editor and then have the AI connect it to the game logic that might be better. Ive tried that but i think this project has gone through way to many rewrites lol.

So i might try and have it document each system, then modify that documentation to be used in a fresh project. There are some other things to work around too, like the fact that the godot lsp will check any file for errors resulting in hundreds of errors in md files and other files.

So if the agent opens an md file suddenly there are way more errors then there should be even though i have the extension limit in place. The agent usually understands this, and can use the lsp on specific files.

Ideally I would use the debugging adaptor but crush doesn't work with it so it seems. Godot can log stuff to a file though, and ill have to add that to the agent document.

I have more ideas but maybe ill save that for another post.

1
CriticalResist8 - 2w

If you were able to transcribe that UI to text the LLM could understand it... Maybe @yogthos@lemmygrad.ml has an idea?

3
☆ Yσɠƚԋσʂ ☆ - 2w

Don't think there's anything more that you could do there. Seems like working with a log in a file is probably the best bet.

2
RedWizard [he/him, comrade/them] - 2w

I think the ideal situation is using Godot's editor to build the UI myself, then using the agent to connect the game system logic to the UI. The UI is defined through a scene file, which is just a txt file, and fully readable by the agent. Though, I'm exploring the idea of using the agent to build a series of design documents first, with code snipits, and then using that documentation with another agent to actually build the systems.

2