shotgun-sh 0.2.10.dev6__py3-none-any.whl → 0.2.10.dev7__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 shotgun-sh might be problematic. Click here for more details.

shotgun/tui/app.py CHANGED
@@ -9,12 +9,16 @@ from shotgun.agents.config import ConfigManager, get_config_manager
9
9
  from shotgun.logging_config import get_logger
10
10
  from shotgun.tui.screens.splash import SplashScreen
11
11
  from shotgun.utils.file_system_utils import get_shotgun_base_path
12
- from shotgun.utils.update_checker import perform_auto_update_async
12
+ from shotgun.utils.update_checker import (
13
+ detect_installation_method,
14
+ perform_auto_update_async,
15
+ )
13
16
 
14
17
  from .screens.chat import ChatScreen
15
18
  from .screens.directory_setup import DirectorySetupScreen
16
19
  from .screens.feedback import FeedbackScreen
17
20
  from .screens.model_picker import ModelPickerScreen
21
+ from .screens.pipx_migration import PipxMigrationScreen
18
22
  from .screens.provider_config import ProviderConfigScreen
19
23
  from .screens.welcome import WelcomeScreen
20
24
 
@@ -56,14 +60,35 @@ class ShotgunApp(App[None]):
56
60
  # Track TUI startup
57
61
  from shotgun.posthog_telemetry import track_event
58
62
 
59
- track_event("tui_started", {})
63
+ track_event(
64
+ "tui_started",
65
+ {
66
+ "installation_method": detect_installation_method(),
67
+ },
68
+ )
60
69
 
61
70
  self.push_screen(
62
71
  SplashScreen(), callback=lambda _arg: self.refresh_startup_screen()
63
72
  )
64
73
 
65
- def refresh_startup_screen(self) -> None:
74
+ def refresh_startup_screen(self, skip_pipx_check: bool = False) -> None:
66
75
  """Push the appropriate screen based on configured providers."""
76
+ # Check for pipx installation and show migration modal first
77
+ if not skip_pipx_check:
78
+ installation_method = detect_installation_method()
79
+ if installation_method == "pipx":
80
+ if isinstance(self.screen, PipxMigrationScreen):
81
+ return
82
+
83
+ # Show pipx migration modal as a blocking modal screen
84
+ self.push_screen(
85
+ PipxMigrationScreen(),
86
+ callback=lambda _arg: self.refresh_startup_screen(
87
+ skip_pipx_check=True
88
+ ),
89
+ )
90
+ return
91
+
67
92
  # Show welcome screen if no providers are configured OR if user hasn't seen it yet
68
93
  config = self.config_manager.load()
