code-puppy 0.0.214__py3-none-any.whl → 0.0.366__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.
- code_puppy/__init__.py +7 -1
- code_puppy/agents/__init__.py +2 -0
- code_puppy/agents/agent_c_reviewer.py +59 -6
- code_puppy/agents/agent_code_puppy.py +7 -1
- code_puppy/agents/agent_code_reviewer.py +12 -2
- code_puppy/agents/agent_cpp_reviewer.py +73 -6
- code_puppy/agents/agent_creator_agent.py +45 -4
- code_puppy/agents/agent_golang_reviewer.py +92 -3
- code_puppy/agents/agent_javascript_reviewer.py +101 -8
- code_puppy/agents/agent_manager.py +81 -4
- code_puppy/agents/agent_pack_leader.py +383 -0
- code_puppy/agents/agent_planning.py +163 -0
- code_puppy/agents/agent_python_programmer.py +165 -0
- code_puppy/agents/agent_python_reviewer.py +28 -6
- code_puppy/agents/agent_qa_expert.py +98 -6
- code_puppy/agents/agent_qa_kitten.py +12 -7
- code_puppy/agents/agent_security_auditor.py +113 -3
- code_puppy/agents/agent_terminal_qa.py +323 -0
- code_puppy/agents/agent_typescript_reviewer.py +106 -7
- code_puppy/agents/base_agent.py +802 -176
- code_puppy/agents/event_stream_handler.py +350 -0
- code_puppy/agents/pack/__init__.py +34 -0
- code_puppy/agents/pack/bloodhound.py +304 -0
- code_puppy/agents/pack/husky.py +321 -0
- code_puppy/agents/pack/retriever.py +393 -0
- code_puppy/agents/pack/shepherd.py +348 -0
- code_puppy/agents/pack/terrier.py +287 -0
- code_puppy/agents/pack/watchdog.py +367 -0
- code_puppy/agents/prompt_reviewer.py +145 -0
- code_puppy/agents/subagent_stream_handler.py +276 -0
- code_puppy/api/__init__.py +13 -0
- code_puppy/api/app.py +169 -0
- code_puppy/api/main.py +21 -0
- code_puppy/api/pty_manager.py +446 -0
- code_puppy/api/routers/__init__.py +12 -0
- code_puppy/api/routers/agents.py +36 -0
- code_puppy/api/routers/commands.py +217 -0
- code_puppy/api/routers/config.py +74 -0
- code_puppy/api/routers/sessions.py +232 -0
- code_puppy/api/templates/terminal.html +361 -0
- code_puppy/api/websocket.py +154 -0
- code_puppy/callbacks.py +142 -4
- code_puppy/chatgpt_codex_client.py +283 -0
- code_puppy/claude_cache_client.py +586 -0
- code_puppy/cli_runner.py +916 -0
- code_puppy/command_line/add_model_menu.py +1079 -0
- code_puppy/command_line/agent_menu.py +395 -0
- code_puppy/command_line/attachments.py +10 -5
- code_puppy/command_line/autosave_menu.py +605 -0
- code_puppy/command_line/clipboard.py +527 -0
- code_puppy/command_line/colors_menu.py +520 -0
- code_puppy/command_line/command_handler.py +176 -738
- code_puppy/command_line/command_registry.py +150 -0
- code_puppy/command_line/config_commands.py +715 -0
- code_puppy/command_line/core_commands.py +792 -0
- code_puppy/command_line/diff_menu.py +863 -0
- code_puppy/command_line/load_context_completion.py +15 -22
- code_puppy/command_line/mcp/base.py +0 -3
- code_puppy/command_line/mcp/catalog_server_installer.py +175 -0
- code_puppy/command_line/mcp/custom_server_form.py +688 -0
- code_puppy/command_line/mcp/custom_server_installer.py +195 -0
- code_puppy/command_line/mcp/edit_command.py +148 -0
- code_puppy/command_line/mcp/handler.py +9 -4
- code_puppy/command_line/mcp/help_command.py +6 -5
- code_puppy/command_line/mcp/install_command.py +15 -26
- code_puppy/command_line/mcp/install_menu.py +685 -0
- code_puppy/command_line/mcp/list_command.py +2 -2
- code_puppy/command_line/mcp/logs_command.py +174 -65
- code_puppy/command_line/mcp/remove_command.py +2 -2
- code_puppy/command_line/mcp/restart_command.py +12 -4
- code_puppy/command_line/mcp/search_command.py +16 -10
- code_puppy/command_line/mcp/start_all_command.py +18 -6
- code_puppy/command_line/mcp/start_command.py +47 -25
- code_puppy/command_line/mcp/status_command.py +4 -5
- code_puppy/command_line/mcp/stop_all_command.py +7 -1
- code_puppy/command_line/mcp/stop_command.py +8 -4
- code_puppy/command_line/mcp/test_command.py +2 -2
- code_puppy/command_line/mcp/wizard_utils.py +20 -16
- code_puppy/command_line/mcp_completion.py +174 -0
- code_puppy/command_line/model_picker_completion.py +75 -25
- code_puppy/command_line/model_settings_menu.py +884 -0
- code_puppy/command_line/motd.py +14 -8
- code_puppy/command_line/onboarding_slides.py +179 -0
- code_puppy/command_line/onboarding_wizard.py +340 -0
- code_puppy/command_line/pin_command_completion.py +329 -0
- code_puppy/command_line/prompt_toolkit_completion.py +463 -63
- code_puppy/command_line/session_commands.py +296 -0
- code_puppy/command_line/utils.py +54 -0
- code_puppy/config.py +898 -112
- code_puppy/error_logging.py +118 -0
- code_puppy/gemini_code_assist.py +385 -0
- code_puppy/gemini_model.py +602 -0
- code_puppy/http_utils.py +210 -148
- code_puppy/keymap.py +128 -0
- code_puppy/main.py +5 -698
- code_puppy/mcp_/__init__.py +17 -0
- code_puppy/mcp_/async_lifecycle.py +35 -4
- code_puppy/mcp_/blocking_startup.py +70 -43
- code_puppy/mcp_/captured_stdio_server.py +2 -2
- code_puppy/mcp_/config_wizard.py +4 -4
- code_puppy/mcp_/dashboard.py +15 -6
- code_puppy/mcp_/managed_server.py +65 -38
- code_puppy/mcp_/manager.py +146 -52
- code_puppy/mcp_/mcp_logs.py +224 -0
- code_puppy/mcp_/registry.py +6 -6
- code_puppy/mcp_/server_registry_catalog.py +24 -5
- code_puppy/messaging/__init__.py +199 -2
- code_puppy/messaging/bus.py +610 -0
- code_puppy/messaging/commands.py +167 -0
- code_puppy/messaging/markdown_patches.py +57 -0
- code_puppy/messaging/message_queue.py +17 -48
- code_puppy/messaging/messages.py +500 -0
- code_puppy/messaging/queue_console.py +1 -24
- code_puppy/messaging/renderers.py +43 -146
- code_puppy/messaging/rich_renderer.py +1027 -0
- code_puppy/messaging/spinner/__init__.py +21 -5
- code_puppy/messaging/spinner/console_spinner.py +86 -51
- code_puppy/messaging/subagent_console.py +461 -0
- code_puppy/model_factory.py +634 -83
- code_puppy/model_utils.py +167 -0
- code_puppy/models.json +66 -68
- code_puppy/models_dev_api.json +1 -0
- code_puppy/models_dev_parser.py +592 -0
- code_puppy/plugins/__init__.py +164 -10
- code_puppy/plugins/antigravity_oauth/__init__.py +10 -0
- code_puppy/plugins/antigravity_oauth/accounts.py +406 -0
- code_puppy/plugins/antigravity_oauth/antigravity_model.py +704 -0
- code_puppy/plugins/antigravity_oauth/config.py +42 -0
- code_puppy/plugins/antigravity_oauth/constants.py +136 -0
- code_puppy/plugins/antigravity_oauth/oauth.py +478 -0
- code_puppy/plugins/antigravity_oauth/register_callbacks.py +406 -0
- code_puppy/plugins/antigravity_oauth/storage.py +271 -0
- code_puppy/plugins/antigravity_oauth/test_plugin.py +319 -0
- code_puppy/plugins/antigravity_oauth/token.py +167 -0
- code_puppy/plugins/antigravity_oauth/transport.py +767 -0
- code_puppy/plugins/antigravity_oauth/utils.py +169 -0
- code_puppy/plugins/chatgpt_oauth/__init__.py +8 -0
- code_puppy/plugins/chatgpt_oauth/config.py +52 -0
- code_puppy/plugins/chatgpt_oauth/oauth_flow.py +328 -0
- code_puppy/plugins/chatgpt_oauth/register_callbacks.py +94 -0
- code_puppy/plugins/chatgpt_oauth/test_plugin.py +293 -0
- code_puppy/plugins/chatgpt_oauth/utils.py +489 -0
- code_puppy/plugins/claude_code_oauth/README.md +167 -0
- code_puppy/plugins/claude_code_oauth/SETUP.md +93 -0
- code_puppy/plugins/claude_code_oauth/__init__.py +6 -0
- code_puppy/plugins/claude_code_oauth/config.py +50 -0
- code_puppy/plugins/claude_code_oauth/register_callbacks.py +308 -0
- code_puppy/plugins/claude_code_oauth/test_plugin.py +283 -0
- code_puppy/plugins/claude_code_oauth/utils.py +518 -0
- code_puppy/plugins/customizable_commands/__init__.py +0 -0
- code_puppy/plugins/customizable_commands/register_callbacks.py +169 -0
- code_puppy/plugins/example_custom_command/README.md +280 -0
- code_puppy/plugins/example_custom_command/register_callbacks.py +2 -2
- code_puppy/plugins/file_permission_handler/__init__.py +4 -0
- code_puppy/plugins/file_permission_handler/register_callbacks.py +523 -0
- code_puppy/plugins/frontend_emitter/__init__.py +25 -0
- code_puppy/plugins/frontend_emitter/emitter.py +121 -0
- code_puppy/plugins/frontend_emitter/register_callbacks.py +261 -0
- code_puppy/plugins/oauth_puppy_html.py +228 -0
- code_puppy/plugins/shell_safety/__init__.py +6 -0
- code_puppy/plugins/shell_safety/agent_shell_safety.py +69 -0
- code_puppy/plugins/shell_safety/command_cache.py +156 -0
- code_puppy/plugins/shell_safety/register_callbacks.py +202 -0
- code_puppy/prompts/antigravity_system_prompt.md +1 -0
- code_puppy/prompts/codex_system_prompt.md +310 -0
- code_puppy/pydantic_patches.py +131 -0
- code_puppy/reopenable_async_client.py +8 -8
- code_puppy/round_robin_model.py +9 -12
- code_puppy/session_storage.py +2 -1
- code_puppy/status_display.py +21 -4
- code_puppy/summarization_agent.py +41 -13
- code_puppy/terminal_utils.py +418 -0
- code_puppy/tools/__init__.py +37 -1
- code_puppy/tools/agent_tools.py +536 -52
- code_puppy/tools/browser/__init__.py +37 -0
- code_puppy/tools/browser/browser_control.py +19 -23
- code_puppy/tools/browser/browser_interactions.py +41 -48
- code_puppy/tools/browser/browser_locators.py +36 -38
- code_puppy/tools/browser/browser_manager.py +316 -0
- code_puppy/tools/browser/browser_navigation.py +16 -16
- code_puppy/tools/browser/browser_screenshot.py +79 -143
- code_puppy/tools/browser/browser_scripts.py +32 -42
- code_puppy/tools/browser/browser_workflows.py +44 -27
- code_puppy/tools/browser/chromium_terminal_manager.py +259 -0
- code_puppy/tools/browser/terminal_command_tools.py +521 -0
- code_puppy/tools/browser/terminal_screenshot_tools.py +556 -0
- code_puppy/tools/browser/terminal_tools.py +525 -0
- code_puppy/tools/command_runner.py +930 -147
- code_puppy/tools/common.py +1113 -5
- code_puppy/tools/display.py +84 -0
- code_puppy/tools/file_modifications.py +288 -89
- code_puppy/tools/file_operations.py +226 -154
- code_puppy/tools/subagent_context.py +158 -0
- code_puppy/uvx_detection.py +242 -0
- code_puppy/version_checker.py +30 -11
- code_puppy-0.0.366.data/data/code_puppy/models.json +110 -0
- code_puppy-0.0.366.data/data/code_puppy/models_dev_api.json +1 -0
- {code_puppy-0.0.214.dist-info → code_puppy-0.0.366.dist-info}/METADATA +149 -75
- code_puppy-0.0.366.dist-info/RECORD +217 -0
- {code_puppy-0.0.214.dist-info → code_puppy-0.0.366.dist-info}/WHEEL +1 -1
- code_puppy/command_line/mcp/add_command.py +0 -183
- code_puppy/messaging/spinner/textual_spinner.py +0 -106
- code_puppy/tools/browser/camoufox_manager.py +0 -216
- code_puppy/tools/browser/vqa_agent.py +0 -70
- code_puppy/tui/__init__.py +0 -10
- code_puppy/tui/app.py +0 -1105
- code_puppy/tui/components/__init__.py +0 -21
- code_puppy/tui/components/chat_view.py +0 -551
- code_puppy/tui/components/command_history_modal.py +0 -218
- code_puppy/tui/components/copy_button.py +0 -139
- code_puppy/tui/components/custom_widgets.py +0 -63
- code_puppy/tui/components/human_input_modal.py +0 -175
- code_puppy/tui/components/input_area.py +0 -167
- code_puppy/tui/components/sidebar.py +0 -309
- code_puppy/tui/components/status_bar.py +0 -185
- code_puppy/tui/messages.py +0 -27
- code_puppy/tui/models/__init__.py +0 -8
- code_puppy/tui/models/chat_message.py +0 -25
- code_puppy/tui/models/command_history.py +0 -89
- code_puppy/tui/models/enums.py +0 -24
- code_puppy/tui/screens/__init__.py +0 -17
- code_puppy/tui/screens/autosave_picker.py +0 -175
- code_puppy/tui/screens/help.py +0 -130
- code_puppy/tui/screens/mcp_install_wizard.py +0 -803
- code_puppy/tui/screens/settings.py +0 -306
- code_puppy/tui/screens/tools.py +0 -74
- code_puppy/tui_state.py +0 -55
- code_puppy-0.0.214.data/data/code_puppy/models.json +0 -112
- code_puppy-0.0.214.dist-info/RECORD +0 -131
- {code_puppy-0.0.214.dist-info → code_puppy-0.0.366.dist-info}/entry_points.txt +0 -0
- {code_puppy-0.0.214.dist-info → code_puppy-0.0.366.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
"""
|
|
2
|
-
Shared spinner implementation for
|
|
2
|
+
Shared spinner implementation for CLI mode.
|
|
3
3
|
|
|
4
4
|
This module provides consistent spinner animations across different UI modes.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
7
|
from .console_spinner import ConsoleSpinner
|
|
8
8
|
from .spinner_base import SpinnerBase
|
|
9
|
-
from .textual_spinner import TextualSpinner
|
|
10
9
|
|
|
11
10
|
# Keep track of all active spinners to manage them globally
|
|
12
11
|
_active_spinners = []
|
|
@@ -25,7 +24,16 @@ def unregister_spinner(spinner):
|
|
|
25
24
|
|
|
26
25
|
|
|
27
26
|
def pause_all_spinners():
|
|
28
|
-
"""Pause all active spinners.
|
|
27
|
+
"""Pause all active spinners.
|
|
28
|
+
|
|
29
|
+
No-op when called from a sub-agent context to prevent
|
|
30
|
+
parallel sub-agents from interfering with the main spinner.
|
|
31
|
+
"""
|
|
32
|
+
# Lazy import to avoid circular dependency
|
|
33
|
+
from code_puppy.tools.subagent_context import is_subagent
|
|
34
|
+
|
|
35
|
+
if is_subagent():
|
|
36
|
+
return # Sub-agents don't control the main spinner
|
|
29
37
|
for spinner in _active_spinners:
|
|
30
38
|
try:
|
|
31
39
|
spinner.pause()
|
|
@@ -35,7 +43,16 @@ def pause_all_spinners():
|
|
|
35
43
|
|
|
36
44
|
|
|
37
45
|
def resume_all_spinners():
|
|
38
|
-
"""Resume all active spinners.
|
|
46
|
+
"""Resume all active spinners.
|
|
47
|
+
|
|
48
|
+
No-op when called from a sub-agent context to prevent
|
|
49
|
+
parallel sub-agents from interfering with the main spinner.
|
|
50
|
+
"""
|
|
51
|
+
# Lazy import to avoid circular dependency
|
|
52
|
+
from code_puppy.tools.subagent_context import is_subagent
|
|
53
|
+
|
|
54
|
+
if is_subagent():
|
|
55
|
+
return # Sub-agents don't control the main spinner
|
|
39
56
|
for spinner in _active_spinners:
|
|
40
57
|
try:
|
|
41
58
|
spinner.resume()
|
|
@@ -56,7 +73,6 @@ def clear_spinner_context() -> None:
|
|
|
56
73
|
|
|
57
74
|
__all__ = [
|
|
58
75
|
"SpinnerBase",
|
|
59
|
-
"TextualSpinner",
|
|
60
76
|
"ConsoleSpinner",
|
|
61
77
|
"register_spinner",
|
|
62
78
|
"unregister_spinner",
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Console spinner implementation for CLI mode using Rich's Live Display.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
import platform
|
|
5
6
|
import threading
|
|
6
7
|
import time
|
|
7
8
|
|
|
@@ -43,12 +44,15 @@ class ConsoleSpinner(SpinnerBase):
|
|
|
43
44
|
if self._thread and self._thread.is_alive():
|
|
44
45
|
return
|
|
45
46
|
|
|
47
|
+
# Print blank line before spinner for visual separation from content
|
|
48
|
+
self.console.print()
|
|
49
|
+
|
|
46
50
|
# Create a Live display for the spinner
|
|
47
51
|
self._live = Live(
|
|
48
52
|
self._generate_spinner_panel(),
|
|
49
53
|
console=self.console,
|
|
50
54
|
refresh_per_second=20,
|
|
51
|
-
transient=True,
|
|
55
|
+
transient=True, # Clear the spinner line when stopped (no puppy litter!)
|
|
52
56
|
auto_refresh=False, # Don't auto-refresh to avoid wiping out user input
|
|
53
57
|
)
|
|
54
58
|
self._live.start()
|
|
@@ -75,6 +79,33 @@ class ConsoleSpinner(SpinnerBase):
|
|
|
75
79
|
|
|
76
80
|
self._thread = None
|
|
77
81
|
|
|
82
|
+
# Windows-specific cleanup: Rich's Live display can leave terminal in corrupted state
|
|
83
|
+
if platform.system() == "Windows":
|
|
84
|
+
import sys
|
|
85
|
+
|
|
86
|
+
try:
|
|
87
|
+
# Reset ANSI formatting for both stdout and stderr
|
|
88
|
+
sys.stdout.write("\x1b[0m") # Reset all attributes
|
|
89
|
+
sys.stdout.flush()
|
|
90
|
+
sys.stderr.write("\x1b[0m")
|
|
91
|
+
sys.stderr.flush()
|
|
92
|
+
|
|
93
|
+
# Clear the line and reposition cursor
|
|
94
|
+
sys.stdout.write("\r") # Return to start of line
|
|
95
|
+
sys.stdout.write("\x1b[K") # Clear to end of line
|
|
96
|
+
sys.stdout.flush()
|
|
97
|
+
|
|
98
|
+
# Flush keyboard input buffer to clear any stuck keys
|
|
99
|
+
try:
|
|
100
|
+
import msvcrt
|
|
101
|
+
|
|
102
|
+
while msvcrt.kbhit():
|
|
103
|
+
msvcrt.getch()
|
|
104
|
+
except ImportError:
|
|
105
|
+
pass # msvcrt not available (not Windows or different Python impl)
|
|
106
|
+
except Exception:
|
|
107
|
+
pass # Fail silently if cleanup doesn't work
|
|
108
|
+
|
|
78
109
|
# Unregister this spinner from global management
|
|
79
110
|
from . import unregister_spinner
|
|
80
111
|
|
|
@@ -86,21 +117,16 @@ class ConsoleSpinner(SpinnerBase):
|
|
|
86
117
|
|
|
87
118
|
def _generate_spinner_panel(self):
|
|
88
119
|
"""Generate a Rich panel containing the spinner text."""
|
|
89
|
-
if
|
|
120
|
+
# Check if we're awaiting user input - show nothing during input prompts
|
|
121
|
+
from code_puppy.tools.command_runner import is_awaiting_user_input
|
|
122
|
+
|
|
123
|
+
if self._paused or is_awaiting_user_input():
|
|
90
124
|
return Text("")
|
|
91
125
|
|
|
92
126
|
text = Text()
|
|
93
127
|
|
|
94
|
-
#
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
if is_awaiting_user_input():
|
|
98
|
-
# Show waiting message when waiting for user input
|
|
99
|
-
text.append(SpinnerBase.WAITING_MESSAGE, style="bold cyan")
|
|
100
|
-
else:
|
|
101
|
-
# Show thinking message during normal processing
|
|
102
|
-
text.append(SpinnerBase.THINKING_MESSAGE, style="bold cyan")
|
|
103
|
-
|
|
128
|
+
# Show thinking message during normal processing
|
|
129
|
+
text.append(SpinnerBase.THINKING_MESSAGE, style="bold cyan")
|
|
104
130
|
text.append(self.current_frame, style="bold cyan")
|
|
105
131
|
|
|
106
132
|
context_info = SpinnerBase.get_context_info()
|
|
@@ -132,39 +158,29 @@ class ConsoleSpinner(SpinnerBase):
|
|
|
132
158
|
# Short sleep to control animation speed
|
|
133
159
|
time.sleep(0.05)
|
|
134
160
|
except Exception as e:
|
|
135
|
-
|
|
161
|
+
# Note: Using sys.stderr - can't use messaging during spinner
|
|
162
|
+
import sys
|
|
163
|
+
|
|
164
|
+
sys.stderr.write(f"\nSpinner error: {e}\n")
|
|
136
165
|
self._is_spinning = False
|
|
137
166
|
|
|
138
167
|
def pause(self):
|
|
139
168
|
"""Pause the spinner animation."""
|
|
140
169
|
if self._is_spinning:
|
|
141
170
|
self._paused = True
|
|
142
|
-
#
|
|
171
|
+
# Stop the live display completely to restore terminal echo during input
|
|
143
172
|
if self._live:
|
|
144
173
|
try:
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
self._live.update(text)
|
|
154
|
-
self._live.refresh()
|
|
155
|
-
# Allow a moment for the waiting message to be visible
|
|
156
|
-
import time
|
|
157
|
-
|
|
158
|
-
time.sleep(0.1)
|
|
159
|
-
|
|
160
|
-
# Then clear the display
|
|
161
|
-
self._live.update(Text(""))
|
|
174
|
+
self._live.stop()
|
|
175
|
+
self._live = None
|
|
176
|
+
# Clear the line to remove any artifacts
|
|
177
|
+
import sys
|
|
178
|
+
|
|
179
|
+
sys.stdout.write("\r") # Return to start of line
|
|
180
|
+
sys.stdout.write("\x1b[K") # Clear to end of line
|
|
181
|
+
sys.stdout.flush()
|
|
162
182
|
except Exception:
|
|
163
|
-
|
|
164
|
-
try:
|
|
165
|
-
self._live.stop()
|
|
166
|
-
except Exception:
|
|
167
|
-
pass
|
|
183
|
+
pass
|
|
168
184
|
|
|
169
185
|
def resume(self):
|
|
170
186
|
"""Resume the spinner animation."""
|
|
@@ -176,24 +192,43 @@ class ConsoleSpinner(SpinnerBase):
|
|
|
176
192
|
|
|
177
193
|
if self._is_spinning and self._paused:
|
|
178
194
|
self._paused = False
|
|
179
|
-
#
|
|
180
|
-
if self._live:
|
|
195
|
+
# Restart the live display if it was stopped during pause
|
|
196
|
+
if not self._live:
|
|
181
197
|
try:
|
|
198
|
+
# Clear any leftover artifacts before starting
|
|
199
|
+
import sys
|
|
200
|
+
|
|
201
|
+
sys.stdout.write("\r") # Return to start of line
|
|
202
|
+
sys.stdout.write("\x1b[K") # Clear to end of line
|
|
203
|
+
sys.stdout.flush()
|
|
204
|
+
|
|
205
|
+
# Print blank line before spinner for visual separation
|
|
206
|
+
self.console.print()
|
|
207
|
+
|
|
208
|
+
self._live = Live(
|
|
209
|
+
self._generate_spinner_panel(),
|
|
210
|
+
console=self.console,
|
|
211
|
+
refresh_per_second=20,
|
|
212
|
+
transient=True, # Clear spinner line when stopped
|
|
213
|
+
auto_refresh=False,
|
|
214
|
+
)
|
|
215
|
+
self._live.start()
|
|
216
|
+
except Exception:
|
|
217
|
+
pass
|
|
218
|
+
else:
|
|
219
|
+
# If live display still exists, clear console state first
|
|
220
|
+
try:
|
|
221
|
+
# Force Rich to reset any cached console state
|
|
222
|
+
if hasattr(self.console, "_buffer"):
|
|
223
|
+
# Clear Rich's internal buffer to prevent artifacts
|
|
224
|
+
self.console.file.write("\r") # Return to start
|
|
225
|
+
self.console.file.write("\x1b[K") # Clear line
|
|
226
|
+
self.console.file.flush()
|
|
227
|
+
|
|
182
228
|
self._live.update(self._generate_spinner_panel())
|
|
229
|
+
self._live.refresh()
|
|
183
230
|
except Exception:
|
|
184
|
-
|
|
185
|
-
# Try to restart it
|
|
186
|
-
try:
|
|
187
|
-
self._live = Live(
|
|
188
|
-
self._generate_spinner_panel(),
|
|
189
|
-
console=self.console,
|
|
190
|
-
refresh_per_second=10,
|
|
191
|
-
transient=True,
|
|
192
|
-
auto_refresh=False, # Don't auto-refresh to avoid wiping out user input
|
|
193
|
-
)
|
|
194
|
-
self._live.start()
|
|
195
|
-
except Exception:
|
|
196
|
-
pass
|
|
231
|
+
pass
|
|
197
232
|
|
|
198
233
|
def __enter__(self):
|
|
199
234
|
"""Support for context manager."""
|