shotgun-sh 0.2.1.dev3__py3-none-any.whl → 0.2.1.dev4__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/agents/config/manager.py +22 -6
- shotgun/agents/config/provider.py +2 -1
- shotgun/tui/app.py +5 -3
- shotgun/tui/screens/chat_screen/command_providers.py +6 -4
- shotgun/tui/screens/model_picker.py +92 -17
- shotgun/tui/screens/provider_config.py +7 -0
- {shotgun_sh-0.2.1.dev3.dist-info → shotgun_sh-0.2.1.dev4.dist-info}/METADATA +1 -1
- {shotgun_sh-0.2.1.dev3.dist-info → shotgun_sh-0.2.1.dev4.dist-info}/RECORD +11 -11
- {shotgun_sh-0.2.1.dev3.dist-info → shotgun_sh-0.2.1.dev4.dist-info}/WHEEL +0 -0
- {shotgun_sh-0.2.1.dev3.dist-info → shotgun_sh-0.2.1.dev4.dist-info}/entry_points.txt +0 -0
- {shotgun_sh-0.2.1.dev3.dist-info → shotgun_sh-0.2.1.dev4.dist-info}/licenses/LICENSE +0 -0
shotgun/agents/config/manager.py
CHANGED
|
@@ -46,13 +46,16 @@ class ConfigManager:
|
|
|
46
46
|
|
|
47
47
|
self._config: ShotgunConfig | None = None
|
|
48
48
|
|
|
49
|
-
def load(self) -> ShotgunConfig:
|
|
49
|
+
def load(self, force_reload: bool = True) -> ShotgunConfig:
|
|
50
50
|
"""Load configuration from file.
|
|
51
51
|
|
|
52
|
+
Args:
|
|
53
|
+
force_reload: If True, reload from disk even if cached (default: True)
|
|
54
|
+
|
|
52
55
|
Returns:
|
|
53
56
|
ShotgunConfig: Loaded configuration or default config if file doesn't exist
|
|
54
57
|
"""
|
|
55
|
-
if self._config is not None:
|
|
58
|
+
if self._config is not None and not force_reload:
|
|
56
59
|
return self._config
|
|
57
60
|
|
|
58
61
|
if not self.config_path.exists():
|
|
@@ -243,7 +246,8 @@ class ConfigManager:
|
|
|
243
246
|
|
|
244
247
|
This checks only the configuration file.
|
|
245
248
|
"""
|
|
246
|
-
|
|
249
|
+
# Use force_reload=False to avoid infinite loop when called from load()
|
|
250
|
+
config = self.load(force_reload=False)
|
|
247
251
|
provider_enum = self._ensure_provider_enum(provider)
|
|
248
252
|
provider_config = self._get_provider_config(config, provider_enum)
|
|
249
253
|
|
|
@@ -251,7 +255,8 @@ class ConfigManager:
|
|
|
251
255
|
|
|
252
256
|
def has_any_provider_key(self) -> bool:
|
|
253
257
|
"""Determine whether any provider has a configured API key."""
|
|
254
|
-
|
|
258
|
+
# Use force_reload=False to avoid infinite loop when called from load()
|
|
259
|
+
config = self.load(force_reload=False)
|
|
255
260
|
# Check LLM provider keys (BYOK)
|
|
256
261
|
has_llm_key = any(
|
|
257
262
|
self._provider_has_api_key(self._get_provider_config(config, provider))
|
|
@@ -381,6 +386,17 @@ class ConfigManager:
|
|
|
381
386
|
return config.user_id
|
|
382
387
|
|
|
383
388
|
|
|
389
|
+
# Global singleton instance
|
|
390
|
+
_config_manager_instance: ConfigManager | None = None
|
|
391
|
+
|
|
392
|
+
|
|
384
393
|
def get_config_manager() -> ConfigManager:
|
|
385
|
-
"""Get the global ConfigManager instance.
|
|
386
|
-
|
|
394
|
+
"""Get the global singleton ConfigManager instance.
|
|
395
|
+
|
|
396
|
+
Returns:
|
|
397
|
+
The singleton ConfigManager instance
|
|
398
|
+
"""
|
|
399
|
+
global _config_manager_instance
|
|
400
|
+
if _config_manager_instance is None:
|
|
401
|
+
_config_manager_instance = ConfigManager()
|
|
402
|
+
return _config_manager_instance
|
|
@@ -139,7 +139,8 @@ def get_provider_model(
|
|
|
139
139
|
ValueError: If provider is not configured properly or model not found
|
|
140
140
|
"""
|
|
141
141
|
config_manager = get_config_manager()
|
|
142
|
-
config
|
|
142
|
+
# Use cached config for read-only access (performance)
|
|
143
|
+
config = config_manager.load(force_reload=False)
|
|
143
144
|
|
|
144
145
|
# Priority 1: Check if Shotgun key exists - if so, use it for ANY model
|
|
145
146
|
shotgun_api_key = _get_api_key(config.shotgun.api_key)
|
shotgun/tui/app.py
CHANGED
|
@@ -64,7 +64,8 @@ class ShotgunApp(App[None]):
|
|
|
64
64
|
return
|
|
65
65
|
|
|
66
66
|
self.push_screen(
|
|
67
|
-
|
|
67
|
+
ProviderConfigScreen(),
|
|
68
|
+
callback=lambda _arg: self.refresh_startup_screen(),
|
|
68
69
|
)
|
|
69
70
|
return
|
|
70
71
|
|
|
@@ -73,7 +74,8 @@ class ShotgunApp(App[None]):
|
|
|
73
74
|
return
|
|
74
75
|
|
|
75
76
|
self.push_screen(
|
|
76
|
-
|
|
77
|
+
DirectorySetupScreen(),
|
|
78
|
+
callback=lambda _arg: self.refresh_startup_screen(),
|
|
77
79
|
)
|
|
78
80
|
return
|
|
79
81
|
|
|
@@ -110,7 +112,7 @@ class ShotgunApp(App[None]):
|
|
|
110
112
|
submit_feedback_survey(feedback)
|
|
111
113
|
self.notify("Feedback sent. Thank you!")
|
|
112
114
|
|
|
113
|
-
self.push_screen(
|
|
115
|
+
self.push_screen(FeedbackScreen(), callback=handle_feedback)
|
|
114
116
|
|
|
115
117
|
|
|
116
118
|
def run(no_update_check: bool = False, continue_session: bool = False) -> None:
|
|
@@ -5,6 +5,8 @@ from textual.command import DiscoveryHit, Hit, Provider
|
|
|
5
5
|
|
|
6
6
|
from shotgun.agents.models import AgentType
|
|
7
7
|
from shotgun.codebase.models import CodebaseGraph
|
|
8
|
+
from shotgun.tui.screens.model_picker import ModelPickerScreen
|
|
9
|
+
from shotgun.tui.screens.provider_config import ProviderConfigScreen
|
|
8
10
|
|
|
9
11
|
if TYPE_CHECKING:
|
|
10
12
|
from shotgun.tui.screens.chat import ChatScreen
|
|
@@ -139,11 +141,11 @@ class ProviderSetupProvider(Provider):
|
|
|
139
141
|
|
|
140
142
|
def open_provider_config(self) -> None:
|
|
141
143
|
"""Show the provider configuration screen."""
|
|
142
|
-
self.chat_screen.app.push_screen(
|
|
144
|
+
self.chat_screen.app.push_screen(ProviderConfigScreen())
|
|
143
145
|
|
|
144
146
|
def open_model_picker(self) -> None:
|
|
145
147
|
"""Show the model picker screen."""
|
|
146
|
-
self.chat_screen.app.push_screen(
|
|
148
|
+
self.chat_screen.app.push_screen(ModelPickerScreen())
|
|
147
149
|
|
|
148
150
|
async def discover(self) -> AsyncGenerator[DiscoveryHit, None]:
|
|
149
151
|
yield DiscoveryHit(
|
|
@@ -282,11 +284,11 @@ class UnifiedCommandProvider(Provider):
|
|
|
282
284
|
|
|
283
285
|
def open_provider_config(self) -> None:
|
|
284
286
|
"""Show the provider configuration screen."""
|
|
285
|
-
self.chat_screen.app.push_screen(
|
|
287
|
+
self.chat_screen.app.push_screen(ProviderConfigScreen())
|
|
286
288
|
|
|
287
289
|
def open_model_picker(self) -> None:
|
|
288
290
|
"""Show the model picker screen."""
|
|
289
|
-
self.chat_screen.app.push_screen(
|
|
291
|
+
self.chat_screen.app.push_screen(ModelPickerScreen())
|
|
290
292
|
|
|
291
293
|
async def discover(self) -> AsyncGenerator[DiscoveryHit, None]:
|
|
292
294
|
"""Provide commands in alphabetical order when palette opens."""
|
|
@@ -12,11 +12,14 @@ from textual.screen import Screen
|
|
|
12
12
|
from textual.widgets import Button, Label, ListItem, ListView, Static
|
|
13
13
|
|
|
14
14
|
from shotgun.agents.config import ConfigManager
|
|
15
|
-
from shotgun.agents.config.models import MODEL_SPECS, ModelName
|
|
15
|
+
from shotgun.agents.config.models import MODEL_SPECS, ModelName, ShotgunConfig
|
|
16
|
+
from shotgun.logging_config import get_logger
|
|
16
17
|
|
|
17
18
|
if TYPE_CHECKING:
|
|
18
19
|
from ..app import ShotgunApp
|
|
19
20
|
|
|
21
|
+
logger = get_logger(__name__)
|
|
22
|
+
|
|
20
23
|
|
|
21
24
|
# Available models for selection
|
|
22
25
|
AVAILABLE_MODELS = list(ModelName)
|
|
@@ -82,20 +85,52 @@ class ModelPickerScreen(Screen[None]):
|
|
|
82
85
|
"Select the AI model you want to use for your tasks.",
|
|
83
86
|
id="model-picker-summary",
|
|
84
87
|
)
|
|
85
|
-
yield ListView(
|
|
88
|
+
yield ListView(id="model-list")
|
|
86
89
|
with Horizontal(id="model-actions"):
|
|
87
90
|
yield Button("Select \\[ENTER]", variant="primary", id="select")
|
|
88
91
|
yield Button("Done \\[ESC]", id="done")
|
|
89
92
|
|
|
90
|
-
def
|
|
91
|
-
|
|
93
|
+
def _rebuild_model_list(self) -> None:
|
|
94
|
+
"""Rebuild the model list from current config.
|
|
95
|
+
|
|
96
|
+
This method is called both on first show and when screen is resumed
|
|
97
|
+
to ensure the list always reflects the current configuration.
|
|
98
|
+
"""
|
|
99
|
+
logger.debug("Rebuilding model list from current config")
|
|
100
|
+
|
|
101
|
+
# Load current config with force_reload to get latest API keys
|
|
92
102
|
config_manager = self.config_manager
|
|
93
|
-
config = config_manager.load()
|
|
103
|
+
config = config_manager.load(force_reload=True)
|
|
104
|
+
|
|
105
|
+
# Log provider key status
|
|
106
|
+
logger.debug(
|
|
107
|
+
"Provider keys: openai=%s, anthropic=%s, google=%s, shotgun=%s",
|
|
108
|
+
config_manager._provider_has_api_key(config.openai),
|
|
109
|
+
config_manager._provider_has_api_key(config.anthropic),
|
|
110
|
+
config_manager._provider_has_api_key(config.google),
|
|
111
|
+
config_manager._provider_has_api_key(config.shotgun),
|
|
112
|
+
)
|
|
113
|
+
|
|
94
114
|
current_model = config.selected_model or ModelName.CLAUDE_SONNET_4_5
|
|
95
115
|
self.selected_model = current_model
|
|
116
|
+
logger.debug("Current selected model: %s", current_model)
|
|
96
117
|
|
|
97
|
-
#
|
|
118
|
+
# Rebuild the model list with current available models
|
|
98
119
|
list_view = self.query_one(ListView)
|
|
120
|
+
|
|
121
|
+
# Remove all existing items
|
|
122
|
+
old_count = len(list(list_view.children))
|
|
123
|
+
for child in list(list_view.children):
|
|
124
|
+
child.remove()
|
|
125
|
+
logger.debug("Removed %d existing model items from list", old_count)
|
|
126
|
+
|
|
127
|
+
# Add new items (labels already have correct text including current indicator)
|
|
128
|
+
new_items = self._build_model_items(config)
|
|
129
|
+
for item in new_items:
|
|
130
|
+
list_view.append(item)
|
|
131
|
+
logger.debug("Added %d available model items to list", len(new_items))
|
|
132
|
+
|
|
133
|
+
# Find and highlight current selection (if it's in the filtered list)
|
|
99
134
|
if list_view.children:
|
|
100
135
|
for i, child in enumerate(list_view.children):
|
|
101
136
|
if isinstance(child, ListItem) and child.id:
|
|
@@ -106,7 +141,20 @@ class ModelPickerScreen(Screen[None]):
|
|
|
106
141
|
if model_name == current_model:
|
|
107
142
|
list_view.index = i
|
|
108
143
|
break
|
|
109
|
-
|
|
144
|
+
|
|
145
|
+
def on_show(self) -> None:
|
|
146
|
+
"""Rebuild model list when screen is first shown."""
|
|
147
|
+
logger.debug("ModelPickerScreen.on_show() called")
|
|
148
|
+
self._rebuild_model_list()
|
|
149
|
+
|
|
150
|
+
def on_screenresume(self) -> None:
|
|
151
|
+
"""Rebuild model list when screen is resumed (subsequent visits).
|
|
152
|
+
|
|
153
|
+
This is called when returning to the screen after it was suspended,
|
|
154
|
+
ensuring the model list reflects any config changes made while away.
|
|
155
|
+
"""
|
|
156
|
+
logger.debug("ModelPickerScreen.on_screenresume() called")
|
|
157
|
+
self._rebuild_model_list()
|
|
110
158
|
|
|
111
159
|
def action_done(self) -> None:
|
|
112
160
|
self.dismiss()
|
|
@@ -138,13 +186,19 @@ class ModelPickerScreen(Screen[None]):
|
|
|
138
186
|
return app.config_manager
|
|
139
187
|
|
|
140
188
|
def refresh_model_labels(self) -> None:
|
|
141
|
-
"""Update the list view entries to reflect current selection.
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
)
|
|
189
|
+
"""Update the list view entries to reflect current selection.
|
|
190
|
+
|
|
191
|
+
Note: This method only updates labels for currently displayed models.
|
|
192
|
+
To rebuild the entire list after provider changes, on_show() should be used.
|
|
193
|
+
"""
|
|
194
|
+
# Load config once with force_reload
|
|
195
|
+
config = self.config_manager.load(force_reload=True)
|
|
196
|
+
current_model = config.selected_model or ModelName.CLAUDE_SONNET_4_5
|
|
197
|
+
|
|
145
198
|
# Update labels for available models only
|
|
146
199
|
for model_name in AVAILABLE_MODELS:
|
|
147
|
-
|
|
200
|
+
# Pass config to avoid multiple force reloads
|
|
201
|
+
if not self._is_model_available(model_name, config):
|
|
148
202
|
continue
|
|
149
203
|
label = self.query_one(
|
|
150
204
|
f"#label-{_sanitize_model_name_for_id(model_name)}", Label
|
|
@@ -153,12 +207,15 @@ class ModelPickerScreen(Screen[None]):
|
|
|
153
207
|
self._model_label(model_name, is_current=model_name == current_model)
|
|
154
208
|
)
|
|
155
209
|
|
|
156
|
-
def _build_model_items(self) -> list[ListItem]:
|
|
210
|
+
def _build_model_items(self, config: ShotgunConfig | None = None) -> list[ListItem]:
|
|
211
|
+
if config is None:
|
|
212
|
+
config = self.config_manager.load(force_reload=True)
|
|
213
|
+
|
|
157
214
|
items: list[ListItem] = []
|
|
158
215
|
current_model = self.selected_model
|
|
159
216
|
for model_name in AVAILABLE_MODELS:
|
|
160
217
|
# Only add models that are available
|
|
161
|
-
if not self._is_model_available(model_name):
|
|
218
|
+
if not self._is_model_available(model_name, config):
|
|
162
219
|
continue
|
|
163
220
|
|
|
164
221
|
label = Label(
|
|
@@ -181,7 +238,9 @@ class ModelPickerScreen(Screen[None]):
|
|
|
181
238
|
return model_name
|
|
182
239
|
return None
|
|
183
240
|
|
|
184
|
-
def _is_model_available(
|
|
241
|
+
def _is_model_available(
|
|
242
|
+
self, model_name: ModelName, config: ShotgunConfig | None = None
|
|
243
|
+
) -> bool:
|
|
185
244
|
"""Check if a model is available based on provider key configuration.
|
|
186
245
|
|
|
187
246
|
A model is available if:
|
|
@@ -190,22 +249,38 @@ class ModelPickerScreen(Screen[None]):
|
|
|
190
249
|
|
|
191
250
|
Args:
|
|
192
251
|
model_name: The model to check availability for
|
|
252
|
+
config: Optional pre-loaded config to avoid multiple reloads
|
|
193
253
|
|
|
194
254
|
Returns:
|
|
195
255
|
True if the model can be used, False otherwise
|
|
196
256
|
"""
|
|
197
|
-
config
|
|
257
|
+
if config is None:
|
|
258
|
+
config = self.config_manager.load(force_reload=True)
|
|
198
259
|
|
|
199
260
|
# If Shotgun Account is configured, all models are available
|
|
200
261
|
if self.config_manager._provider_has_api_key(config.shotgun):
|
|
262
|
+
logger.debug("Model %s available (Shotgun Account configured)", model_name)
|
|
201
263
|
return True
|
|
202
264
|
|
|
203
265
|
# In BYOK mode, check if the model's provider has a key
|
|
204
266
|
if model_name not in MODEL_SPECS:
|
|
267
|
+
logger.debug("Model %s not available (not in MODEL_SPECS)", model_name)
|
|
205
268
|
return False
|
|
206
269
|
|
|
207
270
|
spec = MODEL_SPECS[model_name]
|
|
208
|
-
|
|
271
|
+
# Check provider key directly using the loaded config to avoid stale cache
|
|
272
|
+
provider_config = self.config_manager._get_provider_config(
|
|
273
|
+
config, spec.provider
|
|
274
|
+
)
|
|
275
|
+
has_key = self.config_manager._provider_has_api_key(provider_config)
|
|
276
|
+
logger.debug(
|
|
277
|
+
"Model %s available=%s (provider=%s, has_key=%s)",
|
|
278
|
+
model_name,
|
|
279
|
+
has_key,
|
|
280
|
+
spec.provider,
|
|
281
|
+
has_key,
|
|
282
|
+
)
|
|
283
|
+
return has_key
|
|
209
284
|
|
|
210
285
|
def _model_label(self, model_name: ModelName, is_current: bool) -> str:
|
|
211
286
|
"""Generate label for model with specs and current indicator."""
|
|
@@ -119,6 +119,13 @@ class ProviderConfigScreen(Screen[None]):
|
|
|
119
119
|
self.selected_provider = "openai"
|
|
120
120
|
self.set_focus(self.query_one("#api-key", Input))
|
|
121
121
|
|
|
122
|
+
def on_screenresume(self) -> None:
|
|
123
|
+
"""Refresh provider status when screen is resumed.
|
|
124
|
+
|
|
125
|
+
This ensures the UI reflects any provider changes made elsewhere.
|
|
126
|
+
"""
|
|
127
|
+
self.refresh_provider_status()
|
|
128
|
+
|
|
122
129
|
def action_done(self) -> None:
|
|
123
130
|
self.dismiss()
|
|
124
131
|
|
|
@@ -22,9 +22,9 @@ shotgun/agents/tasks.py,sha256=nk8zIl24o01hfzOGyWSbeVWeke6OGseO4Ppciurh13U,2999
|
|
|
22
22
|
shotgun/agents/usage_manager.py,sha256=5d9JC4_cthXwhTSytMfMExMDAUYp8_nkPepTJZXk13w,5017
|
|
23
23
|
shotgun/agents/config/__init__.py,sha256=Fl8K_81zBpm-OfOW27M_WWLSFdaHHek6lWz95iDREjQ,318
|
|
24
24
|
shotgun/agents/config/constants.py,sha256=I3f0ueoQaTg5HddXGCYimCYpj-U57z3IBQYIVJxVIhg,872
|
|
25
|
-
shotgun/agents/config/manager.py,sha256=
|
|
25
|
+
shotgun/agents/config/manager.py,sha256=2QBpaWBV3WAqZR-wFHE9Ufwen05KHQbEkPzjSb3r_V0,15140
|
|
26
26
|
shotgun/agents/config/models.py,sha256=ZojhfheNO337e1icy_cE2PpBXIl5oHkdajr4azzFF-U,5106
|
|
27
|
-
shotgun/agents/config/provider.py,sha256=
|
|
27
|
+
shotgun/agents/config/provider.py,sha256=TwwZC_BtYSOpN2jdX6WZdor29EnAqfMoQK5GmNEYaPI,11012
|
|
28
28
|
shotgun/agents/history/__init__.py,sha256=XFQj2a6fxDqVg0Q3juvN9RjV_RJbgvFZtQOCOjVJyp4,147
|
|
29
29
|
shotgun/agents/history/compaction.py,sha256=9RMpG0aY_7L4TecbgwHSOkGtbd9W5XZTg-MbzZmNl00,3515
|
|
30
30
|
shotgun/agents/history/constants.py,sha256=yWY8rrTZarLA3flCCMB_hS2NMvUDRDTwP4D4j7MIh1w,446
|
|
@@ -114,7 +114,7 @@ shotgun/sdk/exceptions.py,sha256=qBcQv0v7ZTwP7CMcxZST4GqCsfOWtOUjSzGBo0-heqo,412
|
|
|
114
114
|
shotgun/sdk/models.py,sha256=X9nOTUHH0cdkQW1NfnMEDu-QgK9oUsEISh1Jtwr5Am4,5496
|
|
115
115
|
shotgun/sdk/services.py,sha256=J4PJFSxCQ6--u7rb3Ta-9eYtlYcxcbnzrMP6ThyCnw4,705
|
|
116
116
|
shotgun/tui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
117
|
-
shotgun/tui/app.py,sha256=
|
|
117
|
+
shotgun/tui/app.py,sha256=sBPviBs-3niD8rDoD0wC27lfBsKRbFYMUPttOwmDzOM,5139
|
|
118
118
|
shotgun/tui/filtered_codebase_service.py,sha256=lJ8gTMhIveTatmvmGLP299msWWTkVYKwvY_2FhuL2s4,1687
|
|
119
119
|
shotgun/tui/styles.tcss,sha256=ETyyw1bpMBOqTi5RLcAJUScdPWTvAWEqE9YcT0kVs_E,121
|
|
120
120
|
shotgun/tui/commands/__init__.py,sha256=8D5lvtpqMW5-fF7Bg3oJtUzU75cKOv6aUaHYYszydU8,2518
|
|
@@ -126,11 +126,11 @@ shotgun/tui/screens/chat.py,sha256=CqAv_x6R4zl-MGbtg8KgZWt8OhpBJYpx5gGBQ3oxqgw,3
|
|
|
126
126
|
shotgun/tui/screens/chat.tcss,sha256=2Yq3E23jxsySYsgZf4G1AYrYVcpX0UDW6kNNI0tDmtM,437
|
|
127
127
|
shotgun/tui/screens/directory_setup.py,sha256=lIZ1J4A6g5Q2ZBX8epW7BhR96Dmdcg22CyiM5S-I5WU,3237
|
|
128
128
|
shotgun/tui/screens/feedback.py,sha256=cYtmuM3qqKwevstu8gJ9mmk7lkIKZvfAyDEBUOLh-yI,5660
|
|
129
|
-
shotgun/tui/screens/model_picker.py,sha256=
|
|
130
|
-
shotgun/tui/screens/provider_config.py,sha256=
|
|
129
|
+
shotgun/tui/screens/model_picker.py,sha256=G-EvalpxgHKk0W3FgHMcxIr817VwZyEgh_ZadSQiRwo,11831
|
|
130
|
+
shotgun/tui/screens/provider_config.py,sha256=RWH7ksf9dp7eD7mz0g_o2Q-O6HTAyzIv7ZkOYrIOAI4,8686
|
|
131
131
|
shotgun/tui/screens/splash.py,sha256=E2MsJihi3c9NY1L28o_MstDxGwrCnnV7zdq00MrGAsw,706
|
|
132
132
|
shotgun/tui/screens/chat_screen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
133
|
-
shotgun/tui/screens/chat_screen/command_providers.py,sha256=
|
|
133
|
+
shotgun/tui/screens/chat_screen/command_providers.py,sha256=7Xnxd4k30bpLOMZSX32bcugU4IgpqU4Y8f6eHWKXd4o,12694
|
|
134
134
|
shotgun/tui/screens/chat_screen/hint_message.py,sha256=WOpbk8q7qt7eOHTyyHvh_IQIaublVDeJGaLpsxEk9FA,933
|
|
135
135
|
shotgun/tui/screens/chat_screen/history.py,sha256=Go859iEjw0s5aELKpF42MjLXy7UFQ52XnJMTIkV3aLo,12406
|
|
136
136
|
shotgun/tui/utils/__init__.py,sha256=cFjDfoXTRBq29wgP7TGRWUu1eFfiIG-LLOzjIGfadgI,150
|
|
@@ -140,8 +140,8 @@ shotgun/utils/env_utils.py,sha256=5spVCdeqVKtlWoKocPhz_5j_iRN30neqcGUzUuiWmfc,13
|
|
|
140
140
|
shotgun/utils/file_system_utils.py,sha256=l-0p1bEHF34OU19MahnRFdClHufThfGAjQ431teAIp0,1004
|
|
141
141
|
shotgun/utils/source_detection.py,sha256=Co6Q03R3fT771TF3RzB-70stfjNP2S4F_ArZKibwzm8,454
|
|
142
142
|
shotgun/utils/update_checker.py,sha256=IgzPHRhS1ETH7PnJR_dIx6lxgr1qHpCkMTgzUxvGjhI,7586
|
|
143
|
-
shotgun_sh-0.2.1.
|
|
144
|
-
shotgun_sh-0.2.1.
|
|
145
|
-
shotgun_sh-0.2.1.
|
|
146
|
-
shotgun_sh-0.2.1.
|
|
147
|
-
shotgun_sh-0.2.1.
|
|
143
|
+
shotgun_sh-0.2.1.dev4.dist-info/METADATA,sha256=V5zx_jzJA35YpklMNplhfdKnV63Emod0dZb0omi8x5U,11226
|
|
144
|
+
shotgun_sh-0.2.1.dev4.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
145
|
+
shotgun_sh-0.2.1.dev4.dist-info/entry_points.txt,sha256=asZxLU4QILneq0MWW10saVCZc4VWhZfb0wFZvERnzfA,45
|
|
146
|
+
shotgun_sh-0.2.1.dev4.dist-info/licenses/LICENSE,sha256=YebsZl590zCHrF_acCU5pmNt0pnAfD2DmAnevJPB1tY,1065
|
|
147
|
+
shotgun_sh-0.2.1.dev4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|