11 Commits

Author SHA1 Message Date
Henrik Jess Nielsen
3b7c29d1e6 feat: add landing page at /
All checks were successful
Build and Deploy iLSP / test (push) Successful in 22s
Build and Deploy iLSP / build-and-deploy (push) Successful in 1m49s
Clean HTML page describing iLSP, what LSP is, the WebSocket endpoints,
and setup instructions for Neovim, IntelliJ and VS Code. Live stats
(Bicep modules, pipeline templates, PyPI packages) are rendered from
the in-memory catalog at request time.

No emojis. Minimal CSS, no external dependencies.
2026-05-10 18:17:14 +02:00
Henrik Jess Nielsen
ae751f944c fix: yaml stdio per-connection, iac catalog path, makefile port
All checks were successful
Build and Deploy iLSP / test (push) Successful in 25s
Build and Deploy iLSP / build-and-deploy (push) Successful in 1m37s
- yaml-language-server: rewrite to stdio per WebSocket (fixes crash loop)
  vscode-jsonrpc v9 createServerSocketTransport is a TCP client, not server
  now spawns yaml-language-server --stdio per connection via asyncio subprocess

- bicep/modules.py: add /iac_source_catalog.json as first path in _IAC_SOURCE_PATHS
  Dockerfile copies to /iac_source_catalog.json but path wasn't listed

- server.py: remove YAML_LSP_PORT daemon (no longer needed with stdio mode)

- Makefile: add -e HTTP_PORT=$(HEALTH_PORT) to all docker run commands
  server defaulted to :8000 but Makefile exposed :2089 with no override
2026-05-10 16:37:42 +02:00
Henrik Jess Nielsen
333d986e76 feat: YAML pipeline template autocomplete (AzDO + GHA)
All checks were successful
Build and Deploy iLSP / test (push) Successful in 25s
Build and Deploy iLSP / build-and-deploy (push) Successful in 1m34s
- Add scripts/sync_pipeline_templates.py — scans LRU AzDO and GHA template
  repos; outputs unified pipeline_templates_catalog.json (48 templates: 45
  AzDO + 3 GHA)
- Add scripts/template_sources.yml — source config (AzDO alias, GHA org)
- Add pipeline_templates_catalog.json — baked catalog (49 KB)
- Add ilsp/yaml_lsp/catalog.py — PipelineTemplateCatalog with completion item
  generators for template paths, param names, allowed values, GHA inputs
- Add ilsp/yaml_lsp/proxy.py — async WS↔TCP bridge with LSP frame buffering,
  per-connection document tracking, AzDO/GHA context detection, and completion
  injection (LRU items sortText 0_, standard items downgraded to 9_)
- Wire yaml_ws_handler into server.py (replaces raw _ws_proxy call)
- Load PipelineTemplateCatalog at startup; reload + health report template count
- Update push_catalogs.sh to push pipeline_templates_catalog.json
- Update Dockerfile to bake pipeline_templates_catalog.json as image fallback
- Add tests/test_yaml_catalog.py (14 tests) + tests/test_yaml_proxy.py (18 tests)
  All 67 tests green
2026-05-10 15:59:37 +02:00
Henrik Jess Nielsen
5501254b55 feat: YAML LSP (/yaml endpoint) + IAC source catalog enrichment
All checks were successful
Build and Deploy iLSP / test (push) Successful in 21s
Build and Deploy iLSP / build-and-deploy (push) Successful in 2m49s
- Add yaml-language-server (Node.js) to Dockerfile stage 3
- Add YAML_LSP_PORT=2090 env var (Dockerfile + ilsp.nomad)
- Start yaml-language-server in background thread (_serve_yaml_lsp)
- Expose /yaml WebSocket endpoint (same WS→TCP proxy as /python and /bicep)
- Load iac_source_catalog.json alongside bicep_modules_catalog.json
- Enrich param_completion_items() with descriptions + required flag from IAC source
  - Required params sorted first (sortText 0_lru_param_0_...) and marked with *
  - detail field shows * prefix for required params
- Update /health to report iac_source_modules + yaml_lsp fields
- Rewrite EDITOR_SETUP.md: WebSocket URLs, YAML schemas config for all editors
  (Helix, Neovim, PyCharm, VS Code) with azure-pipelines + gitea actions schemas
