dbagent-cli 0.3.7__tar.gz → 0.3.9__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.
Files changed (74) hide show
  1. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/PKG-INFO +2 -2
  2. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/__init__.py +1 -1
  3. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/cli.py +24 -0
  4. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/ui/console.py +19 -9
  5. dbagent_cli-0.3.9/dbagent/ui/grid_window.py +245 -0
  6. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent_cli.egg-info/PKG-INFO +2 -2
  7. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent_cli.egg-info/SOURCES.txt +1 -0
  8. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/pyproject.toml +2 -2
  9. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/README.md +0 -0
  10. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/agent/confidence.py +0 -0
  11. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/agent/conversation.py +0 -0
  12. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/agent/doctor.py +0 -0
  13. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/agent/error_classifier.py +0 -0
  14. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/agent/generator.py +0 -0
  15. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/agent/pipeline.py +0 -0
  16. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/agent/recommender.py +0 -0
  17. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/agent/validator.py +0 -0
  18. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/config.py +0 -0
  19. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/connectors/base.py +0 -0
  20. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/connectors/factory.py +0 -0
  21. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/connectors/mongo.py +0 -0
  22. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/connectors/relational.py +0 -0
  23. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/execution/__init__.py +0 -0
  24. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/execution/cache.py +0 -0
  25. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/execution/changeset.py +0 -0
  26. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/execution/cost.py +0 -0
  27. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/execution/recovery.py +0 -0
  28. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/execution/sandbox.py +0 -0
  29. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/execution/streaming.py +0 -0
  30. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/llm/auto_setup.py +0 -0
  31. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/llm/base.py +0 -0
  32. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/llm/factory.py +0 -0
  33. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/llm/gemini_provider.py +0 -0
  34. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/llm/groq_provider.py +0 -0
  35. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/llm/mock_provider.py +0 -0
  36. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/llm/ollama_provider.py +0 -0
  37. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/llm/openrouter_provider.py +0 -0
  38. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/schema/cache.py +0 -0
  39. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/schema/formatter.py +0 -0
  40. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/schema/graph.py +0 -0
  41. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/schema/models.py +0 -0
  42. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/schema/retriever.py +0 -0
  43. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/schema/selector.py +0 -0
  44. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/security/__init__.py +0 -0
  45. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/security/audit.py +0 -0
  46. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/security/environment.py +0 -0
  47. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/security/masking.py +0 -0
  48. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/security/modes.py +0 -0
  49. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/security/rbac.py +0 -0
  50. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/semantic/__init__.py +0 -0
  51. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/semantic/dictionary.py +0 -0
  52. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/semantic/templates.py +0 -0
  53. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/sql/__init__.py +0 -0
  54. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/sql/optimizer.py +0 -0
  55. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/sql/validator.py +0 -0
  56. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/ui/viewer.py +0 -0
  57. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent/ui/visualizer.py +0 -0
  58. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent_cli.egg-info/dependency_links.txt +0 -0
  59. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent_cli.egg-info/entry_points.txt +0 -0
  60. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent_cli.egg-info/requires.txt +0 -0
  61. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/dbagent_cli.egg-info/top_level.txt +0 -0
  62. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/setup.cfg +0 -0
  63. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/tests/test_cache.py +0 -0
  64. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/tests/test_cli.py +0 -0
  65. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/tests/test_connectors.py +0 -0
  66. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/tests/test_doctor_and_viz.py +0 -0
  67. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/tests/test_generator.py +0 -0
  68. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/tests/test_graph.py +0 -0
  69. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/tests/test_recovery.py +0 -0
  70. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/tests/test_safety.py +0 -0
  71. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/tests/test_sandbox.py +0 -0
  72. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/tests/test_schema.py +0 -0
  73. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/tests/test_security.py +0 -0
  74. {dbagent_cli-0.3.7 → dbagent_cli-0.3.9}/tests/test_semantic.py +0 -0
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dbagent-cli
3
- Version: 0.3.7
4
- Summary: Production-Grade AI Database Copilot with Seamless Column Scroller (CLI)
3
+ Version: 0.3.9
4
+ Summary: Production-Grade AI Database Copilot with Interactive Desktop & Browser Data Grid Viewers (CLI)
5
5
  Author: Santhosh Gupta
