feat: add streamd lsp subcommand with LSP server #90

Merged
kfickel merged 12 commits from 89_streamd-lsp-subcommand into main 2026-04-19 21:18:45 +02:00
Owner

Summary

Implements a Language Server Protocol server accessible via streamd lsp (stdin/stdout transport). Closes #89.

  • Passive mode: server enters no-op mode if .streamd.toml is absent from the workspace root
  • Workspace-root resolution: reads initializeParams.rootUri directly; bypasses R22/R23 global config
  • Config watching: workspace/didChangeWatchedFiles watcher reloads .streamd.toml without restart
  • Full-document sync on didOpen, didChange, didSave

Features

Capability Detail
@ completions Marker names from merged config; conditional suggestions via if_with; temporal snippets
Diagnostics R15 file-name format warning; R18 timesheet errors (overlapping timecards, unclosed days)
Document symbols LocalizedShard tree as nested DocumentSymbol nodes
Code action "Mark task as done" quickfix for @Task lines
Workspace symbols Cross-file shard search via workspace/symbol
References textDocument/references for @Marker across workspace
Rename textDocument/rename renames @Marker across all files

Dependencies added

tower-lsp 0.20, tokio, dashmap 6, serde_json 1

Test plan

  • 13 new unit tests in src/cli/commands/lsp.rs
  • All 187 tests pass
  • nix flake check passes (clippy -D warnings, fmt, tests, pre-commit)
## Summary Implements a Language Server Protocol server accessible via `streamd lsp` (stdin/stdout transport). Closes #89. - **Passive mode**: server enters no-op mode if `.streamd.toml` is absent from the workspace root - **Workspace-root resolution**: reads `initializeParams.rootUri` directly; bypasses R22/R23 global config - **Config watching**: `workspace/didChangeWatchedFiles` watcher reloads `.streamd.toml` without restart - **Full-document sync** on `didOpen`, `didChange`, `didSave` ### Features | Capability | Detail | |---|---| | `@` completions | Marker names from merged config; conditional suggestions via `if_with`; temporal snippets | | Diagnostics | R15 file-name format warning; R18 timesheet errors (overlapping timecards, unclosed days) | | Document symbols | `LocalizedShard` tree as nested `DocumentSymbol` nodes | | Code action | "Mark task as done" quickfix for `@Task` lines | | Workspace symbols | Cross-file shard search via `workspace/symbol` | | References | `textDocument/references` for `@Marker` across workspace | | Rename | `textDocument/rename` renames `@Marker` across all files | ### Dependencies added `tower-lsp 0.20`, `tokio`, `dashmap 6`, `serde_json 1` ## Test plan - [x] 13 new unit tests in `src/cli/commands/lsp.rs` - [x] All 187 tests pass - [x] `nix flake check` passes (clippy -D warnings, fmt, tests, pre-commit)
kfickel added 2 commits 2026-04-13 21:45:48 +02:00
Implements a full Language Server Protocol server accessible via
`streamd lsp`. The server communicates over stdin/stdout and auto-
detects the workspace root from the LSP initialize request.

Features implemented:
- Passive mode when no .streamd.toml exists in workspace root
- Workspace-root-based config loading (bypasses R22/R23 global config)
- .streamd.toml file watcher (config reloads without restart)
- textDocument/completion with @ trigger, conditional suggestions
  (if_with relationships), and temporal date/time snippets (R16)
- textDocument/publishDiagnostics: R15 file-name format + R18
  timesheet violations (overlapping timecards, unclosed days)
- textDocument/documentSymbol: shard tree exposed as nested symbols
- textDocument/codeAction: "Mark task as done" quickfix for @Task
- workspace/symbol: cross-file shard search
- textDocument/references: find all @Marker occurrences
- textDocument/rename: rename @Marker across all files

Dependencies added: tower-lsp 0.20, tokio, dashmap, serde_json
fix: resolve clippy warnings in lsp module
All checks were successful
Continuous Integration / Lint, Check & Test (push) Successful in 2m30s
Continuous Integration / Build Package (push) Successful in 3m38s
b224620212
- Replace map_or(false, ...) with is_none_or(... !=)
- Replace explicit auto-derefs (&*Static) with auto-deref (&Static)
- Refactor range-indexed loop to iterator with enumerate + skip/take
- Suppress deprecated root_path field with allow(deprecated)

