shotgun-sh 0.2.8.dev1__py3-none-any.whl → 0.2.8.dev2__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.
- shotgun/agents/agent_manager.py +11 -4
- shotgun/main.py +10 -54
- shotgun/tui/app.py +0 -116
- {shotgun_sh-0.2.8.dev1.dist-info → shotgun_sh-0.2.8.dev2.dist-info}/METADATA +1 -2
- {shotgun_sh-0.2.8.dev1.dist-info → shotgun_sh-0.2.8.dev2.dist-info}/RECORD +8 -8
- {shotgun_sh-0.2.8.dev1.dist-info → shotgun_sh-0.2.8.dev2.dist-info}/WHEEL +0 -0
- {shotgun_sh-0.2.8.dev1.dist-info → shotgun_sh-0.2.8.dev2.dist-info}/entry_points.txt +0 -0
- {shotgun_sh-0.2.8.dev1.dist-info → shotgun_sh-0.2.8.dev2.dist-info}/licenses/LICENSE +0 -0
shotgun/agents/agent_manager.py
CHANGED
|
@@ -381,14 +381,21 @@ class AgentManager(Widget):
|
|
|
381
381
|
|
|
382
382
|
# Clear file tracker before each run to track only this run's operations
|
|
383
383
|
deps.file_tracker.clear()
|
|
384
|
-
# preprocess messages; maybe we need to include the user answer in the message history
|
|
385
|
-
|
|
386
|
-
original_messages = self.ui_message_history.copy()
|
|
387
384
|
|
|
385
|
+
# Add user prompt if present (will be shown immediately via post_messages_updated)
|
|
388
386
|
if prompt:
|
|
389
|
-
|
|
387
|
+
user_request = ModelRequest.user_text_prompt(prompt)
|
|
388
|
+
self.ui_message_history.append(user_request)
|
|
389
|
+
|
|
390
|
+
# Always post update before run to show user message (or current state if no prompt)
|
|
390
391
|
self._post_messages_updated()
|
|
391
392
|
|
|
393
|
+
# Save history WITHOUT the just-added prompt to avoid duplicates
|
|
394
|
+
# (result.new_messages() will include the prompt)
|
|
395
|
+
original_messages = (
|
|
396
|
+
self.ui_message_history[:-1] if prompt else self.ui_message_history.copy()
|
|
397
|
+
)
|
|
398
|
+
|
|
392
399
|
# Start with persistent message history
|
|
393
400
|
message_history = self.message_history
|
|
394
401
|
|
shotgun/main.py
CHANGED
|
@@ -125,34 +125,6 @@ def main(
|
|
|
125
125
|
help="Continue previous TUI conversation",
|
|
126
126
|
),
|
|
127
127
|
] = False,
|
|
128
|
-
web: Annotated[
|
|
129
|
-
bool,
|
|
130
|
-
typer.Option(
|
|
131
|
-
"--web",
|
|
132
|
-
help="Serve TUI as web application",
|
|
133
|
-
),
|
|
134
|
-
] = False,
|
|
135
|
-
port: Annotated[
|
|
136
|
-
int,
|
|
137
|
-
typer.Option(
|
|
138
|
-
"--port",
|
|
139
|
-
help="Port for web server (only used with --web)",
|
|
140
|
-
),
|
|
141
|
-
] = 8000,
|
|
142
|
-
host: Annotated[
|
|
143
|
-
str,
|
|
144
|
-
typer.Option(
|
|
145
|
-
"--host",
|
|
146
|
-
help="Host address for web server (only used with --web)",
|
|
147
|
-
),
|
|
148
|
-
] = "localhost",
|
|
149
|
-
public_url: Annotated[
|
|
150
|
-
str | None,
|
|
151
|
-
typer.Option(
|
|
152
|
-
"--public-url",
|
|
153
|
-
help="Public URL if behind proxy (only used with --web)",
|
|
154
|
-
),
|
|
155
|
-
] = None,
|
|
156
128
|
) -> None:
|
|
157
129
|
"""Shotgun - AI-powered CLI tool."""
|
|
158
130
|
logger.debug("Starting shotgun CLI application")
|
|
@@ -162,32 +134,16 @@ def main(
|
|
|
162
134
|
perform_auto_update_async(no_update_check=no_update_check)
|
|
163
135
|
|
|
164
136
|
if ctx.invoked_subcommand is None and not ctx.resilient_parsing:
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
finally:
|
|
176
|
-
# Ensure PostHog is shut down cleanly even if server exits unexpectedly
|
|
177
|
-
from shotgun.posthog_telemetry import shutdown
|
|
178
|
-
|
|
179
|
-
shutdown()
|
|
180
|
-
else:
|
|
181
|
-
logger.debug("Launching shotgun TUI application")
|
|
182
|
-
try:
|
|
183
|
-
tui_app.run(
|
|
184
|
-
no_update_check=no_update_check, continue_session=continue_session
|
|
185
|
-
)
|
|
186
|
-
finally:
|
|
187
|
-
# Ensure PostHog is shut down cleanly even if TUI exits unexpectedly
|
|
188
|
-
from shotgun.posthog_telemetry import shutdown
|
|
189
|
-
|
|
190
|
-
shutdown()
|
|
137
|
+
logger.debug("Launching shotgun TUI application")
|
|
138
|
+
try:
|
|
139
|
+
tui_app.run(
|
|
140
|
+
no_update_check=no_update_check, continue_session=continue_session
|
|
141
|
+
)
|
|
142
|
+
finally:
|
|
143
|
+
# Ensure PostHog is shut down cleanly even if TUI exits unexpectedly
|
|
144
|
+
from shotgun.posthog_telemetry import shutdown
|
|
145
|
+
|
|
146
|
+
shutdown()
|
|
191
147
|
raise typer.Exit()
|
|
192
148
|
|
|
193
149
|
# For CLI commands, register PostHog shutdown handler
|
shotgun/tui/app.py
CHANGED
|
@@ -152,121 +152,5 @@ def run(no_update_check: bool = False, continue_session: bool = False) -> None:
|
|
|
152
152
|
app.run(inline_no_clear=True)
|
|
153
153
|
|
|
154
154
|
|
|
155
|
-
def serve(
|
|
156
|
-
host: str = "localhost",
|
|
157
|
-
port: int = 8000,
|
|
158
|
-
public_url: str | None = None,
|
|
159
|
-
no_update_check: bool = False,
|
|
160
|
-
continue_session: bool = False,
|
|
161
|
-
) -> None:
|
|
162
|
-
"""Serve the TUI application as a web application.
|
|
163
|
-
|
|
164
|
-
Args:
|
|
165
|
-
host: Host address for the web server.
|
|
166
|
-
port: Port number for the web server.
|
|
167
|
-
public_url: Public URL if behind a proxy.
|
|
168
|
-
no_update_check: If True, disable automatic update checks.
|
|
169
|
-
continue_session: If True, continue from previous conversation.
|
|
170
|
-
"""
|
|
171
|
-
# Clean up any corrupted databases BEFORE starting the TUI
|
|
172
|
-
# This prevents crashes from corrupted databases during initialization
|
|
173
|
-
import asyncio
|
|
174
|
-
|
|
175
|
-
from textual_serve.server import Server
|
|
176
|
-
|
|
177
|
-
from shotgun.codebase.core.manager import CodebaseGraphManager
|
|
178
|
-
from shotgun.utils import get_shotgun_home
|
|
179
|
-
|
|
180
|
-
storage_dir = get_shotgun_home() / "codebases"
|
|
181
|
-
manager = CodebaseGraphManager(storage_dir)
|
|
182
|
-
|
|
183
|
-
try:
|
|
184
|
-
removed = asyncio.run(manager.cleanup_corrupted_databases())
|
|
185
|
-
if removed:
|
|
186
|
-
logger.info(
|
|
187
|
-
f"Cleaned up {len(removed)} corrupted database(s) before TUI startup"
|
|
188
|
-
)
|
|
189
|
-
except Exception as e:
|
|
190
|
-
logger.error(f"Failed to cleanup corrupted databases: {e}")
|
|
191
|
-
# Continue anyway - the TUI can still function
|
|
192
|
-
|
|
193
|
-
# Create a new event loop after asyncio.run() closes the previous one
|
|
194
|
-
# This is needed for the Server.serve() method
|
|
195
|
-
loop = asyncio.new_event_loop()
|
|
196
|
-
asyncio.set_event_loop(loop)
|
|
197
|
-
|
|
198
|
-
# Build the command string based on flags
|
|
199
|
-
command = "shotgun"
|
|
200
|
-
if no_update_check:
|
|
201
|
-
command += " --no-update-check"
|
|
202
|
-
if continue_session:
|
|
203
|
-
command += " --continue"
|
|
204
|
-
|
|
205
|
-
# Create and start the server with hardcoded title and debug=False
|
|
206
|
-
server = Server(
|
|
207
|
-
command=command,
|
|
208
|
-
host=host,
|
|
209
|
-
port=port,
|
|
210
|
-
title="The Shotgun",
|
|
211
|
-
public_url=public_url,
|
|
212
|
-
)
|
|
213
|
-
|
|
214
|
-
# Set up graceful shutdown on SIGTERM/SIGINT
|
|
215
|
-
import signal
|
|
216
|
-
import sys
|
|
217
|
-
|
|
218
|
-
def signal_handler(_signum: int, _frame: Any) -> None:
|
|
219
|
-
"""Handle shutdown signals gracefully."""
|
|
220
|
-
from shotgun.posthog_telemetry import shutdown
|
|
221
|
-
|
|
222
|
-
logger.info("Received shutdown signal, cleaning up...")
|
|
223
|
-
# Restore stdout/stderr before shutting down
|
|
224
|
-
sys.stdout = original_stdout
|
|
225
|
-
sys.stderr = original_stderr
|
|
226
|
-
shutdown()
|
|
227
|
-
sys.exit(0)
|
|
228
|
-
|
|
229
|
-
signal.signal(signal.SIGTERM, signal_handler)
|
|
230
|
-
signal.signal(signal.SIGINT, signal_handler)
|
|
231
|
-
|
|
232
|
-
# Suppress the textual-serve banner by redirecting stdout/stderr
|
|
233
|
-
import io
|
|
234
|
-
|
|
235
|
-
# Capture and suppress the banner, but show the actual serving URL
|
|
236
|
-
original_stdout = sys.stdout
|
|
237
|
-
original_stderr = sys.stderr
|
|
238
|
-
|
|
239
|
-
captured_output = io.StringIO()
|
|
240
|
-
sys.stdout = captured_output
|
|
241
|
-
sys.stderr = captured_output
|
|
242
|
-
|
|
243
|
-
try:
|
|
244
|
-
# This will print the banner to our captured output
|
|
245
|
-
import logging
|
|
246
|
-
|
|
247
|
-
# Temporarily set logging to ERROR level to suppress INFO messages
|
|
248
|
-
textual_serve_logger = logging.getLogger("textual_serve")
|
|
249
|
-
original_level = textual_serve_logger.level
|
|
250
|
-
textual_serve_logger.setLevel(logging.ERROR)
|
|
251
|
-
|
|
252
|
-
# Print our own message to the original stdout
|
|
253
|
-
sys.stdout = original_stdout
|
|
254
|
-
sys.stderr = original_stderr
|
|
255
|
-
print(f"Serving Shotgun TUI at http://{host}:{port}")
|
|
256
|
-
print("Press Ctrl+C to quit")
|
|
257
|
-
|
|
258
|
-
# Now suppress output again for the serve call
|
|
259
|
-
sys.stdout = captured_output
|
|
260
|
-
sys.stderr = captured_output
|
|
261
|
-
|
|
262
|
-
server.serve(debug=False)
|
|
263
|
-
finally:
|
|
264
|
-
# Restore original stdout/stderr
|
|
265
|
-
sys.stdout = original_stdout
|
|
266
|
-
sys.stderr = original_stderr
|
|
267
|
-
if "textual_serve_logger" in locals():
|
|
268
|
-
textual_serve_logger.setLevel(original_level)
|
|
269
|
-
|
|
270
|
-
|
|
271
155
|
if __name__ == "__main__":
|
|
272
156
|
run()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: shotgun-sh
|
|
3
|
-
Version: 0.2.8.
|
|
3
|
+
Version: 0.2.8.dev2
|
|
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
|
|
@@ -36,7 +36,6 @@ Requires-Dist: sentencepiece>=0.2.0
|
|
|
36
36
|
Requires-Dist: sentry-sdk[pure-eval]>=2.0.0
|
|
37
37
|
Requires-Dist: tenacity>=8.0.0
|
|
38
38
|
Requires-Dist: textual-dev>=1.7.0
|
|
39
|
-
Requires-Dist: textual-serve>=0.1.0
|
|
40
39
|
Requires-Dist: textual>=6.1.0
|
|
41
40
|
Requires-Dist: tiktoken>=0.7.0
|
|
42
41
|
Requires-Dist: tree-sitter-go>=0.23.0
|
|
@@ -2,13 +2,13 @@ shotgun/__init__.py,sha256=P40K0fnIsb7SKcQrFnXZ4aREjpWchVDhvM1HxI4cyIQ,104
|
|
|
2
2
|
shotgun/api_endpoints.py,sha256=TvxuJyMrZLy6KZTrR6lrdkG8OBtb3TJ48qaw3pWitO0,526
|
|
3
3
|
shotgun/build_constants.py,sha256=RXNxMz46HaB5jucgMVpw8a2yCJqjbhTOh0PddyEVMN8,713
|
|
4
4
|
shotgun/logging_config.py,sha256=UKenihvgH8OA3W0b8ZFcItYaFJVe9MlsMYlcevyW1HY,7440
|
|
5
|
-
shotgun/main.py,sha256=
|
|
5
|
+
shotgun/main.py,sha256=RA3q1xPfqxCu43UmgI2ryZpA-IxPhJb_MJrbLqp9c_g,5140
|
|
6
6
|
shotgun/posthog_telemetry.py,sha256=TOiyBtLg21SttHGWKc4-e-PQgpbq6Uz_4OzlvlxMcZ0,6099
|
|
7
7
|
shotgun/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
shotgun/sentry_telemetry.py,sha256=VD8es-tREfgtRKhDsEVvqpo0_kM_ab6iVm2lkOEmTlI,2950
|
|
9
9
|
shotgun/telemetry.py,sha256=C8dM7Feo1OxJMwDvgAMaA2RyRDO2rYPvC_8kLBuRUS8,3683
|
|
10
10
|
shotgun/agents/__init__.py,sha256=8Jzv1YsDuLyNPFJyckSr_qI4ehTVeDyIMDW4omsfPGc,25
|
|
11
|
-
shotgun/agents/agent_manager.py,sha256=
|
|
11
|
+
shotgun/agents/agent_manager.py,sha256=cdrw96weXEkqaLGgmIPgnA48iMR1fYBLu_05p1eMHtQ,39851
|
|
12
12
|
shotgun/agents/common.py,sha256=0F_dwEc72APvbY1b-lqM9VgPYuY1GpfhjSWv5-1pCB0,19032
|
|
13
13
|
shotgun/agents/conversation_history.py,sha256=c-1PBaG9FXPfSmekWtrD6s6YVT0sd98DdDhzS4a1Hyo,7859
|
|
14
14
|
shotgun/agents/conversation_manager.py,sha256=X3DWZZIqrv0hS1SUasyoxexnLPBUrZMBg4ZmRAipkBE,4429
|
|
@@ -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=
|
|
122
|
+
shotgun/tui/app.py,sha256=B2tKbXeGhWBIVec1jJHGAuBcP1SMbO_6xol2OaBpw2Y,5374
|
|
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
|
|
@@ -148,8 +148,8 @@ shotgun/utils/env_utils.py,sha256=ulM3BRi9ZhS7uC-zorGeDQm4SHvsyFuuU9BtVPqdrHY,14
|
|
|
148
148
|
shotgun/utils/file_system_utils.py,sha256=l-0p1bEHF34OU19MahnRFdClHufThfGAjQ431teAIp0,1004
|
|
149
149
|
shotgun/utils/source_detection.py,sha256=Co6Q03R3fT771TF3RzB-70stfjNP2S4F_ArZKibwzm8,454
|
|
150
150
|
shotgun/utils/update_checker.py,sha256=IgzPHRhS1ETH7PnJR_dIx6lxgr1qHpCkMTgzUxvGjhI,7586
|
|
151
|
-
shotgun_sh-0.2.8.
|
|
152
|
-
shotgun_sh-0.2.8.
|
|
153
|
-
shotgun_sh-0.2.8.
|
|
154
|
-
shotgun_sh-0.2.8.
|
|
155
|
-
shotgun_sh-0.2.8.
|
|
151
|
+
shotgun_sh-0.2.8.dev2.dist-info/METADATA,sha256=8nSxwROnGNuQxNUY8bovpYeFSCwHhnLLx4geGZZVaKo,4299
|
|
152
|
+
shotgun_sh-0.2.8.dev2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
153
|
+
shotgun_sh-0.2.8.dev2.dist-info/entry_points.txt,sha256=asZxLU4QILneq0MWW10saVCZc4VWhZfb0wFZvERnzfA,45
|
|
154
|
+
shotgun_sh-0.2.8.dev2.dist-info/licenses/LICENSE,sha256=YebsZl590zCHrF_acCU5pmNt0pnAfD2DmAnevJPB1tY,1065
|
|
155
|
+
shotgun_sh-0.2.8.dev2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|