{"id":16024327,"url":"https://github.com/axelson/ls_proxy","last_synced_at":"2025-03-18T03:32:04.137Z","repository":{"id":47787324,"uuid":"181052285","full_name":"axelson/ls_proxy","owner":"axelson","description":"Proxies and analyzes the Language Server Protocol","archived":false,"fork":false,"pushed_at":"2022-02-09T12:14:11.000Z","size":14796,"stargazers_count":16,"open_issues_count":2,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-11T08:54:47.695Z","etag":null,"topics":["elixir","language-server"],"latest_commit_sha":null,"homepage":"","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/axelson.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-04-12T17:17:18.000Z","updated_at":"2024-11-15T21:38:17.000Z","dependencies_parsed_at":"2022-09-08T08:22:14.865Z","dependency_job_id":null,"html_url":"https://github.com/axelson/ls_proxy","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axelson%2Fls_proxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axelson%2Fls_proxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axelson%2Fls_proxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/axelson%2Fls_proxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/axelson","download_url":"https://codeload.github.com/axelson/ls_proxy/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243901079,"owners_count":20366251,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","language-server"],"created_at":"2024-10-08T19:06:32.241Z","updated_at":"2025-03-18T03:32:03.756Z","avatar_url":"https://github.com/axelson.png","language":"Elixir","funding_links":[],"categories":[],"sub_categories":[],"readme":"# LSP Proxy\n\n![LSP Proxy Logo](LSPProxy_logo.png)\n\nProxy for [Language Server](https://microsoft.github.io/language-server-protocol/)'s.\n\nIt is kind of similar to:\nhttps://github.com/Microsoft/language-server-protocol-inspector\n\nBut it is Live! You can see the messages coming in in real-time.\n\nArchitecture:\n```\n           Browser\n              ^\n              |\n              v\nEditor \u003c-\u003e LSP Proxy \u003c-\u003e LanguageServer\n```\n\nLSP Proxy reads input from the Editor (stdin), collects metrics on it, and then sends it to the LanguageServer, and sends all responses back to the Editor.\n\nIt also exposes a website with metrics of what was sent to aid in debugging and understanding a LanguageServer.\n\nSteps:\n1) Read from stdin\n2) Read from stdin until killed (or receive eof?)\n3) Forward on to the LanguageServer\n4) Return output from the LanguageServer to the Editor \n\nLSP Proxy architecture:\n```\n            LSP Proxy.Collector\n                    ^\n                    |\n                    v\nEditorPort \u003c-\u003e LSP Proxy.Tee \u003c-\u003e LanguageServerPort\n```\n\n`EditorPort` to `LSP Proxy.Tee` is controlled purely by our `stdin` and `stdout`\n`LSP Proxy.Tee` communicates with `LanguageServerPort` via `erlexec`\n\nAnd the `LSP Proxy.Collector` collects the metrics info to be displayed via HTTP or other interfaces\n\nSince EditorPort is the entrypoint into the system it will be the group leader for all of the processes because it has to write to stdout (not implemented yet).\n\n# Running\n\n```\ncd ~/dev/ls_proxy\n# maybe env MIX_ENV=prod LS_HTTP_PROXY_TO='http://localhost:4000/api/messages' mix escript.build; cp app /tmp/ls_proxy_release/language_server.sh\n# maybe env MIX_ENV=prod mix escript.build; cp app /tmp/ls_proxy_release/language_server.sh\n\ncd ~/dev/forks/vscode-elixir-ls/\ngit checkout ls-proxy\nvsce package\ncode --install-extension ./elixir-ls-0.3.1.vsix  --force\ncode\n\n# In a browser navigate to:\n# http://localhost:5000\n```\n\n# Configuration\n\nEnv var `LS_PROXY_TO`: Where to find the LanguageServer to proxy to (defaults to `\"elixir-ls/release/language_server.sh\"`)\n\nTypically used only for development:\n\nEnv var `LS_HTTP_PROXY_TO`: Where to send copies of the HTTP messages to, useful to quickly iterate on the web frontend\nEnv var `LS_PROXY_RUN_LANGUAGE_SERVER`: Controls if we start up `LSP Proxy.ProxyPort` (defaults to `true`)\n\n# TODO\n\n- [x] parse basic messages\n- [x] work transparently but with some logging\n- [x] move to poncho style project and create a phoenix web server\n- [x] Add Phoenix LiveView\n- [x] implement two modes, direct where we receive input from stdin and http where we receive input over http\n- [x] Compile ls_proxy to proxy requests to a standalone instance\n- [x] Get clustering to work for easier debugging\n- [x] Issue: large messages are being broken up, causing parsing issues\n- [x] Display just the method for each message\n- [x] Add a button to show the whole message\n- [x] Get app.css and app.js to be compiled before StaticAssetController so we can compile them into StaticAssetController (or another module)\n- [x] Show request/response timings\n- [x] Don't require erlang distribution to already be started up\n- [x] Don't fail if port 5000 is already taken\n  - Maybe we can no set `server: true` initially but start up the server after the fact, that wasy we can register a handler to see if it failed (or in the Endpoint.init callback we can check what ports we've already tried)\n- [x] Add ability to log to lsp output\n- [x] Print http port running on to lsp output\n- [x] Update to latest Phoenix LiveView\n- [x] Make requests/messages toggleable as screens\n- [x] Render messages on homepage instead of messages pages\n- [x] Organize messages page for usability\n- [x] Allow filtering all tabs\n- [x] Pressing reset doesn't clear requests and messages immediately\n- [ ] Don't use MessagesView, instead use all live views/components\n- [ ] a live reload doesn't set the query (problem with socket assigns/state? it is a controlled input)\n- [ ] The ReqResp naming is terrible\n- [ ] Change LsppWebWeb to LsppWeb (or LpWeb?)\n- [ ] Update Contex\n- [ ] Filter the requests bar chart also (add special handling when no requests match)\n- [ ] Make it possible to hide the graph\n- [ ] Update filtered requests whenever messages changes\n\nLater:\n- [ ] Show cancelled request/responses\n- [ ] Show client capabilities\n- [ ] Make the request/response section scannable and usable\n- [ ] Show server capabilities\n- [ ] Show current diagnostics (warnings/errors)\n  - [ ] And provide a way to drill down into what the lsp messages were and the messages around the same time\n- [ ] `LSP Proxy.ErrorCodesParser` should show server error code when errror is between `serverErrorStart` and `serverErrorEnd` (e.g. `\"ServerError -32001\"`)\n- [ ] Limit number of stored messages\n  - Ideally would drop the request along with the response\n- [ ] Use `Node.start/3`: https://hexdocs.pm/elixir/Node.html#start/3\n- [ ] Generate a random node name, and display the node name on the home page\n- [ ] Track down byte_length issue in messages_view.ex\n- [ ] Auto-complete in filter text input based on seen messages\n\nLater:\n- [ ] Issue: not reliably sending messages via json and via \"plain-text\" (is this worth fixing?)\n\nMaybe:\n- [ ] Use boundary instead of multiple apps\n- [ ] Switch to using releases instead of an escript\n\nLong-term:\n- [ ] collect client-server communication for bug filing on clients and servers\n- [ ] A way to view collected logs after the fact\n  - lsp-mode: `(setq lsp-print-io t)`\n  - vscode: C-S-p -\u003e User Settings -\u003e type \"trace\" mark css language server to use verbose and then from the output view you will find the vscode trace log\n- [ ] if the specified port is taken, try the next one\n  - [ ] and register with that other server so we can do discovery\n- [ ] Support language-server-protocol-inspector format (is there docs for this?)\n\nOnce published, the docs can be found at\n[https://hexdocs.pm/ls_proxy](https://hexdocs.pm/ls_proxy).\n\nRelated:\n* https://github.com/Microsoft/language-server-protocol-inspector\n\nFuture Features:\n* Render a web page showing the features that the server supports\n* Support TCP sockets? Is that even part of LSP?\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faxelson%2Fls_proxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faxelson%2Fls_proxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faxelson%2Fls_proxy/lists"}