6
6
  Requires-Python: >=3.9
7
7
  Description-Content-Type: text/markdown
@@ -2,5 +2,5 @@
2
2
  DB-Agent: Universal Database Introspection and Script Generation AI Agent (CLI).
3
3
  """
4
4
 
5
- __version__ = "0.3.7"
5
+ __version__ = "0.3.9"
6
6
  __author__ = "Santhosh Gupta"
@@ -60,6 +60,7 @@ from dbagent.ui.console import (
60
60
  open_interactive_scroller,
61
61
  )
62
62
  from dbagent.ui.viewer import SchemaViewer
63
+ from dbagent.ui.grid_window import open_desktop_grid_window, open_browser_grid_window
63
64
 
64
65
  app = typer.Typer(
65
66
  name="db-agent",
@@ -629,6 +630,29 @@ def chat_command(
629
630
  print_results_vertical(last_result.columns, last_result.rows)
630
631
  continue
631
632
 
633
+ if cmd_name in [":wide", ":all", ":raw"]:
634
+ if not last_result or not last_result.rows:
635
+ print_warning("No previous query results to display.")
636
+ continue
637
+ print_results_table(last_result.columns, last_result.rows, title="All Columns (Wide View)", show_all=True)
638
+ continue
639
+
640
+ if cmd_name in [":window", ":gui", ":grid", ":w"]:
641
+ if not last_result or not last_result.rows:
642
+ print_warning("No previous query results to display.")
643
+ continue
644
+ print_info("Opening desktop interactive window with horizontal & vertical scrollbars...")
645
+ open_desktop_grid_window(last_result.columns, last_result.rows, title=f"DB-Agent Data Grid")
646
+ continue
647
+
648
+ if cmd_name in [":web", ":browser", ":html"]:
649
+ if not last_result or not last_result.rows:
650
+ print_warning("No previous query results to display.")
651
+ continue
652
+ print_info("Opening browser interactive data table...")
653
+ open_browser_grid_window(last_result.columns, last_result.rows, title=f"DB-Agent Data View")
654
+ continue
655
+
632
656
  if cmd_name in [":scroll", ":scroller", ":pager"]:
633
657
  if not last_result or not last_result.rows:
634
658
  print_warning("No previous query results to scroll.")
@@ -62,25 +62,35 @@ def print_results_table(
62
62
  rows: List[Dict[str, Any]],
63
63
  title: str = "Results",
64
64
  col_page: int = 1,
65
- cols_per_page: int = 8,
65
+ cols_per_page: Optional[int] = None,
66
+ show_all: bool = False,
66
67
  ) -> None:
67
68
  """
