opencode-sql-lsp-server 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,92 @@
1
+ Metadata-Version: 2.4
2
+ Name: opencode-sql-lsp-server
3
+ Version: 0.1.0
4
+ Summary: SQL Language Server for OpenCode with Trino/StarRocks dialect support
5
+ Author: OpenCode SQL LSP port
6
+ License: MIT
7
+ Keywords: opencode,lsp,sql,sqlfluff,trino,starrocks
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Topic :: Software Development :: Quality Assurance
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: pygls>=1.3.1
18
+ Requires-Dist: lsprotocol>=2023.0.1
19
+ Requires-Dist: sqlfluff>=3.0.0
20
+
21
+ # opencode-sql-lsp-server
22
+
23
+ SQL LSP server (stdio) intended for OpenCode, with dialect-aware parsing/formatting.
24
+
25
+ ## Install
26
+
27
+ ### From PyPI (recommended)
28
+
29
+ ```bash
30
+ pipx install opencode-sql-lsp-server
31
+ ```
32
+
33
+ ### From source
34
+
35
+ Recommended: pipx (or a venv)
36
+
37
+ ```bash
38
+ pipx install -e .
39
+ ```
40
+
41
+ If you don't have pipx, use a virtualenv or `uv tool install`.
42
+
43
+ Or pip:
44
+
45
+ ```bash
46
+ python3 -m pip install -e .
47
+ ```
48
+
49
+ ## OpenCode config
50
+
51
+ `opencode.json`:
52
+
53
+ ```json
54
+ {
55
+ "$schema": "https://opencode.ai/config.json",
56
+ "lsp": {
57
+ "opencode-sql": {
58
+ "command": ["opencode-sql-lsp", "--stdio"],
59
+ "extensions": [".sql"]
60
+ }
61
+ }
62
+ }
63
+ ```
64
+
65
+ ## Dialect config
66
+
67
+ Create `.opencode/sql-lsp.json` in your project:
68
+
69
+ ```json
70
+ {
71
+ "defaultDialect": "starrocks",
72
+ "overrides": {
73
+ "trino/**/*.sql": "trino"
74
+ }
75
+ }
76
+ ```
77
+
78
+ Dialect keys are sqlfluff dialect labels, e.g.:
79
+
80
+ - `trino`
81
+ - `starrocks`
82
+
83
+ ## Notes
84
+
85
+ - Diagnostics and formatting are powered by `sqlfluff`.
86
+ - Dialect keys (sqlfluff): `trino`, `starrocks`.
87
+
88
+ ## Verify dialects
89
+
90
+ ```bash
91
+ sqlfluff dialects
92
+ ```
@@ -0,0 +1,72 @@
1
+ # opencode-sql-lsp-server
2
+
3
+ SQL LSP server (stdio) intended for OpenCode, with dialect-aware parsing/formatting.
4
+
5
+ ## Install
6
+
7
+ ### From PyPI (recommended)
8
+
9
+ ```bash
10
+ pipx install opencode-sql-lsp-server
11
+ ```
12
+
13
+ ### From source
14
+
15
+ Recommended: pipx (or a venv)
16
+
17
+ ```bash
18
+ pipx install -e .
19
+ ```
20
+
21
+ If you don't have pipx, use a virtualenv or `uv tool install`.
22
+
23
+ Or pip:
24
+
25
+ ```bash
26
+ python3 -m pip install -e .
27
+ ```
28
+
29
+ ## OpenCode config
30
+
31
+ `opencode.json`:
32
+
33
+ ```json
34
+ {
35
+ "$schema": "https://opencode.ai/config.json",
36
+ "lsp": {
37
+ "opencode-sql": {
38
+ "command": ["opencode-sql-lsp", "--stdio"],
39
+ "extensions": [".sql"]
40
+ }
41
+ }
42
+ }
43
+ ```
44
+
45
+ ## Dialect config
46
+
47
+ Create `.opencode/sql-lsp.json` in your project:
48
+
49
+ ```json
50
+ {
51
+ "defaultDialect": "starrocks",
52
+ "overrides": {
53
+ "trino/**/*.sql": "trino"
54
+ }
55
+ }
56
+ ```
57
+
58
+ Dialect keys are sqlfluff dialect labels, e.g.:
59
+
60
+ - `trino`
61
+ - `starrocks`
62
+
63
+ ## Notes
64
+
65
+ - Diagnostics and formatting are powered by `sqlfluff`.
66
+ - Dialect keys (sqlfluff): `trino`, `starrocks`.
67
+
68
+ ## Verify dialects
69
+
70
+ ```bash
71
+ sqlfluff dialects
72
+ ```
@@ -0,0 +1,36 @@
1
+ [build-system]
2
+ requires = ["setuptools>=68", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "opencode-sql-lsp-server"
7
+ version = "0.1.0"
8
+ description = "SQL Language Server for OpenCode with Trino/StarRocks dialect support"
9
+ readme = "README.md"
10
+ requires-python = ">=3.10"
11
+ license = { text = "MIT" }
12
+ authors = [{ name = "OpenCode SQL LSP port" }]
13
+ keywords = ["opencode", "lsp", "sql", "sqlfluff", "trino", "starrocks"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Environment :: Console",
17
+ "Intended Audience :: Developers",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3 :: Only",
21
+ "Topic :: Software Development :: Quality Assurance",
22
+ ]
23
+ dependencies = [
24
+ "pygls>=1.3.1",
25
+ "lsprotocol>=2023.0.1",
26
+ "sqlfluff>=3.0.0",
27
+ ]
28
+
29
+ [project.scripts]
30
+ opencode-sql-lsp = "opencode_sql_lsp_server.cli:main"
31
+
32
+ [tool.setuptools]
33
+ package-dir = {"" = "src"}
34
+
35
+ [tool.setuptools.packages.find]
36
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,2 @@
1
+ __all__ = ["__version__"]
2
+ __version__ = "0.1.0"
@@ -0,0 +1,30 @@
1
+ from __future__ import annotations
2
+
3
+ import argparse
4
+
5
+ from .server import server
6
+
7
+
8
+ def main() -> None:
9
+ parser = argparse.ArgumentParser(prog="opencode-sql-lsp")
10
+ parser.add_argument(
11
+ "--stdio",
12
+ action="store_true",
13
+ help="Run the language server over stdio (recommended)",
14
+ )
15
+ parser.add_argument(
16
+ "--workspace",
17
+ type=str,
18
+ default=None,
19
+ help="Workspace root (used for .opencode/sql-lsp.json); if omitted, uses client rootUri when possible",
20
+ )
21
+ args = parser.parse_args()
22
+
23
+ if not args.stdio:
24
+ raise SystemExit("Only --stdio transport is supported")
25
+
26
+ # pygls gets rootUri from initialize; we optionally allow an override.
27
+ if args.workspace:
28
+ server.set_workspace_root(args.workspace)
29
+
30
+ server.start_io()
@@ -0,0 +1,41 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from dataclasses import dataclass
5
+ from fnmatch import fnmatch
6
+ from pathlib import Path
7
+ from typing import Any
8
+
9
+
10
+ @dataclass(frozen=True)
11
+ class SqlLspConfig:
12
+ default_dialect: str
13
+ overrides: dict[str, str]
14
+
15
+ @staticmethod
16
+ def load(root: Path) -> "SqlLspConfig":
17
+ cfg_path = root / ".opencode" / "sql-lsp.json"
18
+ if not cfg_path.exists():
19
+ return SqlLspConfig(default_dialect="starrocks", overrides={})
20
+ data: Any = json.loads(cfg_path.read_text(encoding="utf-8"))
21
+ default_dialect = data.get("defaultDialect")
22
+ if not isinstance(default_dialect, str) or not default_dialect.strip():
23
+ default_dialect = "starrocks"
24
+ overrides_raw = data.get("overrides")
25
+ overrides: dict[str, str] = {}
26
+ if isinstance(overrides_raw, dict):
27
+ for k, v in overrides_raw.items():
28
+ if (
29
+ isinstance(k, str)
30
+ and isinstance(v, str)
31
+ and k.strip()
32
+ and v.strip()
33
+ ):
34
+ overrides[k] = v
35
+ return SqlLspConfig(default_dialect=default_dialect, overrides=overrides)
36
+
37
+ def dialect_for_path(self, relative_path: str) -> str:
38
+ for pattern, dialect in self.overrides.items():
39
+ if fnmatch(relative_path, pattern):
40
+ return dialect
41
+ return self.default_dialect
@@ -0,0 +1,108 @@
1
+ from __future__ import annotations
2
+
3
+ from pathlib import Path
4
+ from typing import Optional
5
+
6
+ from lsprotocol.types import (
7
+ Diagnostic,
8
+ DiagnosticSeverity,
9
+ DocumentFormattingParams,
10
+ InitializeParams,
11
+ INITIALIZE,
12
+ PublishDiagnosticsParams,
13
+ TEXT_DOCUMENT_DID_CHANGE,
14
+ TEXT_DOCUMENT_DID_OPEN,
15
+ TEXT_DOCUMENT_FORMATTING,
16
+ Position,
17
+ Range,
18
+ TextEdit,
19
+ )
20
+ from pygls.lsp.server import LanguageServer
21
+
22
+ from .config import SqlLspConfig
23
+ from .sqlfluff_adapter import format_sql, lint_issues
24
+
25
+
26
+ class OpenCodeSqlLanguageServer(LanguageServer):
27
+ def __init__(self) -> None:
28
+ super().__init__("opencode-sql-lsp", "0.1.0")
29
+ self._workspace_root: Optional[Path] = None
30
+ self._config: Optional[SqlLspConfig] = None
31
+
32
+ def set_workspace_root(self, root: Optional[str]) -> None:
33
+ self._workspace_root = Path(root).resolve() if root else None
34
+ self._config = (
35
+ SqlLspConfig.load(self._workspace_root) if self._workspace_root else None
36
+ )
37
+
38
+ def dialect_for_document(self, doc_uri: str) -> str:
39
+ if not self._workspace_root or not self._config:
40
+ return "starrocks"
41
+ try:
42
+ p = Path(self.uri_to_path(doc_uri)).resolve()
43
+ rel = p.relative_to(self._workspace_root)
44
+ return self._config.dialect_for_path(str(rel))
45
+ except Exception:
46
+ return self._config.default_dialect
47
+
48
+
49
+ server = OpenCodeSqlLanguageServer()
50
+
51
+
52
+ @server.feature(INITIALIZE)
53
+ def initialize(ls: OpenCodeSqlLanguageServer, params: InitializeParams):
54
+ root_uri = getattr(params, "root_uri", None)
55
+ if isinstance(root_uri, str) and root_uri:
56
+ try:
57
+ ls.set_workspace_root(ls.uri_to_path(root_uri))
58
+ except Exception:
59
+ pass
60
+
61
+
62
+ def _publish_diagnostics(ls: OpenCodeSqlLanguageServer, uri: str) -> None:
63
+ doc = ls.workspace.get_text_document(uri)
64
+ dialect = ls.dialect_for_document(uri)
65
+ issues = lint_issues(doc.source, dialect=dialect)
66
+ diagnostics: list[Diagnostic] = []
67
+ for issue in issues:
68
+ start = Position(line=issue.line - 1, character=issue.character)
69
+ end = Position(line=issue.line - 1, character=issue.character + 1)
70
+ diagnostics.append(
71
+ Diagnostic(
72
+ range=Range(start=start, end=end),
73
+ message=issue.message,
74
+ severity=DiagnosticSeverity.Error,
75
+ source="sqlglot",
76
+ )
77
+ )
78
+ ls.text_document_publish_diagnostics(
79
+ PublishDiagnosticsParams(uri=uri, diagnostics=diagnostics)
80
+ )
81
+
82
+
83
+ @server.feature(TEXT_DOCUMENT_DID_OPEN)
84
+ def did_open(ls: OpenCodeSqlLanguageServer, params):
85
+ _publish_diagnostics(ls, params.text_document.uri)
86
+
87
+
88
+ @server.feature(TEXT_DOCUMENT_DID_CHANGE)
89
+ def did_change(ls: OpenCodeSqlLanguageServer, params):
90
+ _publish_diagnostics(ls, params.text_document.uri)
91
+
92
+
93
+ @server.feature(TEXT_DOCUMENT_FORMATTING)
94
+ def formatting(ls: OpenCodeSqlLanguageServer, params: DocumentFormattingParams):
95
+ doc = ls.workspace.get_text_document(params.text_document.uri)
96
+ dialect = ls.dialect_for_document(params.text_document.uri)
97
+ try:
98
+ formatted = format_sql(doc.source, dialect=dialect)
99
+ except Exception:
100
+ return []
101
+ # Replace entire document
102
+ last_line = max(0, len(doc.lines) - 1)
103
+ last_char = len(doc.lines[last_line]) if doc.lines else 0
104
+ edit_range = Range(
105
+ start=Position(line=0, character=0),
106
+ end=Position(line=last_line, character=last_char),
107
+ )
108
+ return [TextEdit(range=edit_range, new_text=formatted)]
@@ -0,0 +1,54 @@
1
+ from __future__ import annotations
2
+
3
+ from dataclasses import dataclass
4
+
5
+
6
+ @dataclass(frozen=True)
7
+ class SqlIssue:
8
+ message: str
9
+ line: int
10
+ character: int
11
+
12
+
13
+ def lint_issues(sql: str, dialect: str) -> list[SqlIssue]:
14
+ try:
15
+ from sqlfluff.api.simple import get_simple_config
16
+ from sqlfluff.core import Linter
17
+ except Exception as e:
18
+ return [SqlIssue(message=f"sqlfluff not available: {e}", line=1, character=0)]
19
+
20
+ try:
21
+ config = get_simple_config(dialect=dialect)
22
+ linter = Linter(config=config)
23
+ result = linter.lint_string_wrapped(sql)
24
+ violations = result.get_violations()
25
+ issues: list[SqlIssue] = []
26
+ for v in violations:
27
+ line_no = getattr(v, "line_no", None)
28
+ line_pos = getattr(v, "line_pos", None)
29
+ if isinstance(line_no, int) and isinstance(line_pos, int):
30
+ issues.append(
31
+ SqlIssue(
32
+ message=str(
33
+ getattr(v, "desc", None)
34
+ or getattr(v, "description", None)
35
+ or v
36
+ ),
37
+ line=max(1, line_no),
38
+ character=max(0, line_pos - 1),
39
+ )
40
+ )
41
+ else:
42
+ issues.append(SqlIssue(message=str(v), line=1, character=0))
43
+ return issues
44
+ except Exception as e:
45
+ return [SqlIssue(message=str(e), line=1, character=0)]
46
+
47
+
48
+ def format_sql(sql: str, dialect: str) -> str:
49
+ try:
50
+ from sqlfluff.api.simple import fix
51
+ except Exception as e:
52
+ raise RuntimeError(f"sqlfluff not available: {e}")
53
+
54
+ return fix(sql, dialect=dialect)
@@ -0,0 +1,92 @@
1
+ Metadata-Version: 2.4
2
+ Name: opencode-sql-lsp-server
3
+ Version: 0.1.0
4
+ Summary: SQL Language Server for OpenCode with Trino/StarRocks dialect support
5
+ Author: OpenCode SQL LSP port
6
+ License: MIT
7
+ Keywords: opencode,lsp,sql,sqlfluff,trino,starrocks
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Topic :: Software Development :: Quality Assurance
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ Requires-Dist: pygls>=1.3.1
18
+ Requires-Dist: lsprotocol>=2023.0.1
19
+ Requires-Dist: sqlfluff>=3.0.0
20
+
21
+ # opencode-sql-lsp-server
22
+
23
+ SQL LSP server (stdio) intended for OpenCode, with dialect-aware parsing/formatting.
24
+
25
+ ## Install
26
+
27
+ ### From PyPI (recommended)
28
+
29
+ ```bash
30
+ pipx install opencode-sql-lsp-server
31
+ ```
32
+
33
+ ### From source
34
+
35
+ Recommended: pipx (or a venv)
36
+
37
+ ```bash
38
+ pipx install -e .
39
+ ```
40
+
41
+ If you don't have pipx, use a virtualenv or `uv tool install`.
42
+
43
+ Or pip:
44
+
45
+ ```bash
46
+ python3 -m pip install -e .
47
+ ```
48
+
49
+ ## OpenCode config
50
+
51
+ `opencode.json`:
52
+
53
+ ```json
54
+ {
55
+ "$schema": "https://opencode.ai/config.json",
56
+ "lsp": {
57
+ "opencode-sql": {
58
+ "command": ["opencode-sql-lsp", "--stdio"],
59
+ "extensions": [".sql"]
60
+ }
61
+ }
62
+ }
63
+ ```
64
+
65
+ ## Dialect config
66
+
67
+ Create `.opencode/sql-lsp.json` in your project:
68
+
69
+ ```json
70
+ {
71
+ "defaultDialect": "starrocks",
72
+ "overrides": {
73
+ "trino/**/*.sql": "trino"
74
+ }
75
+ }
76
+ ```
77
+
78
+ Dialect keys are sqlfluff dialect labels, e.g.:
79
+
80
+ - `trino`
81
+ - `starrocks`
82
+
83
+ ## Notes
84
+
85
+ - Diagnostics and formatting are powered by `sqlfluff`.
86
+ - Dialect keys (sqlfluff): `trino`, `starrocks`.
87
+
88
+ ## Verify dialects
89
+
90
+ ```bash
91
+ sqlfluff dialects
92
+ ```
@@ -0,0 +1,13 @@
1
+ README.md
2
+ pyproject.toml
3
+ src/opencode_sql_lsp_server/__init__.py
4
+ src/opencode_sql_lsp_server/cli.py
5
+ src/opencode_sql_lsp_server/config.py
6
+ src/opencode_sql_lsp_server/server.py
7
+ src/opencode_sql_lsp_server/sqlfluff_adapter.py
8
+ src/opencode_sql_lsp_server.egg-info/PKG-INFO
9
+ src/opencode_sql_lsp_server.egg-info/SOURCES.txt
10
+ src/opencode_sql_lsp_server.egg-info/dependency_links.txt
11
+ src/opencode_sql_lsp_server.egg-info/entry_points.txt
12
+ src/opencode_sql_lsp_server.egg-info/requires.txt
13
+ src/opencode_sql_lsp_server.egg-info/top_level.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ opencode-sql-lsp = opencode_sql_lsp_server.cli:main
@@ -0,0 +1,3 @@
1
+ pygls>=1.3.1
2
+ lsprotocol>=2023.0.1
3
+ sqlfluff>=3.0.0