- All 35 tests pass
2026-05-10 15:40:13 +02:00
Henrik Jess Nielsen
bf24b5677f fix: backend unavailable test — use free port + ws.close(timeout=2s)
All checks were successful
Build and Deploy iLSP / test (push) Successful in 20s
Build and Deploy iLSP / build-and-deploy (push) Successful in 1m32s
- Use _free_port() instead of hardcoded 19999 (avoids CI port conflicts)
- Add timeout=2.0 to ws.close() so close handshake never blocks >2s
2026-05-10 15:16:55 +02:00
Henrik Jess Nielsen
404bd1418d fix: add 3s timeout to LSP backend connection (handles CI firewall drops)
Some checks failed
Build and Deploy iLSP / test (push) Failing after 27s
Build and Deploy iLSP / build-and-deploy (push) Has been skipped
asyncio.open_connection hangs indefinitely when backend port is silently
dropped. Add wait_for(timeout=3.0) so the WS close frame is always sent
within the test's 5s window.
2026-05-10 15:13:03 +02:00
Henrik Jess Nielsen
941d7b003f refactor: single HTTP port, WebSocket proxy for LSP endpoints
All checks were successful
Build and Deploy iLSP / test (push) Successful in 19s
Build and Deploy iLSP / build-and-deploy (push) Successful in 1m27s
- Remove static ports 2087/2088/2089 from Nomad; use one dynamic port
- pylsp and Bicep LS stay on localhost inside container (not exposed)
- aiohttp adds /python and /bicep WebSocket routes bridging to localhost LSPs
- Nomad env: HTTP_PORT=$NOMAD_PORT_http, internal ports fixed at 2087/2088
- Editors connect via ws://ilsp.i80.dk/python and ws://ilsp.i80.dk/bicep
- Traefik routes ilsp.i80.dk → single dynamic HTTP port
2026-05-10 14:44:33 +02:00
Henrik Jess Nielsen
0527df717c feat: volume-based catalog refresh with hot-reload
Some checks failed
Build and Deploy iLSP / test (push) Successful in 18s
Build and Deploy iLSP / build-and-deploy (push) Failing after 12m14s
- modules.py: check /data/ volume first, then baked-in /bicep_modules_catalog.json
- server.py: add POST /reload endpoint — reloads catalogs without restart
- ilsp.nomad: add 'ilsp-data' host volume mounted at /data
- Makefile: add push-catalogs, health-prod, run-with-data targets; DEVOPS_MCP_REPO var
- scripts/push_catalogs.sh: SCP both catalogs to autobox + call /reload

Workflow: sync scripts on Mac → make push-catalogs → completions live in <5s
2026-05-10 13:51:01 +02:00
Henrik Jess Nielsen
6b38cbd70c feat: bake bicep catalog into image; fix dict-based modules parsing
Some checks failed
Build and Deploy iLSP / build-and-deploy (push) Has been cancelled
Build and Deploy iLSP / test (push) Successful in 18s
- Remove all DevOpsMCP/aiohttp runtime deps from BicepModuleCatalog
- BicepModuleCatalog.load() reads bicep_modules_catalog.json from disk at startup (sync)
- Fix _load_catalog: catalog uses dict {path: {versions, schema}} not a list
- server.py: call BicepModuleCatalog.load() synchronously, not via asyncio.gather
- Dockerfile: COPY bicep_modules_catalog.json into both builder + runtime stages
- Health endpoint now reports bicep_modules: 27

Verified locally: make run-quick → health returns pypi_packages:40 bicep_modules:27
2026-05-10 13:40:48 +02:00
Henrik Jess Nielsen
6385e159ff fix: replace asyncio subprocess proxy with thread-based Popen proxy
Some checks failed
Build and Deploy iLSP / test (push) Failing after 12s
Build and Deploy iLSP / build-and-deploy (push) Has been skipped
asyncio subprocess PIPE unreliable for long-lived stdio bridging. Use Popen + threads instead. Also fix smoke_test.sh stdin handling.
2026-05-10 13:02:52 +02:00
Henrik Jess Nielsen
d8536468ab feat: initial iLSP project scaffolding
Some checks failed
CI / deploy (push) Has been cancelled
CI / build-and-push (push) Has been cancelled
- Python LSP (pylsp + pylsp_i80 plugin): i80 pypi package completions
- Bicep LSP (asyncio TCP proxy → Bicep.LangServer.dll): LRU module injection
- Health HTTP endpoint (:2089) for Consul/Nomad checks
- Startup catalog fetch from pypi-server.i80.dk + DevOpsMCP (no volume needed)
- Multi-stage Dockerfile: downloads Bicep LS at build time, dotnet-runtime-8.0 + python3.12
- Nomad job: static TCP ports 2087/2088, health check on 2089
- Gitea Actions CI: build + push + deploy pipeline
- Editor configs: Helix / nvim / LSP4IJ / VS Code
2026-05-10 12:23:05 +02:00