68
- Print query results in a clean, readable Rich table with multi-column horizontal paging.
69
+ Print query results in a clean, readable Rich table.
70
+ Dynamically scales column count based on terminal zoom-out/width.
69
71
  """
70
72
  if not columns or not rows:
71
73
  console.print("[dim]Query returned 0 rows.[/dim]\n")
72
74
  return
73
75
 
74
76
  total_cols = len(columns)
75
- total_pages = max(1, math.ceil(total_cols / cols_per_page))
77
+ term_width = console.width or 120
78
+ auto_cols = max(8, term_width // 16)
79
+
80
+ if show_all or total_cols <= auto_cols:
81
+ effective_cols_per_page = total_cols
82
+ else:
83
+ effective_cols_per_page = cols_per_page or auto_cols
84
+
85
+ total_pages = max(1, math.ceil(total_cols / effective_cols_per_page))
76
86
  current_page = max(1, min(col_page, total_pages))
77
87
 
78
- start_idx = (current_page - 1) * cols_per_page
79
- end_idx = min(start_idx + cols_per_page, total_cols)
80
- display_cols = columns[start_idx:end_idx]
88
+ start_idx = (current_page - 1) * effective_cols_per_page
89
+ end_idx = min(start_idx + effective_cols_per_page, total_cols)
90
+ display_cols = columns if show_all else columns[start_idx:end_idx]
81
91
 
82
92
  tbl_title = f"[bold cyan]{title}[/bold cyan]"
83
- if total_pages > 1:
93
+ if total_pages > 1 and not show_all:
84
94
  tbl_title += f" [dim](Cols {start_idx + 1}–{end_idx} of {total_cols} | Page {current_page}/{total_pages})[/dim]"
85
95
 
86
96
  table = Table(title=tbl_title, show_header=True, header_style="bold magenta", border_style="dim")
@@ -101,9 +111,9 @@ def print_results_table(
101
111
  console.print("")
102
112
  console.print(table)
103
113
 
104
- if total_pages > 1:
114
+ if total_pages > 1 and not show_all:
105
115
  console.print(
106
- f"[dim]⚡ [bold]:page <1-{total_pages}>[/bold] to switch column view | [bold]:card[/bold] for expanded vertical view | [bold]:scroll[/bold] for full scroller[/dim]"
116
+ f"[dim]⚡ [bold]:window[/bold] (GUI scroll window) | [bold]:page <1-{total_pages}>[/bold] | [bold]:card[/bold] (vertical) | [bold]:wide[/bold] (zoom-out)[/dim]"
107
117
  )
108
118
  console.print(f"[bold green]Total rows:[/bold green] {len(rows)}\n")
109
119
 
@@ -0,0 +1,245 @@
1
+ """
2
+ Interactive Desktop and Browser Data Grid Viewers with Horizontal & Vertical Scrollbars.
3
+ """
4
+
5
+ import os
6
+ import tempfile
7
+ import webbrowser
8
+ import threading
9
+ from typing import List, Dict, Any, Optional
10
+
11
+
12
+ def open_desktop_grid_window(
13
+ columns: List[str],
14
+ rows: List[Dict[str, Any]],
15
+ title: str = "DB-Agent Interactive Data Viewer",
16
+ ) -> None:
17
+ """
18
+ Opens a native desktop GUI window with smooth horizontal and vertical scrollbars,
19
+ search/filter bar, and resizable columns. Runs in a separate thread.
20
+ """
21
+ if not columns or not rows:
22
+ return
23
+
24
+ def _launch_gui():
25
+ try:
26
+ import tkinter as tk
27
+ from tkinter import ttk, messagebox, filedialog
28
+ import csv
29
+
30
+ root = tk.Tk()
31
+ root.title(f"{title} - ({len(rows)} rows, {len(columns)} columns)")
32
+ root.geometry("1100x650")
33
+ root.minsize(700, 400)
34
+
35
+ # Modern Styling
36
+ style = ttk.Style()
37
+ try:
38
+ style.theme_use("clam")
39
+ except Exception:
40
+ pass
41
+
42
+ style.configure("Treeview.Heading", font=("Segoe UI", 10, "bold"), background="#2c3e50", foreground="white")
43
+ style.configure("Treeview", font=("Segoe UI", 9), rowheight=24)
44
+ style.map("Treeview", background=[("selected", "#3498db")])
45
+
46
+ # Top toolbar (Search & Export)
47
+ top_frame = ttk.Frame(root, padding=8)
48
+ top_frame.pack(fill=tk.X, side=tk.TOP)
49
+
50
+ ttk.Label(top_frame, text="🔍 Search / Filter:", font=("Segoe UI", 9, "bold")).pack(side=tk.LEFT, padx=(0, 5))
51
+ search_var = tk.StringVar()
52
+ search_entry = ttk.Entry(top_frame, textvariable=search_var, width=30)
53
+ search_entry.pack(side=tk.LEFT, padx=5)
54
+
55
+ status_lbl = ttk.Label(top_frame, text=f"Total: {len(rows)} records, {len(columns)} columns", font=("Segoe UI", 9))
56
+ status_lbl.pack(side=tk.LEFT, padx=15)
57
+
58
+ def _export_csv():
59
+ fpath = filedialog.asksaveasfilename(
60
+ defaultextension=".csv",
61
+ filetypes=[("CSV Files", "*.csv"), ("All Files", "*.*")],
62
+ initialfile="query_results.csv",
63
+ )
64
+ if fpath:
65
+ try:
66
+ with open(fpath, "w", newline="", encoding="utf-8") as f:
67
+ writer = csv.writer(f)
68
+ writer.writerow(columns)
69
+ for r in rows:
70
+ writer.writerow([r.get(c, "") for c in columns])
71
+ messagebox.showinfo("Export Success", f"Exported {len(rows)} rows to:\n{fpath}")
72
+ except Exception as e:
73
+ messagebox.showerror("Export Failed", str(e))
74
+
75
+ export_btn = ttk.Button(top_frame, text="💾 Export to CSV", command=_export_csv)
76
+ export_btn.pack(side=tk.RIGHT, padx=5)
77
+
78
+ # Center Data Grid Frame with Both Scrollbars
79
+ grid_frame = ttk.Frame(root)
80
+ grid_frame.pack(fill=tk.BOTH, expand=True, padx=8, pady=(0, 8))
81
+
82
+ # Vertical Scrollbar
83
+ v_scroll = ttk.Scrollbar(grid_frame, orient=tk.VERTICAL)
84
+ v_scroll.pack(side=tk.RIGHT, fill=tk.Y)
85
+
86
+ # Horizontal Scrollbar
87
+ h_scroll = ttk.Scrollbar(grid_frame, orient=tk.HORIZONTAL)
88
+ h_scroll.pack(side=tk.BOTTOM, fill=tk.X)
89
+
90
+ # Treeview Table
91
+ tree = ttk.Treeview(
92
+ grid_frame,
93
+ columns=columns,
94
+ show="headings",
95
+ yscrollcommand=v_scroll.set,
96
+ xscrollcommand=h_scroll.set,
97
+ )
98
+ v_scroll.config(command=tree.yview)
99
+ h_scroll.config(command=tree.xview)
100
+ tree.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
101
+
102
+ # Configure Columns
103
+ for col in columns:
104
+ tree.heading(col, text=col)
105
+ # Dynamic column width based on column name length
106
+ col_w = max(120, min(280, len(str(col)) * 12))
107
+ tree.column(col, width=col_w, minwidth=80, stretch=False)
108
+
109
+ def populate_table(filter_text=""):
110
+ tree.delete(*tree.get_children())
111
+ f_lower = filter_text.strip().lower()
112
+ count = 0
113
+ for r in rows:
114
+ row_vals = [str(r.get(c, "")) if r.get(c) is not None else "NULL" for c in columns]
115
+ if f_lower:
116
+ if not any(f_lower in v.lower() for v in row_vals):
117
+ continue
118
+ tree.insert("", tk.END, values=row_vals)
119
+ count += 1
120
+ status_lbl.config(text=f"Showing: {count} of {len(rows)} rows ({len(columns)} columns)")
121
+
122
+ populate_table()
123
+
124
+ def on_search_change(*args):
125
+ populate_table(search_var.get())
126
+
127
+ search_var.trace_add("write", on_search_change)
128
+
129
+ root.mainloop()
130
+ except Exception as e:
131
+ print(f"[DB-Agent GUI Error] Could not launch desktop window: {e}")
132
+
133
+ # Launch GUI in background thread so CLI prompt stays responsive
134
+ thread = threading.Thread(target=_launch_gui, daemon=True)
135
+ thread.start()
136
+
137
+
138
+ def open_browser_grid_window(
139
+ columns: List[str],
140
+ rows: List[Dict[str, Any]],
141
+ title: str = "DB-Agent Interactive Data Grid",
142
+ ) -> None:
143
+ """
144
+ Generates a standalone, ultra-fast HTML data grid with frozen headers,
145
+ instant horizontal & vertical scrolling, search, and CSV export, then opens it in browser.
146
+ """
147
+ if not columns or not rows:
148
+ return
149
+
150
+ import json
151
+
152
+ cols_json = json.dumps([{"title": c, "field": c, "headerFilter": "input", "resizable": True} for c in columns])
153
+ data_json = json.dumps(rows, default=str)
154
+
155
+ html_content = f"""<!DOCTYPE html>
156
+ <html lang="en">
157
+ <head>
158
+ <meta charset="UTF-8">
159
+ <title>{title}</title>
160
+ <link href="https://unpkg.com/tabulator-tables@5.5.0/dist/css/tabulator_midnight.min.css" rel="stylesheet">
161
+ <script type="text/javascript" src="https://unpkg.com/tabulator-tables@5.5.0/dist/js/tabulator.min.js"></script>
162
+ <style>
163
+ body {{
164
+ margin: 0;
165
+ padding: 16px;
166
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
167
+ background: #0f172a;
168
+ color: #f8fafc;
169
+ }}
170
+ .header {{
171
+ display: flex;
172
+ justify-content: space-between;
173
+ align-items: center;
174
+ margin-bottom: 12px;
175
+ }}
176
+ h1 {{
177
+ margin: 0;
178
+ font-size: 1.3rem;
179
+ color: #38bdf8;
180
+ }}
181
+ .badge {{
182
+ background: #1e293b;
183
+ padding: 4px 10px;
184
+ border-radius: 6px;
185
+ font-size: 0.85rem;
186
+ color: #94a3b8;
187
+ border: 1px solid #334155;
188
+ }}
189
+ .btn {{
190
+ background: #0284c7;
191
+ color: white;
192
+ border: none;
193
+ padding: 6px 14px;
194
+ border-radius: 6px;
195
+ font-weight: 600;
196
+ cursor: pointer;
197
+ }}
198
+ .btn:hover {{
199
+ background: #0369a1;
200
+ }}
201
+ #data-table {{
202
+ height: calc(100vh - 85px);
203
+ background: #1e293b;
204
+ border-radius: 8px;
205
+ border: 1px solid #334155;
206
+ }}
207
+ </style>
208
+ </head>
209
+ <body>
210
+ <div class="header">
211
+ <div>
212
+ <h1>📊 {title}</h1>
213
+ <span class="badge">{len(rows)} Records &bull; {len(columns)} Columns</span>
214
+ </div>
215
+ <div>
216
+ <button class="btn" onclick="table.download('csv', 'data_export.csv')">💾 Download CSV</button>
217
+ </div>
218
+ </div>
219
+ <div id="data-table"></div>
220
+
221
+ <script>
222
+ const tableData = {data_json};
223
+ const tableCols = {cols_json};
224
+
225
+ const table = new Tabulator("#data-table", {{
226
+ data: tableData,
227
+ columns: tableCols,
228
+ layout: "fitData",
229
+ pagination: false,
230
+ renderVertical: "virtual",
231
+ renderHorizontal: "virtual",
232
+ movableColumns: true,
233
+ responsiveLayout: false,
234
+ }});
235
+ </script>
236
+ </body>
237
+ </html>
238
+ """
239
+
240
+ temp_dir = tempfile.gettempdir()
241
+ temp_path = os.path.join(temp_dir, "dbagent_data_grid.html")
242
+ with open(temp_path, "w", encoding="utf-8") as f:
243
+ f.write(html_content)
244
+
245
+ webbrowser.open(f"file://{temp_path}")
@@ -1,7 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dbagent-cli
3
- Version: 0.3.7
4
- Summary: Production-Grade AI Database Copilot with Seamless Column Scroller (CLI)
3
+ Version: 0.3.9
4
+ Summary: Production-Grade AI Database Copilot with Interactive Desktop & Browser Data Grid Viewers (CLI)
5
5
  Author: Santhosh Gupta
6
6
  Requires-Python: >=3.9
7
7
  Description-Content-Type: text/markdown
@@ -49,6 +49,7 @@ dbagent/sql/__init__.py
49
49
  dbagent/sql/optimizer.py
50
50
  dbagent/sql/validator.py
51
51
  dbagent/ui/console.py
52
+ dbagent/ui/grid_window.py
52
53
  dbagent/ui/viewer.py
53
54
  dbagent/ui/visualizer.py
54
55
  dbagent_cli.egg-info/PKG-INFO
@@ -4,8 +4,8 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "dbagent-cli"
7
- version = "0.3.7"
8
- description = "Production-Grade AI Database Copilot with Seamless Column Scroller (CLI)"
7
+ version = "0.3.9"
8
+ description = "Production-Grade AI Database Copilot with Interactive Desktop & Browser Data Grid Viewers (CLI)"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
11
11
  authors = [
File without changes
File without changes