sqlsaber 0.28.0__py3-none-any.whl → 0.29.1__py3-none-any.whl
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.
Potentially problematic release.
This version of sqlsaber might be problematic. Click here for more details.
- sqlsaber/application/auth_setup.py +3 -3
- sqlsaber/application/db_setup.py +2 -2
- sqlsaber/application/model_selection.py +2 -2
- sqlsaber/cli/auth.py +10 -8
- sqlsaber/cli/commands.py +5 -3
- sqlsaber/cli/database.py +22 -20
- sqlsaber/cli/interactive.py +11 -5
- sqlsaber/cli/memory.py +10 -10
- sqlsaber/cli/models.py +12 -12
- sqlsaber/cli/onboarding.py +41 -44
- sqlsaber/cli/theme.py +146 -0
- sqlsaber/cli/threads.py +3 -3
- sqlsaber/config/api_keys.py +5 -5
- sqlsaber/config/oauth_flow.py +11 -10
- sqlsaber/config/oauth_tokens.py +7 -5
- sqlsaber/database/schema.py +1 -1
- sqlsaber/theme/manager.py +87 -85
- {sqlsaber-0.28.0.dist-info → sqlsaber-0.29.1.dist-info}/METADATA +1 -1
- {sqlsaber-0.28.0.dist-info → sqlsaber-0.29.1.dist-info}/RECORD +22 -21
- {sqlsaber-0.28.0.dist-info → sqlsaber-0.29.1.dist-info}/WHEEL +0 -0
- {sqlsaber-0.28.0.dist-info → sqlsaber-0.29.1.dist-info}/entry_points.txt +0 -0
- {sqlsaber-0.28.0.dist-info → sqlsaber-0.29.1.dist-info}/licenses/LICENSE +0 -0
sqlsaber/theme/manager.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"""Theme management for unified theming across Rich and prompt_toolkit."""
|
|
2
2
|
|
|
3
|
+
import json
|
|
3
4
|
import os
|
|
4
|
-
import tomllib
|
|
5
5
|
from dataclasses import dataclass
|
|
6
6
|
from functools import lru_cache
|
|
7
7
|
from typing import Dict
|
|
@@ -10,20 +10,14 @@ from platformdirs import user_config_dir
|
|
|
10
10
|
from prompt_toolkit.styles import Style as PTStyle
|
|
11
11
|
from prompt_toolkit.styles.pygments import style_from_pygments_cls
|
|
12
12
|
from pygments.styles import get_style_by_name
|
|
13
|
+
from pygments.token import Token
|
|
14
|
+
from pygments.util import ClassNotFound
|
|
13
15
|
from rich.console import Console
|
|
14
16
|
from rich.theme import Theme
|
|
15
17
|
|
|
16
18
|
DEFAULT_THEME_NAME = "nord"
|
|
17
19
|
|
|
18
20
|
DEFAULT_ROLE_PALETTE = {
|
|
19
|
-
# base roles
|
|
20
|
-
"primary": "cyan",
|
|
21
|
-
"accent": "magenta",
|
|
22
|
-
"success": "green",
|
|
23
|
-
"warning": "yellow",
|
|
24
|
-
"error": "red",
|
|
25
|
-
"info": "cyan",
|
|
26
|
-
"muted": "dim",
|
|
27
21
|
# components
|
|
28
22
|
"table.header": "bold $primary",
|
|
29
23
|
"panel.border.user": "$info",
|
|
@@ -43,89 +37,97 @@ DEFAULT_ROLE_PALETTE = {
|
|
|
43
37
|
"title": "bold $success",
|
|
44
38
|
}
|
|
45
39
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
"error": "#dc322f", # (using solarized red as fallback)
|
|
85
|
-
"info": "#2aa198", # (using solarized cyan as fallback)
|
|
86
|
-
"muted": "dim",
|
|
87
|
-
},
|
|
88
|
-
# Material (approximation based on material design colors)
|
|
89
|
-
"material": {
|
|
90
|
-
"primary": "#89ddff", # cyan
|
|
91
|
-
"accent": "#f07178", # pink/red
|
|
92
|
-
"success": "#c3e88d", # green
|
|
93
|
-
"warning": "#ffcb6b", # yellow
|
|
94
|
-
"error": "#ff5370", # red
|
|
95
|
-
"info": "#82aaff", # blue
|
|
96
|
-
"muted": "dim",
|
|
97
|
-
},
|
|
98
|
-
# One Dark - exact colors from pygments one-dark theme
|
|
99
|
-
"one-dark": {
|
|
100
|
-
"primary": "#c678dd", # Keyword (purple)
|
|
101
|
-
"accent": "#e06c75", # Name (red)
|
|
102
|
-
"success": "#98c379", # String (green)
|
|
103
|
-
"warning": "#e5c07b", # Keyword.Type (yellow)
|
|
104
|
-
"error": "#e06c75", # Name (red, used for errors)
|
|
105
|
-
"info": "#61afef", # Name.Function (blue)
|
|
106
|
-
"muted": "dim",
|
|
107
|
-
},
|
|
108
|
-
# Lightbulb - exact colors from pygments lightbulb theme (minimal dark)
|
|
109
|
-
"lightbulb": {
|
|
110
|
-
"primary": "#73d0ff", # Keyword.Type/Name.Class (blue_1)
|
|
111
|
-
"accent": "#dfbfff", # Number (magenta_1)
|
|
112
|
-
"success": "#d5ff80", # String (green_1)
|
|
113
|
-
"warning": "#ffd173", # Name.Function (yellow_1)
|
|
114
|
-
"error": "#f88f7f", # Error (red_1)
|
|
115
|
-
"info": "#95e6cb", # Name.Entity (cyan_1)
|
|
116
|
-
"muted": "dim",
|
|
117
|
-
},
|
|
40
|
+
ROLE_TOKEN_PREFERENCES: dict[str, tuple] = {
|
|
41
|
+
"primary": (
|
|
42
|
+
Token.Keyword,
|
|
43
|
+
Token.Keyword.Namespace,
|
|
44
|
+
Token.Name.Tag,
|
|
45
|
+
),
|
|
46
|
+
"accent": (
|
|
47
|
+
Token.Name.Tag,
|
|
48
|
+
Token.Keyword.Type,
|
|
49
|
+
Token.Literal.Number,
|
|
50
|
+
Token.Operator.Word,
|
|
51
|
+
),
|
|
52
|
+
"success": (
|
|
53
|
+
Token.Literal.String,
|
|
54
|
+
Token.Generic.Inserted,
|
|
55
|
+
Token.Name.Attribute,
|
|
56
|
+
),
|
|
57
|
+
"warning": (
|
|
58
|
+
Token.Literal.String.Escape,
|
|
59
|
+
Token.Name.Constant,
|
|
60
|
+
Token.Generic.Emph,
|
|
61
|
+
),
|
|
62
|
+
"error": (
|
|
63
|
+
Token.Error,
|
|
64
|
+
Token.Generic.Error,
|
|
65
|
+
Token.Generic.Deleted,
|
|
66
|
+
Token.Name.Exception,
|
|
67
|
+
),
|
|
68
|
+
"info": (
|
|
69
|
+
Token.Name.Function,
|
|
70
|
+
Token.Name.Builtin,
|
|
71
|
+
Token.Keyword.Type,
|
|
72
|
+
),
|
|
73
|
+
"muted": (
|
|
74
|
+
Token.Comment,
|
|
75
|
+
Token.Generic.Subheading,
|
|
76
|
+
Token.Text,
|
|
77
|
+
),
|
|
118
78
|
}
|
|
119
79
|
|
|
120
80
|
|
|
81
|
+
def _normalize_hex(color: str | None) -> str | None:
|
|
82
|
+
if not color:
|
|
83
|
+
return None
|
|
84
|
+
color = color.strip()
|
|
85
|
+
if not color:
|
|
86
|
+
return None
|
|
87
|
+
if color.startswith("#"):
|
|
88
|
+
color = color[1:]
|
|
89
|
+
if len(color) == 3:
|
|
90
|
+
color = "".join(ch * 2 for ch in color)
|
|
91
|
+
if len(color) != 6:
|
|
92
|
+
return None
|
|
93
|
+
return f"#{color.lower()}"
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def _build_role_palette_from_style(style_name: str) -> dict[str, str]:
|
|
97
|
+
try:
|
|
98
|
+
style_cls = get_style_by_name(style_name)
|
|
99
|
+
except ClassNotFound:
|
|
100
|
+
return {}
|
|
101
|
+
|
|
102
|
+
palette: dict[str, str] = {}
|
|
103
|
+
try:
|
|
104
|
+
base_color = _normalize_hex(style_cls.style_for_token(Token.Text).get("color"))
|
|
105
|
+
except KeyError:
|
|
106
|
+
base_color = None
|
|
107
|
+
for role, tokens in ROLE_TOKEN_PREFERENCES.items():
|
|
108
|
+
for token in tokens:
|
|
109
|
+
try:
|
|
110
|
+
style_def = style_cls.style_for_token(token)
|
|
111
|
+
except KeyError:
|
|
112
|
+
continue
|
|
113
|
+
color = _normalize_hex(style_def.get("color"))
|
|
114
|
+
if not color or color == base_color:
|
|
115
|
+
continue
|
|
116
|
+
if role == "accent" and color == palette.get("primary"):
|
|
117
|
+
continue
|
|
118
|
+
palette[role] = color
|
|
119
|
+
break
|
|
120
|
+
return palette
|
|
121
|
+
|
|
122
|
+
|
|
121
123
|
def _load_user_theme_config() -> dict:
|
|
122
124
|
"""Load theme configuration from user config directory."""
|
|
123
125
|
cfg_dir = user_config_dir("sqlsaber")
|
|
124
|
-
path = os.path.join(cfg_dir, "theme.
|
|
126
|
+
path = os.path.join(cfg_dir, "theme.json")
|
|
125
127
|
if not os.path.exists(path):
|
|
126
128
|
return {}
|
|
127
|
-
with open(path, "
|
|
128
|
-
return
|
|
129
|
+
with open(path, "r") as f:
|
|
130
|
+
return json.load(f)
|
|
129
131
|
|
|
130
132
|
|
|
131
133
|
def _resolve_refs(palette: dict[str, str]) -> dict[str, str]:
|
|
@@ -204,7 +206,7 @@ def get_theme_manager() -> ThemeManager:
|
|
|
204
206
|
pygments_style = user_cfg.get("theme", {}).get("pygments_style") or name
|
|
205
207
|
|
|
206
208
|
roles = dict(DEFAULT_ROLE_PALETTE)
|
|
207
|
-
roles.update(
|
|
209
|
+
roles.update(_build_role_palette_from_style(pygments_style))
|
|
208
210
|
roles.update(user_cfg.get("roles", {}))
|
|
209
211
|
|
|
210
212
|
cfg = ThemeConfig(name=name, pygments_style=pygments_style, roles=roles)
|
|
@@ -5,28 +5,29 @@ sqlsaber/agents/base.py,sha256=40-MKEoz5rGrqVIylV1U2DaAUSPFcC75ohRin4E3-kk,2668
|
|
|
5
5
|
sqlsaber/agents/mcp.py,sha256=Pn8tdDRUEVLYQyEi5nHRp9MKNePwHVVoeNI-uqWcr0Y,757
|
|
6
6
|
sqlsaber/agents/pydantic_ai_agent.py,sha256=wBxKz0pjOkL-HI-TXV6B67bczZNgu7k26Rr3w5usR3o,10064
|
|
7
7
|
sqlsaber/application/__init__.py,sha256=KY_-d5nEdQyAwNOsK5r-f7Tb69c63XbuEkHPeLpJal8,84
|
|
8
|
-
sqlsaber/application/auth_setup.py,sha256=
|
|
9
|
-
sqlsaber/application/db_setup.py,sha256=
|
|
10
|
-
sqlsaber/application/model_selection.py,sha256=
|
|
8
|
+
sqlsaber/application/auth_setup.py,sha256=D94dyU9bOVfnNHLnnFJb5PaeWsKPTL21CiS_DLcY93A,5114
|
|
9
|
+
sqlsaber/application/db_setup.py,sha256=ZSgR9rJJVHttIjsbYQS9GEIyzkM09k5RLrVGdegrfYc,6859
|
|
10
|
+
sqlsaber/application/model_selection.py,sha256=fSC06MZNKinHDR-csMFVYYJFyK8MydKf6pStof74Jp0,3191
|
|
11
11
|
sqlsaber/application/prompts.py,sha256=4rMGcWpYJbNWPMzqVWseUMx0nwvXOkWS6GaTAJ5mhfc,3473
|
|
12
12
|
sqlsaber/cli/__init__.py,sha256=qVSLVJLLJYzoC6aj6y9MFrzZvAwc4_OgxU9DlkQnZ4M,86
|
|
13
|
-
sqlsaber/cli/auth.py,sha256=
|
|
14
|
-
sqlsaber/cli/commands.py,sha256
|
|
13
|
+
sqlsaber/cli/auth.py,sha256=elUpw8gypHGlxbHx4a4_z4wFznx2vr6V1h8lqpeC6OQ,6121
|
|
14
|
+
sqlsaber/cli/commands.py,sha256=Pii_SlVKpNEtt57_QPQzwC1u-x6tA8kuG8yd43undWE,8628
|
|
15
15
|
sqlsaber/cli/completers.py,sha256=g-hLDq5fiBx7gg8Bte1Lq8GU-ZxCYVs4dcPsmHPIcK4,6574
|
|
16
|
-
sqlsaber/cli/database.py,sha256=
|
|
16
|
+
sqlsaber/cli/database.py,sha256=Tqy8H5MnjsrmOSPcbA5Qy-u-IOYJCIXRJVhk0veLNDk,10726
|
|
17
17
|
sqlsaber/cli/display.py,sha256=WB5JCumhXadziDEX1EZHG3vN1Chol5FNAaTXHieqFK0,17892
|
|
18
|
-
sqlsaber/cli/interactive.py,sha256=
|
|
19
|
-
sqlsaber/cli/memory.py,sha256=
|
|
20
|
-
sqlsaber/cli/models.py,sha256=
|
|
21
|
-
sqlsaber/cli/onboarding.py,sha256=
|
|
18
|
+
sqlsaber/cli/interactive.py,sha256=PcY6mszImo_3PsqjjWmx_cOfj44OmKvD9ENOvGA-wjU,13715
|
|
19
|
+
sqlsaber/cli/memory.py,sha256=IKq09DUbqpvvtATsyDlpm7rDlGqWEhdUX9wgnR-oiq4,7850
|
|
20
|
+
sqlsaber/cli/models.py,sha256=iMTw3DCKIQbWfSfikwy-nQ5tiHWjoN4cbKA-G6RFlj4,8535
|
|
21
|
+
sqlsaber/cli/onboarding.py,sha256=iBGT-W-OJFRvQoEpuHYyO1c9Mym5c97eIefRvxGHtTg,11265
|
|
22
22
|
sqlsaber/cli/streaming.py,sha256=1XoZGPPMoTmBQVgp_Bqk483MR93j9oXxSV6Tx_-TpOg,6923
|
|
23
|
-
sqlsaber/cli/
|
|
23
|
+
sqlsaber/cli/theme.py,sha256=hP0kmsMLCtqaT7b5wB1dk1hW1hV94oP4BHdz8S6887A,4243
|
|
24
|
+
sqlsaber/cli/threads.py,sha256=o9q9Hst1Wt7cxSyrpAtwG6pkUct6csgiAmN_0P_WO3k,13637
|
|
24
25
|
sqlsaber/config/__init__.py,sha256=olwC45k8Nc61yK0WmPUk7XHdbsZH9HuUAbwnmKe3IgA,100
|
|
25
|
-
sqlsaber/config/api_keys.py,sha256=
|
|
26
|
+
sqlsaber/config/api_keys.py,sha256=9RyhD5Bntq8NMFRPiZZo8YEHACK9MPyFGp8dsmQZ1iI,3678
|
|
26
27
|
sqlsaber/config/auth.py,sha256=b5qB2h1doXyO9Bn8z0CcL8LAR2jF431gGXBGKLgTmtQ,2756
|
|
27
28
|
sqlsaber/config/database.py,sha256=Yec6_0wdzq-ADblMNnbgvouYCimYOY_DWHT9oweaISc,11449
|
|
28
|
-
sqlsaber/config/oauth_flow.py,sha256=
|
|
29
|
-
sqlsaber/config/oauth_tokens.py,sha256=
|
|
29
|
+
sqlsaber/config/oauth_flow.py,sha256=P81lHhtICdhiQu8lNwyqn2m45FGEqCEzLgUQTLG5UW0,10343
|
|
30
|
+
sqlsaber/config/oauth_tokens.py,sha256=V4U8GAQHjTfgUcTzwjRVaIE7DeN0tF9OsSjiasHw7Uc,5970
|
|
30
31
|
sqlsaber/config/providers.py,sha256=JFjeJv1K5Q93zWSlWq3hAvgch1TlgoF0qFa0KJROkKY,2957
|
|
31
32
|
sqlsaber/config/settings.py,sha256=iB4CnGQ4hw8gxkaa9CVLB_JEy6Y9h9FQTAams5OCVyI,6421
|
|
32
33
|
sqlsaber/database/__init__.py,sha256=Gi9N_NOkD459WRWXDg3hSuGoBs3xWbMDRBvsTVmnGAg,2025
|
|
@@ -36,7 +37,7 @@ sqlsaber/database/duckdb.py,sha256=8HNKdx208aFK_YtwGjLz6LTne0xEmNevD-f9dRWlrFg,1
|
|
|
36
37
|
sqlsaber/database/mysql.py,sha256=wMzDQqq4GFbfEdqXtv_sCb4Qbr9GSWqYAvOLeo5UryY,14472
|
|
37
38
|
sqlsaber/database/postgresql.py,sha256=fuf2Wl29NKXvD3mqsR08PDleNQ1PG-fNvWSxT6HDh2M,13223
|
|
38
39
|
sqlsaber/database/resolver.py,sha256=wSCcn__aCqwIfpt_LCjtW2Zgb8RpG5PlmwwZHli1q_U,3628
|
|
39
|
-
sqlsaber/database/schema.py,sha256=
|
|
40
|
+
sqlsaber/database/schema.py,sha256=CuV0ewoVaERe1gj_fJFJFWAP8aEPgepmn6X6B7bgkfQ,6962
|
|
40
41
|
sqlsaber/database/sqlite.py,sha256=iReEIiSpkhhS1VzITd79ZWqSL3fHMyfe3DRCDpM0DvE,9421
|
|
41
42
|
sqlsaber/mcp/__init__.py,sha256=COdWq7wauPBp5Ew8tfZItFzbcLDSEkHBJSMhxzy8C9c,112
|
|
42
43
|
sqlsaber/mcp/mcp.py,sha256=tpNPHpkaCre1Xjp7c4DHXbTKeuYpDQ8qhmJZvAyr7Vk,3939
|
|
@@ -44,7 +45,7 @@ sqlsaber/memory/__init__.py,sha256=GiWkU6f6YYVV0EvvXDmFWe_CxarmDCql05t70MkTEWs,6
|
|
|
44
45
|
sqlsaber/memory/manager.py,sha256=p3fybMVfH-E4ApT1ZRZUnQIWSk9dkfUPCyfkmA0HALs,2739
|
|
45
46
|
sqlsaber/memory/storage.py,sha256=ne8szLlGj5NELheqLnI7zu21V8YS4rtpYGGC7tOmi-s,5745
|
|
46
47
|
sqlsaber/theme/__init__.py,sha256=qCICX1Cg4B6yCbZ1UrerxglWxcqldRFVSRrSs73na_8,188
|
|
47
|
-
sqlsaber/theme/manager.py,sha256=
|
|
48
|
+
sqlsaber/theme/manager.py,sha256=xOi1ZLNr31ZtE8-WzxdtvywCB1rbJ7z2DTzcqHsCavY,6377
|
|
48
49
|
sqlsaber/threads/__init__.py,sha256=Hh3dIG1tuC8fXprREUpslCIgPYz8_6o7aRLx4yNeO48,139
|
|
49
50
|
sqlsaber/threads/storage.py,sha256=rsUdxT4CR52D7xtGir9UlsFnBMk11jZeflzDrk2q4ME,11183
|
|
50
51
|
sqlsaber/tools/__init__.py,sha256=x3YdmX_7P0Qq_HtZHAgfIVKTLxYqKk6oc4tGsujQWsc,586
|
|
@@ -54,8 +55,8 @@ sqlsaber/tools/instructions.py,sha256=X-x8maVkkyi16b6Tl0hcAFgjiYceZaSwyWTfmrvx8U
|
|
|
54
55
|
sqlsaber/tools/registry.py,sha256=HWOQMsNIdL4XZS6TeNUyrL-5KoSDH6PHsWd3X66o-18,3211
|
|
55
56
|
sqlsaber/tools/sql_guard.py,sha256=dTDwcZP-N4xPGzcr7MQtKUxKrlDzlc1irr9aH5a4wvk,6182
|
|
56
57
|
sqlsaber/tools/sql_tools.py,sha256=ujmAcfLkNaBrb5LWEgWcINQEQSX0LRPX3VK5Dag1Sj4,9178
|
|
57
|
-
sqlsaber-0.
|
|
58
|
-
sqlsaber-0.
|
|
59
|
-
sqlsaber-0.
|
|
60
|
-
sqlsaber-0.
|
|
61
|
-
sqlsaber-0.
|
|
58
|
+
sqlsaber-0.29.1.dist-info/METADATA,sha256=kx_nQDGhcDUJp4DadT7Pi89QsUuf8S5W6IVqwaJfuXM,7174
|
|
59
|
+
sqlsaber-0.29.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
60
|
+
sqlsaber-0.29.1.dist-info/entry_points.txt,sha256=qEbOB7OffXPFgyJc7qEIJlMEX5RN9xdzLmWZa91zCQQ,162
|
|
61
|
+
sqlsaber-0.29.1.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
62
|
+
sqlsaber-0.29.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|