docs: update README and REQUIREMENTS for streamd lsp

- Add streamd lsp to commands table in README
- Add Editor Integration section with Zed, Neovim, VS Code snippets
- Add R25 LSP requirements (R25a–R25e) to REQUIREMENTS.md
kfickel added 1 commit 2026-04-13 21:52:47 +02:00
refactor: simplify LSP implementation
All checks were successful
Continuous Integration / Lint, Check & Test (push) Successful in 1m34s
Continuous Integration / Build Package (push) Successful in 2m17s
d0e4dccd1a
- Extract find_pattern_occurrences_in_lines helper; use in both references and rename handlers (deduplicates word-boundary search logic)
- Add MD_EXT constant to replace three repeated "md" string literals
- Fix double lock acquire/drop/re-acquire in code_action (use single guard)
- Fix symbol() to populate file_lines cache when parsing from disk (avoids redundant re-reads on subsequent requests)
- Remove section separator comment blocks (code structure is self-evident from Rust syntax)
kfickel added 1 commit 2026-04-19 10:55:25 +02:00
fix(daily): use midnight when creating file for non-today date
All checks were successful
Continuous Integration / Lint, Check & Test (push) Successful in 4m17s
Continuous Integration / Build Package (push) Successful in 5m24s
d872e9e338
kfickel added 1 commit 2026-04-19 17:59:15 +02:00
feat: add zed extension
All checks were successful
Continuous Integration / Lint, Check & Test (push) Successful in 2m38s
Continuous Integration / Build Package (push) Successful in 3m46s
9787710d59
kfickel force-pushed 89_streamd-lsp-subcommand from 9787710d59 to 0f73864693 2026-04-19 18:10:38 +02:00 Compare
kfickel force-pushed 89_streamd-lsp-subcommand from 0f73864693 to 3b116782cc 2026-04-19 20:29:20 +02:00 Compare
kfickel added 1 commit 2026-04-19 20:49:02 +02:00
fix: fix lsp adding two @
All checks were successful
Continuous Integration / Lint, Check & Test (push) Successful in 1m41s
Continuous Integration / Build Package (push) Successful in 2m21s
036d57176f
kfickel added 2 commits 2026-04-19 20:56:49 +02:00
fix: use actual timestamps for completion
Some checks failed
Continuous Integration / Lint, Check & Test (push) Failing after 59s
Continuous Integration / Build Package (push) Successful in 2m18s
50cdc14c06
kfickel added 1 commit 2026-04-19 21:01:54 +02:00
fix: fix timestamp insertion
Some checks failed
Continuous Integration / Build Package (push) Has been cancelled
Continuous Integration / Lint, Check & Test (push) Has been cancelled
74dae9a9eb
kfickel force-pushed 89_streamd-lsp-subcommand from 74dae9a9eb to 43ec0a56de 2026-04-19 21:03:03 +02:00 Compare
kfickel added 1 commit 2026-04-19 21:07:37 +02:00
fix: fix clippy
All checks were successful
Continuous Integration / Lint, Check & Test (push) Successful in 1m40s
Continuous Integration / Build Package (push) Successful in 2m18s
8e69a6afe8
kfickel added 2 commits 2026-04-19 21:16:14 +02:00
Splits git hooks into two configurations: a sandbox-safe set for
`nix flake check` (rustfmt + commitizen) and a full dev set installed
via `nix develop` that also runs clippy (deny warnings) and cargo test.
feat: add Zed extension release artifact with WSL2 support
All checks were successful
Continuous Integration / Build Package (push) Successful in 30s
Continuous Integration / Lint, Check & Test (push) Successful in 1m9s
Release / Build and Release (push) Successful in 7m10s
82adb655f1
The Zed extension now detects Windows via current_platform() and
automatically uses `wsl streamd lsp` instead of `streamd lsp`,
enabling seamless LSP support when Zed runs on Windows with streamd
installed in WSL2.

A pre-built zip (extension.toml + extension.wasm) is now built as
`zed-extension-zip` and published to every release. The README gains
a step-by-step WSL2 installation guide.
kfickel merged commit 82adb655f1 into main 2026-04-19 21:18:45 +02:00
kfickel deleted branch 89_streamd-lsp-subcommand 2026-04-19 21:18:45 +02:00
Sign in to join this conversation.
No reviewers
No labels
planned
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference: kfickel/streamd#90
No description provided.