code-puppy 0.0.169__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 +8 -8
- code_puppy/agents/agent_c_reviewer.py +155 -0
- code_puppy/agents/agent_code_puppy.py +9 -2
- code_puppy/agents/agent_code_reviewer.py +90 -0
- code_puppy/agents/agent_cpp_reviewer.py +132 -0
- code_puppy/agents/agent_creator_agent.py +48 -9
- code_puppy/agents/agent_golang_reviewer.py +151 -0
- code_puppy/agents/agent_javascript_reviewer.py +160 -0
- code_puppy/agents/agent_manager.py +146 -199
- 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 +90 -0
- code_puppy/agents/agent_qa_expert.py +163 -0
- code_puppy/agents/agent_qa_kitten.py +208 -0
- code_puppy/agents/agent_security_auditor.py +181 -0
- code_puppy/agents/agent_terminal_qa.py +323 -0
- code_puppy/agents/agent_typescript_reviewer.py +166 -0
- code_puppy/agents/base_agent.py +1713 -1
- code_puppy/agents/event_stream_handler.py +350 -0
- code_puppy/agents/json_agent.py +12 -1
- 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 +174 -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 +395 -0
- 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 +233 -627
- 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 +1 -4
- 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 +16 -27
- code_puppy/command_line/mcp/install_menu.py +685 -0
- code_puppy/command_line/mcp/list_command.py +3 -3
- 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 +17 -11
- code_puppy/command_line/mcp/start_all_command.py +22 -13
- code_puppy/command_line/mcp/start_command.py +50 -31
- code_puppy/command_line/mcp/status_command.py +6 -7
- code_puppy/command_line/mcp/stop_all_command.py +11 -8
- code_puppy/command_line/mcp/stop_command.py +11 -10
- code_puppy/command_line/mcp/test_command.py +2 -2
- code_puppy/command_line/mcp/utils.py +1 -1
- code_puppy/command_line/mcp/wizard_utils.py +22 -18
- code_puppy/command_line/mcp_completion.py +174 -0
- code_puppy/command_line/model_picker_completion.py +89 -30
- 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 +626 -75
- code_puppy/command_line/session_commands.py +296 -0
- code_puppy/command_line/utils.py +54 -0
- code_puppy/config.py +1181 -51
- 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 +220 -104
- code_puppy/keymap.py +128 -0
- code_puppy/main.py +5 -594
- code_puppy/{mcp → mcp_}/__init__.py +17 -0
- code_puppy/{mcp → mcp_}/async_lifecycle.py +35 -4
- code_puppy/{mcp → mcp_}/blocking_startup.py +70 -43
- code_puppy/{mcp → mcp_}/captured_stdio_server.py +2 -2
- code_puppy/{mcp → mcp_}/config_wizard.py +5 -5
- code_puppy/{mcp → mcp_}/dashboard.py +15 -6
- code_puppy/{mcp → mcp_}/examples/retry_example.py +4 -1
- code_puppy/{mcp → mcp_}/managed_server.py +66 -39
- code_puppy/{mcp → mcp_}/manager.py +146 -52
- code_puppy/mcp_/mcp_logs.py +224 -0
- code_puppy/{mcp → mcp_}/registry.py +6 -6
- code_puppy/{mcp → mcp_}/server_registry_catalog.py +25 -8
- 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 +33 -5
- code_puppy/messaging/spinner/console_spinner.py +92 -52
- code_puppy/messaging/spinner/spinner_base.py +29 -0
- code_puppy/messaging/subagent_console.py +461 -0
- code_puppy/model_factory.py +686 -80
- code_puppy/model_utils.py +167 -0
- code_puppy/models.json +86 -104
- 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 +51 -0
- 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 +10 -15
- code_puppy/session_storage.py +294 -0
- code_puppy/status_display.py +21 -4
- code_puppy/summarization_agent.py +52 -14
- code_puppy/terminal_utils.py +418 -0
- code_puppy/tools/__init__.py +139 -6
- code_puppy/tools/agent_tools.py +548 -49
- code_puppy/tools/browser/__init__.py +37 -0
- code_puppy/tools/browser/browser_control.py +289 -0
- code_puppy/tools/browser/browser_interactions.py +545 -0
- code_puppy/tools/browser/browser_locators.py +640 -0
- code_puppy/tools/browser/browser_manager.py +316 -0
- code_puppy/tools/browser/browser_navigation.py +251 -0
- code_puppy/tools/browser/browser_screenshot.py +179 -0
- code_puppy/tools/browser/browser_scripts.py +462 -0
- code_puppy/tools/browser/browser_workflows.py +221 -0
- 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 +941 -153
- code_puppy/tools/common.py +1146 -6
- code_puppy/tools/display.py +84 -0
- code_puppy/tools/file_modifications.py +288 -89
- code_puppy/tools/file_operations.py +352 -266
- 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.169.dist-info → code_puppy-0.0.366.dist-info}/METADATA +184 -67
- code_puppy-0.0.366.dist-info/RECORD +217 -0
- {code_puppy-0.0.169.dist-info → code_puppy-0.0.366.dist-info}/WHEEL +1 -1
- {code_puppy-0.0.169.dist-info → code_puppy-0.0.366.dist-info}/entry_points.txt +1 -0
- code_puppy/agent.py +0 -231
- code_puppy/agents/agent_orchestrator.json +0 -26
- code_puppy/agents/runtime_manager.py +0 -272
- code_puppy/command_line/mcp/add_command.py +0 -183
- code_puppy/command_line/meta_command_handler.py +0 -153
- code_puppy/message_history_processor.py +0 -490
- code_puppy/messaging/spinner/textual_spinner.py +0 -101
- code_puppy/state_management.py +0 -200
- code_puppy/tui/__init__.py +0 -10
- code_puppy/tui/app.py +0 -986
- code_puppy/tui/components/__init__.py +0 -21
- code_puppy/tui/components/chat_view.py +0 -550
- 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 -182
- 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 -15
- 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 -290
- code_puppy/tui/screens/tools.py +0 -74
- code_puppy-0.0.169.data/data/code_puppy/models.json +0 -128
- code_puppy-0.0.169.dist-info/RECORD +0 -112
- /code_puppy/{mcp → mcp_}/circuit_breaker.py +0 -0
- /code_puppy/{mcp → mcp_}/error_isolation.py +0 -0
- /code_puppy/{mcp → mcp_}/health_monitor.py +0 -0
- /code_puppy/{mcp → mcp_}/retry_manager.py +0 -0
- /code_puppy/{mcp → mcp_}/status_tracker.py +0 -0
- /code_puppy/{mcp → mcp_}/system_tools.py +0 -0
- {code_puppy-0.0.169.dist-info → code_puppy-0.0.366.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Chat message data model.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from dataclasses import dataclass
|
|
6
|
-
from datetime import datetime
|
|
7
|
-
from typing import Any, Dict
|
|
8
|
-
|
|
9
|
-
from .enums import MessageType
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
@dataclass
|
|
13
|
-
class ChatMessage:
|
|
14
|
-
"""Represents a message in the chat interface."""
|
|
15
|
-
|
|
16
|
-
id: str
|
|
17
|
-
type: MessageType
|
|
18
|
-
content: str
|
|
19
|
-
timestamp: datetime
|
|
20
|
-
metadata: Dict[str, Any] = None
|
|
21
|
-
group_id: str = None
|
|
22
|
-
|
|
23
|
-
def __post_init__(self):
|
|
24
|
-
if self.metadata is None:
|
|
25
|
-
self.metadata = {}
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Command history reader for TUI history tab.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
import os
|
|
6
|
-
import re
|
|
7
|
-
from datetime import datetime
|
|
8
|
-
from typing import Dict, List
|
|
9
|
-
|
|
10
|
-
from code_puppy.config import COMMAND_HISTORY_FILE
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class HistoryFileReader:
|
|
14
|
-
"""Reads and parses the command history file for display in the TUI history tab."""
|
|
15
|
-
|
|
16
|
-
def __init__(self, history_file_path: str = COMMAND_HISTORY_FILE):
|
|
17
|
-
"""Initialize the history file reader.
|
|
18
|
-
|
|
19
|
-
Args:
|
|
20
|
-
history_file_path: Path to the command history file. Defaults to the standard location.
|
|
21
|
-
"""
|
|
22
|
-
self.history_file_path = history_file_path
|
|
23
|
-
self._timestamp_pattern = re.compile(
|
|
24
|
-
r"^# (\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})"
|
|
25
|
-
)
|
|
26
|
-
|
|
27
|
-
def read_history(self, max_entries: int = 100) -> List[Dict[str, str]]:
|
|
28
|
-
"""Read command history from the history file.
|
|
29
|
-
|
|
30
|
-
Args:
|
|
31
|
-
max_entries: Maximum number of entries to read. Defaults to 100.
|
|
32
|
-
|
|
33
|
-
Returns:
|
|
34
|
-
List of history entries with timestamp and command, most recent first.
|
|
35
|
-
"""
|
|
36
|
-
if not os.path.exists(self.history_file_path):
|
|
37
|
-
return []
|
|
38
|
-
|
|
39
|
-
try:
|
|
40
|
-
with open(self.history_file_path, "r") as f:
|
|
41
|
-
content = f.read()
|
|
42
|
-
|
|
43
|
-
# Split content by timestamp marker
|
|
44
|
-
raw_chunks = re.split(r"(# \d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2})", content)
|
|
45
|
-
|
|
46
|
-
# Filter out empty chunks
|
|
47
|
-
chunks = [chunk for chunk in raw_chunks if chunk.strip()]
|
|
48
|
-
|
|
49
|
-
entries = []
|
|
50
|
-
|
|
51
|
-
# Process chunks in pairs (timestamp and command)
|
|
52
|
-
i = 0
|
|
53
|
-
while i < len(chunks) - 1:
|
|
54
|
-
if self._timestamp_pattern.match(chunks[i]):
|
|
55
|
-
timestamp = self._timestamp_pattern.match(chunks[i]).group(1)
|
|
56
|
-
command_text = chunks[i + 1].strip()
|
|
57
|
-
|
|
58
|
-
if command_text: # Skip empty commands
|
|
59
|
-
entries.append(
|
|
60
|
-
{"timestamp": timestamp, "command": command_text}
|
|
61
|
-
)
|
|
62
|
-
|
|
63
|
-
i += 2
|
|
64
|
-
else:
|
|
65
|
-
# Skip invalid chunks
|
|
66
|
-
i += 1
|
|
67
|
-
|
|
68
|
-
# Limit the number of entries and reverse to get most recent first
|
|
69
|
-
return entries[-max_entries:][::-1]
|
|
70
|
-
|
|
71
|
-
except Exception:
|
|
72
|
-
# Return empty list on any error
|
|
73
|
-
return []
|
|
74
|
-
|
|
75
|
-
def format_timestamp(self, timestamp: str, format_str: str = "%H:%M:%S") -> str:
|
|
76
|
-
"""Format a timestamp string for display.
|
|
77
|
-
|
|
78
|
-
Args:
|
|
79
|
-
timestamp: ISO format timestamp string (YYYY-MM-DDThh:mm:ss)
|
|
80
|
-
format_str: Format string for datetime.strftime
|
|
81
|
-
|
|
82
|
-
Returns:
|
|
83
|
-
Formatted timestamp string
|
|
84
|
-
"""
|
|
85
|
-
try:
|
|
86
|
-
dt = datetime.fromisoformat(timestamp)
|
|
87
|
-
return dt.strftime(format_str)
|
|
88
|
-
except (ValueError, TypeError):
|
|
89
|
-
return timestamp
|
code_puppy/tui/models/enums.py
DELETED
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Enums for the TUI module.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from enum import Enum
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class MessageType(Enum):
|
|
9
|
-
"""Types of messages in the chat interface."""
|
|
10
|
-
|
|
11
|
-
USER = "user"
|
|
12
|
-
AGENT = "agent"
|
|
13
|
-
SYSTEM = "system"
|
|
14
|
-
ERROR = "error"
|
|
15
|
-
DIVIDER = "divider"
|
|
16
|
-
INFO = "info"
|
|
17
|
-
SUCCESS = "success"
|
|
18
|
-
WARNING = "warning"
|
|
19
|
-
TOOL_OUTPUT = "tool_output"
|
|
20
|
-
COMMAND_OUTPUT = "command_output"
|
|
21
|
-
|
|
22
|
-
AGENT_REASONING = "agent_reasoning"
|
|
23
|
-
PLANNED_NEXT_STEPS = "planned_next_steps"
|
|
24
|
-
AGENT_RESPONSE = "agent_response"
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
TUI screens package.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from .help import HelpScreen
|
|
6
|
-
from .mcp_install_wizard import MCPInstallWizardScreen
|
|
7
|
-
from .settings import SettingsScreen
|
|
8
|
-
from .tools import ToolsScreen
|
|
9
|
-
|
|
10
|
-
__all__ = [
|
|
11
|
-
"HelpScreen",
|
|
12
|
-
"SettingsScreen",
|
|
13
|
-
"ToolsScreen",
|
|
14
|
-
"MCPInstallWizardScreen",
|
|
15
|
-
]
|
code_puppy/tui/screens/help.py
DELETED
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
Help modal screen.
|
|
3
|
-
"""
|
|
4
|
-
|
|
5
|
-
from textual import on
|
|
6
|
-
from textual.app import ComposeResult
|
|
7
|
-
from textual.containers import Container, VerticalScroll
|
|
8
|
-
from textual.screen import ModalScreen
|
|
9
|
-
from textual.widgets import Button, Static
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
class HelpScreen(ModalScreen):
|
|
13
|
-
"""Help modal screen."""
|
|
14
|
-
|
|
15
|
-
DEFAULT_CSS = """
|
|
16
|
-
HelpScreen {
|
|
17
|
-
align: center middle;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
#help-dialog {
|
|
21
|
-
width: 80;
|
|
22
|
-
height: 30;
|
|
23
|
-
border: thick $primary;
|
|
24
|
-
background: $surface;
|
|
25
|
-
padding: 1;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
#help-content {
|
|
29
|
-
height: 1fr;
|
|
30
|
-
margin: 0 0 1 0;
|
|
31
|
-
overflow-y: auto;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
#help-buttons {
|
|
35
|
-
layout: horizontal;
|
|
36
|
-
height: 3;
|
|
37
|
-
align: center middle;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
#dismiss-button {
|
|
41
|
-
margin: 0 1;
|
|
42
|
-
}
|
|
43
|
-
"""
|
|
44
|
-
|
|
45
|
-
def compose(self) -> ComposeResult:
|
|
46
|
-
with Container(id="help-dialog"):
|
|
47
|
-
yield Static("📚 Code Puppy TUI Help", id="help-title")
|
|
48
|
-
with VerticalScroll(id="help-content"):
|
|
49
|
-
yield Static(self.get_help_content(), id="help-text")
|
|
50
|
-
with Container(id="help-buttons"):
|
|
51
|
-
yield Button("Dismiss", id="dismiss-button", variant="primary")
|
|
52
|
-
|
|
53
|
-
def get_help_content(self) -> str:
|
|
54
|
-
"""Get the help content text."""
|
|
55
|
-
try:
|
|
56
|
-
# Get terminal width for responsive help
|
|
57
|
-
terminal_width = self.app.size.width if hasattr(self.app, "size") else 80
|
|
58
|
-
except Exception:
|
|
59
|
-
terminal_width = 80
|
|
60
|
-
|
|
61
|
-
if terminal_width < 60:
|
|
62
|
-
# Compact help for narrow terminals
|
|
63
|
-
return """
|
|
64
|
-
Code Puppy TUI (Compact Mode):
|
|
65
|
-
|
|
66
|
-
Controls:
|
|
67
|
-
- Enter: Send message
|
|
68
|
-
- Ctrl+Enter: New line
|
|
69
|
-
- Ctrl+Q: Quit
|
|
70
|
-
- Ctrl+2: Toggle History
|
|
71
|
-
- Ctrl+3: Settings
|
|
72
|
-
- Ctrl+4: Tools
|
|
73
|
-
- Ctrl+5: Focus prompt
|
|
74
|
-
- Ctrl+6: Focus response
|
|
75
|
-
|
|
76
|
-
Use this help for full details.
|
|
77
|
-
"""
|
|
78
|
-
else:
|
|
79
|
-
# Full help text
|
|
80
|
-
return """
|
|
81
|
-
Code Puppy TUI Help:
|
|
82
|
-
|
|
83
|
-
Input Controls:
|
|
84
|
-
- Enter: Send message
|
|
85
|
-
- ALT+Enter: New line (multi-line input)
|
|
86
|
-
- Standard text editing shortcuts supported
|
|
87
|
-
|
|
88
|
-
Keyboard Shortcuts:
|
|
89
|
-
- Ctrl+Q/Ctrl+C: Quit application
|
|
90
|
-
- Ctrl+L: Clear chat history
|
|
91
|
-
- Ctrl+1: Show this help
|
|
92
|
-
- Ctrl+2: Toggle History
|
|
93
|
-
- Ctrl+3: Open settings
|
|
94
|
-
- Ctrl+4: Tools
|
|
95
|
-
- Ctrl+5: Focus prompt (input field)
|
|
96
|
-
- Ctrl+6: Focus response (chat area)
|
|
97
|
-
|
|
98
|
-
Chat Navigation:
|
|
99
|
-
- Ctrl+Up/Down: Scroll chat up/down
|
|
100
|
-
- Ctrl+Home: Scroll to top
|
|
101
|
-
- Ctrl+End: Scroll to bottom
|
|
102
|
-
|
|
103
|
-
Commands:
|
|
104
|
-
- /clear: Clear chat history
|
|
105
|
-
- /m <model>: Switch model
|
|
106
|
-
- /cd <dir>: Change directory
|
|
107
|
-
- /help: Show help
|
|
108
|
-
- /status: Show current status
|
|
109
|
-
|
|
110
|
-
Use the input area at the bottom to type messages.
|
|
111
|
-
Press Ctrl+2 to view History when needed.
|
|
112
|
-
Agent responses support syntax highlighting for code blocks.
|
|
113
|
-
Press Ctrl+3 to access all configuration settings.
|
|
114
|
-
|
|
115
|
-
Copy Feature:
|
|
116
|
-
- 📋 Copy buttons appear after agent responses
|
|
117
|
-
- Click or press Enter/Space on copy button to copy content
|
|
118
|
-
- Raw markdown content is copied to clipboard
|
|
119
|
-
- Visual feedback shows copy success/failure
|
|
120
|
-
"""
|
|
121
|
-
|
|
122
|
-
@on(Button.Pressed, "#dismiss-button")
|
|
123
|
-
def dismiss_help(self) -> None:
|
|
124
|
-
"""Dismiss the help modal."""
|
|
125
|
-
self.dismiss()
|
|
126
|
-
|
|
127
|
-
def on_key(self, event) -> None:
|
|
128
|
-
"""Handle key events."""
|
|
129
|
-
if event.key == "escape":
|
|
130
|
-
self.dismiss()
|