snowglobe-cli 0.2.0__tar.gz → 0.2.1__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 (83) hide show
  1. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/PKG-INFO +1 -1
  2. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/pyproject.toml +1 -1
  3. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/screens/cost.py +2 -1
  4. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/screens/home.py +23 -12
  5. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/styles.tcss +16 -4
  6. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe_cli.egg-info/PKG-INFO +1 -1
  7. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/LICENSE +0 -0
  8. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/README.md +0 -0
  9. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/setup.cfg +0 -0
  10. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/__init__.py +0 -0
  11. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/__main__.py +0 -0
  12. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/cli/__init__.py +0 -0
  13. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/cli/access.py +0 -0
  14. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/cli/app.py +0 -0
  15. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/cli/context.py +0 -0
  16. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/cli/cost.py +0 -0
  17. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/cli/debug.py +0 -0
  18. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/cli/diff.py +0 -0
  19. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/cli/optimizer.py +0 -0
  20. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/cli/prompts.py +0 -0
  21. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/cli/report.py +0 -0
  22. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/cli/shell.py +0 -0
  23. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/cli/shell_completer.py +0 -0
  24. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/collectors/access.py +0 -0
  25. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/collectors/query_history.py +0 -0
  26. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/collectors/query_profile.py +0 -0
  27. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/config/loader.py +0 -0
  28. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/core/access_service.py +0 -0
  29. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/core/cost_service.py +0 -0
  30. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/core/optimizer.py +0 -0
  31. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/core/query_service.py +0 -0
  32. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/core/report_service.py +0 -0
  33. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/core/risk_service.py +0 -0
  34. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/engines/access/__init__.py +0 -0
  35. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/engines/access/explainer.py +0 -0
  36. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/engines/access/resolver.py +0 -0
  37. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/engines/ai/cortex_optimizer.py +0 -0
  38. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/engines/optimizer/query_optimizer.py +0 -0
  39. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/graphs/__init__.py +0 -0
  40. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/graphs/role_graph.py +0 -0
  41. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/graphs/user_graph.py +0 -0
  42. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/models/__init__.py +0 -0
  43. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/models/access.py +0 -0
  44. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/models/access_path.py +0 -0
  45. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/models/object_ref.py +0 -0
  46. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/models/object_type.py +0 -0
  47. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/models/optimizer.py +0 -0
  48. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/models/privilege.py +0 -0
  49. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/models/query.py +0 -0
  50. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/output/__init__.py +0 -0
  51. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/output/cli.py +0 -0
  52. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/queries/__init__.py +0 -0
  53. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/queries/query_history.py +0 -0
  54. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/snowflake/connection.py +0 -0
  55. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/state/db.py +0 -0
  56. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/state/state.py +0 -0
  57. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/templates/report.md.j2 +0 -0
  58. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tests/access_tests.py +0 -0
  59. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/__init__.py +0 -0
  60. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/__main__.py +0 -0
  61. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/app.py +0 -0
  62. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/screens/__init__.py +0 -0
  63. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/screens/access.py +0 -0
  64. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/screens/refresh.py +0 -0
  65. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/screens/reports.py +0 -0
  66. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/screens/risk.py +0 -0
  67. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/screens/tune.py +0 -0
  68. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/widgets/__init__.py +0 -0
  69. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/widgets/access_paths.py +0 -0
  70. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/widgets/cache_badge.py +0 -0
  71. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/widgets/header.py +0 -0
  72. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe/tui/widgets/nav.py +0 -0
  73. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe_cli.egg-info/SOURCES.txt +0 -0
  74. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe_cli.egg-info/dependency_links.txt +0 -0
  75. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe_cli.egg-info/entry_points.txt +0 -0
  76. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe_cli.egg-info/requires.txt +0 -0
  77. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/snowglobe_cli.egg-info/top_level.txt +0 -0
  78. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/tests/test_access.py +0 -0
  79. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/tests/test_optimizer_engine.py +0 -0
  80. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/tests/test_output.py +0 -0
  81. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/tests/test_query_validation.py +0 -0
  82. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/tests/test_state_db.py +0 -0
  83. {snowglobe_cli-0.2.0 → snowglobe_cli-0.2.1}/tests/test_tui_tune.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: snowglobe-cli
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Explainable cost and access visibility for Snowflake
5
5
  Author-email: Jaryd Thornton <jaryd90@gmail.com>
6
6
  License-Expression: Apache-2.0
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "snowglobe-cli"
3
- version = "0.2.0"
3
+ version = "0.2.1"
4
4
  description = "Explainable cost and access visibility for Snowflake"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12.3"
@@ -562,7 +562,8 @@ class CostScreen(Vertical):
562
562
  self.app.call_from_thread(self._render_day_drill, df, date)
563
563
 
564
564
  def _render_day_drill(self, df: pd.DataFrame, date: str) -> None:
565
- table = self._reset_table()
565
+ self._reset_table()
566
+ table = self.query_one(DataTable)
566
567
  if df is None or df.empty:
567
568
  table.add_columns("(no warehouse activity on this date)")
568
569
  self._set_status(f"{date} · no data · Esc to return")
@@ -46,7 +46,7 @@ class HomeScreen(Vertical):
46
46
  with Vertical(id="home-trend", classes="panel"):
47
47
  yield Static("30d spend trend", classes="panel-title")
48
48
  yield DataTable(id="home-trend-table",
49
- cursor_type="none", zebra_stripes=True)
49
+ cursor_type="row", zebra_stripes=True)
50
50
  with Vertical(id="home-queries", classes="panel"):
51
51
  yield Static("Recent expensive queries (7d)", classes="panel-title")
52
52
  yield DataTable(id="home-queries-table",
@@ -193,6 +193,7 @@ class HomeScreen(Vertical):
193
193
  str(row["DATE"]),
194
194
  f"{credits:,.2f}",
195
195
  "█" * bar_width,
196
+ key=str(row["DATE"]),
196
197
  )
197
198
 
198
199
  # --- Recent expensive queries (one Snowflake call on mount) -----
@@ -229,17 +230,27 @@ class HomeScreen(Vertical):
229
230
  )
230
231
 
231
232
  def on_data_table_row_selected(self, event: DataTable.RowSelected) -> None:
232
- # Drill: open the query in the Tune screen.
233
233
  key = event.row_key.value if event.row_key else None
234
234
  if not key:
235
235
  return
236
- try:
237
- from textual.widgets import ContentSwitcher, Input
238
- from snowglobe.tui.screens.tune import TuneScreen
239
- switcher = self.app.query_one(ContentSwitcher)
240
- switcher.current = "tune"
241
- tune = self.app.query_one(TuneScreen)
242
- tune.query_one("#tu-query-id", Input).value = key
243
- self.app.notify(f"Loaded {key[:24]}… into Tune. Press Analyse.", timeout=4)
244
- except Exception:
245
- self.app.notify(f"Query: {key[:24]}", timeout=4)
236
+
237
+ if event.data_table.id == "home-trend-table":
238
+ # Drill into that day on the Cost screen.
239
+ try:
240
+ from textual.widgets import ContentSwitcher
241
+ from snowglobe.tui.screens.cost import CostScreen
242
+ self.app.query_one(ContentSwitcher).current = "cost"
243
+ self.app.query_one(CostScreen)._fetch_day_drill(key)
244
+ except Exception as e:
245
+ self.app.notify(f"Could not open day detail: {e}", severity="warning", timeout=4)
246
+ else:
247
+ # Queries table — open in Tune.
248
+ try:
249
+ from textual.widgets import ContentSwitcher, Input
250
+ from snowglobe.tui.screens.tune import TuneScreen
251
+ self.app.query_one(ContentSwitcher).current = "tune"
252
+ tune = self.app.query_one(TuneScreen)
253
+ tune.query_one("#tu-query-id", Input).value = key
254
+ self.app.notify(f"Loaded {key[:24]}… into Tune. Press Analyse.", timeout=4)
255
+ except Exception:
256
+ self.app.notify(f"Query: {key[:24]}…", timeout=4)
@@ -365,16 +365,22 @@ Tree > .tree--label-highlighted {
365
365
  margin-right: 1;
366
366
  }
367
367
 
368
- #tu-sql {
368
+ #tu-sql-scroll {
369
369
  height: 1fr;
370
+ }
371
+
372
+ #tu-sql {
370
373
  background: $background;
371
374
  padding: 1;
372
375
  }
373
376
 
377
+ #tu-heuristics-scroll {
378
+ height: 1fr;
379
+ }
380
+
374
381
  #tu-heuristics {
375
382
  padding: 1;
376
383
  color: $foreground;
377
- height: 1fr;
378
384
  }
379
385
 
380
386
  #tu-insights-table,
@@ -388,11 +394,14 @@ Tree > .tree--label-highlighted {
388
394
  height: 1fr;
389
395
  }
390
396
 
397
+ #tu-ai-scroll {
398
+ height: 1fr;
399
+ }
400
+
391
401
  #tu-ai {
392
402
  background: $background;
393
403
  color: $foreground;
394
404
  padding: 1;
395
- height: 1fr;
396
405
  }
397
406
 
398
407
  /* --- Reports screen --- */
@@ -402,8 +411,11 @@ Tree > .tree--label-highlighted {
402
411
  margin-bottom: 1;
403
412
  }
404
413
 
405
- #rp-preview {
414
+ #rp-preview-scroll {
406
415
  height: 1fr;
416
+ }
417
+
418
+ #rp-preview {
407
419
  background: $background;
408
420
  border: round $primary;
409
421
  padding: 1;
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: snowglobe-cli
3
- Version: 0.2.0
3
+ Version: 0.2.1
4
4
  Summary: Explainable cost and access visibility for Snowflake
5
5
  Author-email: Jaryd Thornton <jaryd90@gmail.com>
6
6
  License-Expression: Apache-2.0
File without changes
File without changes
File without changes