69
94
  if (
@@ -0,0 +1,153 @@
1
+ """Migration notice screen for pipx users."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import TYPE_CHECKING
6
+
7
+ from textual import on
8
+ from textual.app import ComposeResult
9
+ from textual.containers import Container, Horizontal, VerticalScroll
10
+ from textual.screen import ModalScreen
11
+ from textual.widgets import Button, Markdown
12
+
13
+ if TYPE_CHECKING:
14
+ pass
15
+
16
+
17
+ class PipxMigrationScreen(ModalScreen[None]):
18
+ """Modal screen warning pipx users about migration to uvx."""
19
+
20
+ CSS = """
21
+ PipxMigrationScreen {
22
+ align: center middle;
23
+ }
24
+
25
+ #migration-container {
26
+ width: 90;
27
+ height: auto;
28
+ max-height: 90%;
29
+ border: thick $error;
30
+ background: $surface;
31
+ padding: 2;
32
+ }
33
+
34
+ #migration-content {
35
+ height: 1fr;
36
+ padding: 1 0;
37
+ }
38
+
39
+ #buttons-container {
40
+ height: auto;
41
+ padding: 2 0 1 0;
42
+ }
43
+
44
+ #action-buttons {
45
+ width: 100%;
46
+ height: auto;
47
+ align: center middle;
48
+ }
49
+
50
+ .action-button {
51
+ margin: 0 1;
52
+ min-width: 20;
53
+ }
54
+ """
55
+
56
+ BINDINGS = [
57
+ ("escape", "dismiss", "Continue Anyway"),
58
+ ("ctrl+c", "app.quit", "Quit"),
59
+ ]
60
+
61
+ def compose(self) -> ComposeResult:
62
+ """Compose the migration notice modal."""
63
+ with Container(id="migration-container"):
64
+ with VerticalScroll(id="migration-content"):
65
+ yield Markdown(
66
+ """
67
+ ## We've Switched to uvx
68
+
69
+ We've switched from `pipx` to `uvx` as the primary installation method due to critical build issues with our `kuzu` dependency.
70
+
71
+ ### The Problem
72
+ Users with pipx encounter cmake build errors during installation because pip falls back to building from source instead of using pre-built binary wheels.
73
+
74
+ ### The Solution: uvx
75
+ - ✅ **No build tools required** - Binary wheels enforced
76
+ - ✅ **10-100x faster** - Much faster than pipx
77
+ - ✅ **Better reliability** - No cmake/build errors
78
+
79
+ ### How to Migrate
80
+
81
+ **1. Uninstall shotgun-sh from pipx:**
82
+ ```bash
83
+ pipx uninstall shotgun-sh
84
+ ```
85
+
86
+ **2. Install uv:**
87
+ ```bash
88
+ curl -LsSf https://astral.sh/uv/install.sh | sh
89
+ ```
90
+ Or with Homebrew: `brew install uv`
91
+
92
+ **3. Run shotgun-sh with uvx:**
93
+ ```bash
94
+ uvx shotgun-sh
95
+ ```
96
+ Or install permanently: `uv tool install shotgun-sh`
97
+
98
+ ---
99
+
100
+ ### Need Help?
101
+
102
+ **Discord:** https://discord.gg/5RmY6J2N7s
103
+
104
+ **Full Migration Guide:** https://github.com/shotgun-sh/shotgun-sdk/blob/main/PIPX_MIGRATION.md
105
+ """
106
+ )
107
+
108
+ with Container(id="buttons-container"):
109
+ with Horizontal(id="action-buttons"):
110
+ yield Button(
111
+ "Copy Instructions to Clipboard",
112
+ variant="default",
113
+ id="copy-instructions",
114
+ classes="action-button",
115
+ )
116
+ yield Button(
117
+ "Continue Anyway",
118
+ variant="primary",
119
+ id="continue",
120
+ classes="action-button",
121
+ )
122
+
123
+ def on_mount(self) -> None:
124
+ """Focus the continue button and ensure scroll starts at top."""
125
+ self.query_one("#continue", Button).focus()
126
+ self.query_one("#migration-content", VerticalScroll).scroll_home(animate=False)
127
+
128
+ @on(Button.Pressed, "#copy-instructions")
129
+ def _copy_instructions(self) -> None:
130
+ """Copy all migration instructions to clipboard."""
131
+ instructions = """# Step 1: Uninstall from pipx
132
+ pipx uninstall shotgun-sh
133
+
134
+ # Step 2: Install uv
135
+ curl -LsSf https://astral.sh/uv/install.sh | sh
136
+
137
+ # Step 3: Run shotgun with uvx
138
+ uvx shotgun-sh"""
139
+ try:
140
+ import pyperclip # type: ignore[import-untyped] # noqa: PGH003
141
+
142
+ pyperclip.copy(instructions)
143
+ self.notify("Copied migration instructions to clipboard!")
144
+ except ImportError:
145
+ self.notify(
146
+ "Clipboard not available. See instructions above.",
147
+ severity="warning",
148
+ )
149
+
150
+ @on(Button.Pressed, "#continue")
151
+ def _continue(self) -> None:
152
+ """Dismiss the modal and continue."""
153
+ self.dismiss()
@@ -1,5 +1,6 @@
1
1
  """Simple auto-update functionality for shotgun-sh CLI."""
2
2
 
3
+ import os
3
4
  import subprocess
4
5
  import sys
5
6
  import threading
@@ -20,6 +21,11 @@ def detect_installation_method() -> str:
20
21
  Returns:
21
22
  Installation method: 'uvx', 'uv-tool', 'pipx', 'pip', 'venv', or 'unknown'.
22
23
  """
24
+ # Check for simulation environment variable (for testing)
25
+ if os.getenv("PIPX_SIMULATE", "").lower() in ("true", "1"):
26
+ logger.debug("PIPX_SIMULATE enabled, simulating pipx installation")
27
+ return "pipx"
28
+
23
29
  # Check for uvx (ephemeral execution) by looking at executable path
24
30
  # uvx runs from a temporary cache directory
25
31
  executable = Path(sys.executable)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shotgun-sh
3
- Version: 0.2.10.dev6
3
+ Version: 0.2.10.dev7
4
4
  Summary: AI-powered research, planning, and task management CLI tool
5
5
  Project-URL: Homepage, https://shotgun.sh/
6
6
  Project-URL: Repository, https://github.com/shotgun-sh/shotgun
@@ -119,7 +119,7 @@ shotgun/shotgun_web/client.py,sha256=n5DDuVfSa6VPZjhSsfSxQlSFOnhgDHyidRnB8Hv9XF4
119
119
  shotgun/shotgun_web/constants.py,sha256=eNvtjlu81bAVQaCwZXOVjSpDopUm9pf34XuZEvuMiko,661
120
120
  shotgun/shotgun_web/models.py,sha256=Ie9VfqKZM2tIJhIjentU9qLoNaMZvnUJaIu-xg9kQsA,1391
121
121
  shotgun/tui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
