Show HN: Graft – Your local environment, everywhere

(graft.run)

5 points | by erdaniels 13 hours ago ago

2 comments

  • LatticeAnimal 13 hours ago

    Cool project! How do language servers work with this system? Suppose I am developing PyTorch+cuda code on a remote machine, do I need to have that same PyTorch version installed locally?

    If you run the language server remotely, how do you sync the file before it has been saved so that the user gets autocomplete?

    • erdaniels 12 hours ago

      Good question. To quickly answer, no you don't need it installed locally but you will benefit from having the source available.

      Just so we have a common reference, look at https://github.com/edaniels/graft/blob/main/pkg/local_client.... The main idea is that we are always matching the local current working directory to the corresponding synchronization directory. Using that idea, we serve an LSP locally that rewrites all json-rpc messages that utilize URIs (https://github.com/edaniels/graft/blob/main/pkg/local_client...) from local to remote, and back. The local LSP and the remote LSP we launch are none the wiser. Because of this proxy, when you go to definition, you are going to load the local source definition; when you go an lsp format tool, it runs remotely and the file sync gets you results locally.

      The lsp functionality is pretty barebones but has been working for me in sublime when I open a project of mine in a graft connected directory. I've tested it on golang and typescript. I believe python should work but I suppose dependencies could be funky depending on how you synchronize dependencies (uv, pip, etc.).

      For go, I used this on my lsp settings and it worked great. What doesn't work great is if you get disconnected :(. Making the LSP very reliable is another story for another task for another day.

          {
              "log_debug": true,
              "clients":
              {
                  "super-gopls":
                  {
                      "env": {
                          "GRAFT_LOG_LEVEL": "debug",
                      },
                      "command":
                      [
                          "graft",
                          "lsp",
                          "gopls"
                      ],
                      "enabled": false,
                      "initializationOptions":
                      {
                          "analyses":
                          {
                              "composites": false,
                          },
                      },
                      "selector": "source.go",
                  },
              },
              "lsp_code_actions_on_save":
              {
                  "source.fixAll": true,
                  "source.organizeImports": true,
              },
              "lsp_format_on_save": true,
          }