122
- shotgun/tui/app.py,sha256=DwHBJO4PI5qykOb-nmiU3WJRxCeu1e80qPVE_GHn4Fo,9759
122
+ shotgun/tui/app.py,sha256=I4rPtHIp_XiO4Vy3TQe3Rjfp20xHkxDvijdlY7x6wi8,10636
123
123
  shotgun/tui/filtered_codebase_service.py,sha256=lJ8gTMhIveTatmvmGLP299msWWTkVYKwvY_2FhuL2s4,1687
124
124
  shotgun/tui/styles.tcss,sha256=ETyyw1bpMBOqTi5RLcAJUScdPWTvAWEqE9YcT0kVs_E,121
125
125
  shotgun/tui/commands/__init__.py,sha256=8D5lvtpqMW5-fF7Bg3oJtUzU75cKOv6aUaHYYszydU8,2518
@@ -132,6 +132,7 @@ shotgun/tui/screens/chat.tcss,sha256=2Yq3E23jxsySYsgZf4G1AYrYVcpX0UDW6kNNI0tDmtM
132
132
  shotgun/tui/screens/directory_setup.py,sha256=lIZ1J4A6g5Q2ZBX8epW7BhR96Dmdcg22CyiM5S-I5WU,3237
133
133
  shotgun/tui/screens/feedback.py,sha256=VxpW0PVxMp22ZvSfQkTtgixNrpEOlfWtekjqlVfYEjA,5708
134
134
  shotgun/tui/screens/model_picker.py,sha256=G-EvalpxgHKk0W3FgHMcxIr817VwZyEgh_ZadSQiRwo,11831
135
+ shotgun/tui/screens/pipx_migration.py,sha256=Tsm650AT80aaP1nBeMj32UI-zZXNEu8xlbu1NZY3ha8,4325
135
136
  shotgun/tui/screens/provider_config.py,sha256=UCnAzjXPoP7Y73gsXxZF2PNA4LdSgpgoGYwiOd6fERA,10902
136
137
  shotgun/tui/screens/shotgun_auth.py,sha256=Y--7LZewV6gfDkucxymfAO7BCd7eI2C3H1ClDMztVio,10663
137
138
  shotgun/tui/screens/splash.py,sha256=E2MsJihi3c9NY1L28o_MstDxGwrCnnV7zdq00MrGAsw,706
@@ -147,9 +148,9 @@ shotgun/utils/datetime_utils.py,sha256=x_uYmG1n9rkhSO2oR2uV9ttiuPL0nKa9os8YYaPfd
147
148
  shotgun/utils/env_utils.py,sha256=ulM3BRi9ZhS7uC-zorGeDQm4SHvsyFuuU9BtVPqdrHY,1418
148
149
  shotgun/utils/file_system_utils.py,sha256=l-0p1bEHF34OU19MahnRFdClHufThfGAjQ431teAIp0,1004
149
150
  shotgun/utils/source_detection.py,sha256=Co6Q03R3fT771TF3RzB-70stfjNP2S4F_ArZKibwzm8,454
150
- shotgun/utils/update_checker.py,sha256=CAEnZ7_ZOazf_7tfyCAGGf4cW6N2dmwZekLNynHsg2c,9425
151
- shotgun_sh-0.2.10.dev6.dist-info/METADATA,sha256=EGhWKATi4BzTfMnG1eoxLNdD2suwtxONTKGtK2Rx0JU,4670
152
- shotgun_sh-0.2.10.dev6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
153
- shotgun_sh-0.2.10.dev6.dist-info/entry_points.txt,sha256=asZxLU4QILneq0MWW10saVCZc4VWhZfb0wFZvERnzfA,45
154
- shotgun_sh-0.2.10.dev6.dist-info/licenses/LICENSE,sha256=YebsZl590zCHrF_acCU5pmNt0pnAfD2DmAnevJPB1tY,1065
155
- shotgun_sh-0.2.10.dev6.dist-info/RECORD,,
151
+ shotgun/utils/update_checker.py,sha256=5pK9ZXEjgnE-BQLvibm9Fj6SJHVYeG0U-WspRf0bJec,9660
152
+ shotgun_sh-0.2.10.dev7.dist-info/METADATA,sha256=74Klt0giHmh_Z-lbkc4ed7aj0YOPMSLowPZj2Ai0Gzw,4670
153
+ shotgun_sh-0.2.10.dev7.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
154
+ shotgun_sh-0.2.10.dev7.dist-info/entry_points.txt,sha256=GQmtjKaPtviqYOuB3C0SMGlG5RZS9-VDDIKxV_IVHmY,75
155
+ shotgun_sh-0.2.10.dev7.dist-info/licenses/LICENSE,sha256=YebsZl590zCHrF_acCU5pmNt0pnAfD2DmAnevJPB1tY,1065
156
+ shotgun_sh-0.2.10.dev7.dist-info/RECORD,,
@@ -1,2 +1,3 @@
1
1
  [console_scripts]
2
2
  shotgun = shotgun.main:app
3
+ shotgun-sh = shotgun.main:app