tunacode-cli 0.0.53__py3-none-any.whl → 0.0.55__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 tunacode-cli might be problematic. Click here for more details.

@@ -1,9 +1,7 @@
1
1
  """Key binding handlers for TunaCode UI."""
2
2
 
3
3
  import logging
4
- import time
5
4
 
6
- from prompt_toolkit.application import run_in_terminal
7
5
  from prompt_toolkit.key_binding import KeyBindings
8
6
 
9
7
  from ..core.state import StateManager
@@ -32,38 +30,12 @@ def create_key_bindings(state_manager: StateManager = None) -> KeyBindings:
32
30
 
33
31
  @kb.add("escape")
34
32
  def _escape(event):
35
- """Handle ESC key with double-press logic: first press warns, second cancels."""
36
- if not state_manager:
37
- logger.debug("Escape key pressed without state manager")
38
- return
33
+ """Handle ESC key - raises KeyboardInterrupt for unified abort handling."""
34
+ logger.debug("ESC key pressed - raising KeyboardInterrupt")
39
35
 
40
- current_time = time.time()
41
- session = state_manager.session
42
-
43
- # Reset counter if too much time has passed (3 seconds timeout)
44
- if session.last_esc_time and (current_time - session.last_esc_time) > 3.0:
45
- session.esc_press_count = 0
46
-
47
- session.esc_press_count = (session.esc_press_count or 0) + 1
48
- session.last_esc_time = current_time
49
-
50
- logger.debug(f"ESC key pressed: count={session.esc_press_count}, time={current_time}")
51
-
52
- if session.esc_press_count == 1:
53
- # First ESC press - show warning message
54
- from ..ui.output import warning
55
-
56
- run_in_terminal(lambda: warning("Hit ESC again within 3 seconds to cancel operation"))
57
- logger.debug("First ESC press - showing warning")
58
- else:
59
- # Second ESC press - cancel operation
60
- session.esc_press_count = 0 # Reset counter
61
- logger.debug("Second ESC press - initiating cancellation")
62
-
63
- # Mark the session as being cancelled to prevent new operations
64
- session.operation_cancelled = True
65
-
66
- current_task = session.current_task
36
+ # Cancel any active task if present
37
+ if state_manager and hasattr(state_manager.session, "current_task"):
38
+ current_task = state_manager.session.current_task
67
39
  if current_task and not current_task.done():
68
40
  logger.debug(f"Cancelling current task: {current_task}")
69
41
  try:
@@ -71,12 +43,8 @@ def create_key_bindings(state_manager: StateManager = None) -> KeyBindings:
71
43
  logger.debug("Task cancellation initiated successfully")
72
44
  except Exception as e:
73
45
  logger.debug(f"Failed to cancel task: {e}")
74
- else:
75
- logger.debug(f"No active task to cancel: current_task={current_task}")
76
46
 
77
- # Force exit the current input by raising KeyboardInterrupt
78
- # This will be caught by the prompt manager and converted to UserAbortError
79
- logger.debug("Raising KeyboardInterrupt to abort current operation")
80
- raise KeyboardInterrupt()
47
+ # Raise KeyboardInterrupt to trigger unified abort handling in REPL
48
+ raise KeyboardInterrupt()
81
49
 
82
50
  return kb
tunacode/ui/output.py CHANGED
@@ -1,5 +1,7 @@
1
1
  """Output and display functions for TunaCode UI."""
2
2
 
3
+ from typing import Optional
4
+
3
5
  from prompt_toolkit.application import run_in_terminal
4
6
  from rich.console import Console
5
7
  from rich.padding import Padding
@@ -109,20 +111,39 @@ async def show_update_message(latest_version: str) -> None:
109
111
  await update_available(latest_version)
110
112
 
111
113
 
112
- async def spinner(show: bool = True, spinner_obj=None, state_manager: StateManager = None):
113
- """Manage a spinner display."""
114
+ async def spinner(
115
+ show: bool = True,
116
+ spinner_obj=None,
117
+ state_manager: StateManager = None,
118
+ message: Optional[str] = None,
119
+ ):
120
+ """Manage a spinner display with dynamic message support.
121
+
122
+ Args:
123
+ show: Whether to show (True) or hide (False) the spinner
124
+ spinner_obj: Existing spinner object to reuse
125
+ state_manager: State manager instance for storing spinner
126
+ message: Optional custom message to display (uses UI_THINKING_MESSAGE if None)
127
+
128
+ Returns:
129
+ The spinner object for further manipulation
130
+ """
114
131
  icon = SPINNER_TYPE
115
- message = UI_THINKING_MESSAGE
132
+ display_message = message or UI_THINKING_MESSAGE
116
133
 
117
134
  # Get spinner from state manager if available
118
135
  if spinner_obj is None and state_manager:
119
136
  spinner_obj = state_manager.session.spinner
120
137
 
121
138
  if not spinner_obj:
122
- spinner_obj = await run_in_terminal(lambda: console.status(message, spinner=icon))
139
+ spinner_obj = await run_in_terminal(lambda: console.status(display_message, spinner=icon))
123
140
  # Store it back in state manager if available
124
141
  if state_manager:
125
142
  state_manager.session.spinner = spinner_obj
143
+ else:
144
+ # Update existing spinner message if provided
145
+ if message and hasattr(spinner_obj, "update"):
146
+ spinner_obj.update(display_message)
126
147
 
127
148
  if show:
128
149
  spinner_obj.start()
@@ -132,6 +153,20 @@ async def spinner(show: bool = True, spinner_obj=None, state_manager: StateManag
132
153
  return spinner_obj
133
154
 
134
155
 
156
+ async def update_spinner_message(message: str, state_manager: StateManager = None):
157
+ """Update the spinner message if a spinner is active.
158
+
159
+ Args:
160
+ message: New message to display
161
+ state_manager: State manager instance containing spinner
162
+ """
163
+ if state_manager and state_manager.session.spinner:
164
+ spinner_obj = state_manager.session.spinner
165
+ if hasattr(spinner_obj, "update"):
166
+ # Rich's Status object supports update method
167
+ await run_in_terminal(lambda: spinner_obj.update(message))
168
+
169
+
135
170
  def get_context_window_display(total_tokens: int, max_tokens: int) -> str:
136
171
  """
137
172
  Create a color-coded display for the context window status.
tunacode/ui/panels.py CHANGED
@@ -1,5 +1,7 @@
1
1
  """Panel display functions for TunaCode UI."""
2
2
 
3
+ import asyncio
4
+ import time
3
5
  from typing import Any, Optional, Union
4
6
 
5
7
  from rich.box import ROUNDED
@@ -81,11 +83,24 @@ async def agent(text: str, bottom: int = 1) -> None:
81
83
  class StreamingAgentPanel:
82
84
  """Streaming agent panel using Rich.Live for progressive display."""
83
85
 
86
+ bottom: int
87
+ title: str
88
+ content: str
89
+ live: Optional[Live]
90
+ _last_update_time: float
91
+ _dots_task: Optional[asyncio.Task]
92
+ _dots_count: int
93
+ _show_dots: bool
94
+
84
95
  def __init__(self, bottom: int = 1):
85
96
  self.bottom = bottom
86
97
  self.title = f"[bold {colors.primary}]●[/bold {colors.primary}] {APP_NAME}"
87
98
  self.content = ""
88
99
  self.live = None
100
+ self._last_update_time = 0.0
101
+ self._dots_task = None
102
+ self._dots_count = 0
103
+ self._show_dots = False
89
104
 
90
105
  def _create_panel(self) -> Padding:
91
106
  """Create a Rich panel with current content."""
@@ -94,11 +109,19 @@ class StreamingAgentPanel:
94
109
 
95
110
  from tunacode.constants import UI_THINKING_MESSAGE
96
111
 
97
- # Handle the default thinking message with Rich markup
112
+ # Show "Thinking..." only when no content has arrived yet
98
113
  if not self.content:
99
114
  content_renderable: Union[Text, Markdown] = Text.from_markup(UI_THINKING_MESSAGE)
100
115
  else:
101
- content_renderable = Markdown(self.content)
116
+ # Once we have content, show it with optional dots animation
117
+ display_content = self.content
118
+ # Add animated dots if we're waiting for more content
119
+ if self._show_dots:
120
+ # Cycle through: "", ".", "..", "..."
121
+ dots_patterns = ["", ".", "..", "..."]
122
+ dots = dots_patterns[self._dots_count % len(dots_patterns)]
123
+ display_content = self.content.rstrip() + dots
124
+ content_renderable = Markdown(display_content)
102
125
  panel_obj = Panel(
103
126
  Padding(content_renderable, (0, 1, 0, 1)),
104
127
  title=f"[bold]{self.title}[/bold]",
@@ -117,12 +140,30 @@ class StreamingAgentPanel:
117
140
  ),
118
141
  )
119
142
 
143
+ async def _animate_dots(self):
144
+ """Animate dots after a pause in streaming."""
145
+ while True:
146
+ await asyncio.sleep(0.5)
147
+ current_time = time.time()
148
+ # Only show dots after 1 second of no updates
149
+ if current_time - self._last_update_time > 1.0:
150
+ self._show_dots = True
151
+ self._dots_count += 1
152
+ if self.live:
153
+ self.live.update(self._create_panel())
154
+ else:
155
+ self._show_dots = False
156
+ self._dots_count = 0
157
+
120
158
  async def start(self):
121
159
  """Start the live streaming display."""
122
160
  from .output import console
123
161
 
124
162
  self.live = Live(self._create_panel(), console=console, refresh_per_second=4)
125
163
  self.live.start()
164
+ self._last_update_time = time.time()
165
+ # Start the dots animation task
166
+ self._dots_task = asyncio.create_task(self._animate_dots())
126
167
 
127
168
  async def update(self, content_chunk: str):
128
169
  """Update the streaming display with new content."""
@@ -131,6 +172,11 @@ class StreamingAgentPanel:
131
172
  content_chunk = ""
132
173
  # Ensure type safety for concatenation
133
174
  self.content = (self.content or "") + str(content_chunk)
175
+
176
+ # Reset the update timer when we get new content
177
+ self._last_update_time = time.time()
178
+ self._show_dots = False # Hide dots immediately when new content arrives
179
+
134
180
  if self.live:
135
181
  self.live.update(self._create_panel())
136
182
 
@@ -142,6 +188,14 @@ class StreamingAgentPanel:
142
188
 
143
189
  async def stop(self):
144
190
  """Stop the live streaming display."""
191
+ # Cancel the dots animation task
192
+ if self._dots_task:
193
+ self._dots_task.cancel()
194
+ try:
195
+ await self._dots_task
196
+ except asyncio.CancelledError:
197
+ pass
198
+
145
199
  if self.live:
146
200
  # Get the console before stopping the live display
147
201
  from .output import console
@@ -0,0 +1,115 @@
1
+ """Tool description mappings for user-friendly spinner messages."""
2
+
3
+ from typing import Dict, Optional
4
+
5
+
6
+ def get_tool_description(tool_name: str, args: Optional[Dict] = None) -> str:
7
+ """
8
+ Get a human-readable description for a tool execution.
9
+
10
+ Args:
11
+ tool_name: Name of the tool being executed
12
+ args: Optional tool arguments for more specific descriptions
13
+
14
+ Returns:
15
+ User-friendly description of the tool operation
16
+ """
17
+ # Base descriptions for each tool
18
+ base_descriptions = {
19
+ # File operations
20
+ "read_file": "Reading file",
21
+ "write_file": "Writing file",
22
+ "update_file": "Updating file",
23
+ "create_file": "Creating file",
24
+ "delete_file": "Deleting file",
25
+ # Directory operations
26
+ "list_dir": "Listing directory",
27
+ "create_dir": "Creating directory",
28
+ "delete_dir": "Deleting directory",
29
+ # Search operations
30
+ "grep": "Searching files",
31
+ "glob": "Finding files",
32
+ "find_files": "Searching for files",
33
+ # Code operations
34
+ "run_command": "Executing command",
35
+ "bash": "Running shell command",
36
+ "python": "Executing Python code",
37
+ # Analysis operations
38
+ "analyze_code": "Analyzing code",
39
+ "lint": "Running linter",
40
+ "format_code": "Formatting code",
41
+ # Version control
42
+ "git_status": "Checking git status",
43
+ "git_diff": "Getting git diff",
44
+ "git_commit": "Creating git commit",
45
+ # Testing
46
+ "run_tests": "Running tests",
47
+ "test": "Executing tests",
48
+ # Documentation
49
+ "generate_docs": "Generating documentation",
50
+ "update_docs": "Updating documentation",
51
+ # Default
52
+ "unknown": "Processing",
53
+ }
54
+
55
+ # Get base description
56
+ base_desc = base_descriptions.get(tool_name, f"Executing {tool_name}")
57
+
58
+ # Add specific details from args if available
59
+ if args:
60
+ if tool_name == "read_file" and "file_path" in args:
61
+ return f"{base_desc}: {args['file_path']}"
62
+ elif tool_name == "write_file" and "file_path" in args:
63
+ return f"{base_desc}: {args['file_path']}"
64
+ elif tool_name == "update_file" and "file_path" in args:
65
+ return f"{base_desc}: {args['file_path']}"
66
+ elif tool_name == "list_dir" and "directory" in args:
67
+ return f"{base_desc}: {args['directory']}"
68
+ elif tool_name == "grep" and "pattern" in args:
69
+ pattern = args["pattern"]
70
+ # Truncate long patterns
71
+ if len(pattern) > 30:
72
+ pattern = pattern[:27] + "..."
73
+ return f"{base_desc} for: {pattern}"
74
+ elif tool_name == "glob" and "pattern" in args:
75
+ return f"{base_desc}: {args['pattern']}"
76
+ elif tool_name == "run_command" and "command" in args:
77
+ cmd = args["command"]
78
+ # Truncate long commands
79
+ if len(cmd) > 40:
80
+ cmd = cmd[:37] + "..."
81
+ return f"{base_desc}: {cmd}"
82
+ elif tool_name == "bash" and "command" in args:
83
+ cmd = args["command"]
84
+ if len(cmd) > 40:
85
+ cmd = cmd[:37] + "..."
86
+ return f"{base_desc}: {cmd}"
87
+
88
+ return base_desc
89
+
90
+
91
+ def get_batch_description(tool_count: int, tool_names: Optional[list] = None) -> str:
92
+ """
93
+ Get a description for batch tool execution.
94
+
95
+ Args:
96
+ tool_count: Number of tools being executed
97
+ tool_names: Optional list of tool names for more detail
98
+
99
+ Returns:
100
+ Description of the batch operation
101
+ """
102
+ if tool_count == 1:
103
+ return "Executing 1 tool"
104
+
105
+ if tool_names and len(set(tool_names)) == 1:
106
+ # All tools are the same type
107
+ tool_type = tool_names[0]
108
+ if tool_type == "read_file":
109
+ return f"Reading {tool_count} files in parallel"
110
+ elif tool_type == "grep":
111
+ return f"Searching {tool_count} patterns in parallel"
112
+ elif tool_type == "list_dir":
113
+ return f"Listing {tool_count} directories in parallel"
114
+
115
+ return f"Executing {tool_count} tools in parallel"
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tunacode-cli
3
- Version: 0.0.53
3
+ Version: 0.0.55
4
4
  Summary: Your agentic CLI developer.
5
5
  Author-email: larock22 <noreply@github.com>
6
6
  License: MIT
@@ -1,5 +1,5 @@
1
1
  tunacode/__init__.py,sha256=yUul8igNYMfUrHnYfioIGAqvrH8b5BKiO_pt1wVnmd0,119
2
- tunacode/constants.py,sha256=PTd740UJlY1KKeK6DZRirEY1nPpCjZits6ZeZ9p41uc,5968
2
+ tunacode/constants.py,sha256=nNS_4fOgxWjzUxnCm-FBXgfVRifwFytkt7yICn7eL1I,5968
3
3
  tunacode/context.py,sha256=YtfRjUiqsSkk2k9Nn_pjb_m-AXyh6XcOBOJWtFI0wVw,2405
4
4
  tunacode/exceptions.py,sha256=oDO1SVKOgjcKIylwqdbqh_g5my4roU5mB9Nv4n_Vb0s,3877
5
5
  tunacode/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -7,10 +7,10 @@ tunacode/setup.py,sha256=a5S-uGkVYoBTvH9nsqMBgAFoH4CILOgfKvgS30qGnoU,1978
7
7
  tunacode/types.py,sha256=bCJ0mq1iQKa42fhBN5Pimkx0FV0f2J3-qRzbMzFhmBw,8499
8
8
  tunacode/cli/__init__.py,sha256=zgs0UbAck8hfvhYsWhWOfBe5oK09ug2De1r4RuQZREA,55
9
9
  tunacode/cli/main.py,sha256=4MF4nGEU-CB83ckIl85AY-015EeUJHrE_UdbuSa9wCU,2968
10
- tunacode/cli/repl.py,sha256=gEepV-vD0iH0rdRkz0DeLmyoHhJSlbZCMonRda4nraQ,15841
11
- tunacode/cli/commands/__init__.py,sha256=zmE9JcJ9Qd2xJhgdS4jMDJOoZsrAZmL5MAFxbKkk7F8,1670
10
+ tunacode/cli/repl.py,sha256=GMEvDW8LP1iM-bwOY83BviYk0fMngDJiZiI3f28CHwo,16327
11
+ tunacode/cli/commands/__init__.py,sha256=7rPwGkdYbPUgf__cPVX9oQUJOPQ18MdxDT_I64crdak,1740
12
12
  tunacode/cli/commands/base.py,sha256=Ge_lNQA-GDfcb1Ap1oznCH3UrifBiHH3bA9DNL-tCDw,2519
13
- tunacode/cli/commands/registry.py,sha256=XgewkwpljAl9MYemKpWrOW2pSm9uGOPrDKckqcstDY4,9267
13
+ tunacode/cli/commands/registry.py,sha256=Xmfb4qRZ1wvT-3OggGsuDxpXlCykuhOkSBberysj1SE,9345
14
14
  tunacode/cli/commands/template_shortcut.py,sha256=ApYTPkDVBRaLxa7rWaPrsGcJdkR7eg09k18KyTjYg_E,3447
15
15
  tunacode/cli/commands/implementations/__init__.py,sha256=DHjQm1f14OV1go0ZyqacFa3yfnGWH7LZFbZVVQZ5Iw0,1011
16
16
  tunacode/cli/commands/implementations/conversation.py,sha256=ZijCNaRi1p5v1Q-IaVHtU2_BripSW3JCVKTtqFkOUjg,4676
@@ -24,28 +24,30 @@ tunacode/cli/repl_components/__init__.py,sha256=5ZjPJ3yUvZ5x6Vg9EYJ03-tdxfEEdmfr
24
24
  tunacode/cli/repl_components/command_parser.py,sha256=SuDRP-nt8Sq5klI4-tXkllN_4nVzji5VJ-dQvbxDmDw,880
25
25
  tunacode/cli/repl_components/error_recovery.py,sha256=yPoWXzuMi6B_Pwlm1wnFIJV55lJEOChvHGDca4XtoVI,3064
26
26
  tunacode/cli/repl_components/output_display.py,sha256=SGhP7Hc1ymfZf-AvrkELgdJCZ3UVEzTx2Y6W737zdoY,816
27
- tunacode/cli/repl_components/tool_executor.py,sha256=TrB1tNAKsKdumL8l0yOJikA7BgSE1rBD42bKfVwl10I,2995
27
+ tunacode/cli/repl_components/tool_executor.py,sha256=p5oSpoO0qkiKr9fsgIQVSXCv6ZiSWk8QtPb_x7IpKhE,3147
28
28
  tunacode/configuration/__init__.py,sha256=MbVXy8bGu0yKehzgdgZ_mfWlYGvIdb1dY2Ly75nfuPE,17
29
29
  tunacode/configuration/defaults.py,sha256=5TUeSqMTeA7kW7gz9hND_H4s9Key0_khPvc6mNFMlZc,838
30
30
  tunacode/configuration/models.py,sha256=buH8ZquvcYI3OQBDIZeJ08cu00rSCeNABtUwl3VQS0E,4103
31
31
  tunacode/configuration/settings.py,sha256=9wtIWBlLhW_ZBlLx-GA4XDfVZyGj2Gs6Zk49vk-nHq0,1047
32
32
  tunacode/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
33
  tunacode/core/code_index.py,sha256=jgAx3lSWP_DwnyiP5Jkm1YvX4JJyI4teMzlNrJSpEOA,15661
34
- tunacode/core/state.py,sha256=pjrJgjqdQF3JTb4nFERVGl-idlYsQIMfNGct0qfbEu0,6162
34
+ tunacode/core/state.py,sha256=RGBTOHTpe4z42MbIjRKhGNz9MIGyY0QbpdDJMldm53o,6284
35
35
  tunacode/core/tool_handler.py,sha256=FqA3w8M_fhpyOQKJIgl_8MAhSFVEguufbZH6gm_b7NI,2932
36
36
  tunacode/core/agents/__init__.py,sha256=UUJiPYb91arwziSpjd7vIk7XNGA_4HQbsOIbskSqevA,149
37
- tunacode/core/agents/main.py,sha256=6mvdtqmYs_hA4drZa6MFF5w8RUc5bTiwbs7TNsuPyzQ,28964
37
+ tunacode/core/agents/main.py,sha256=myz_K2lxqYH8pQdbw8n8bai8F40Mqfj-kTLagPR1dP4,18253
38
38
  tunacode/core/agents/utils.py,sha256=dJsdbvWs48vxQpwAtUjJLMj7_huv12Mx3E2CEgwoK94,14467
39
- tunacode/core/agents/agent_components/__init__.py,sha256=V9C_BDKumgA8OZf69NJ1J_v6jbzCtn9gqdFiC1l0RZw,911
39
+ tunacode/core/agents/agent_components/__init__.py,sha256=CL4XH47T6v_iYy7xCPYjyiEFNOFnkcKwbTuKw6IjKTs,1474
40
40
  tunacode/core/agents/agent_components/agent_config.py,sha256=6m2RBZ7Y-0p_KFBVmfPW4ZGLGzTAw3YFQ4i94qsqEpM,4373
41
+ tunacode/core/agents/agent_components/agent_helpers.py,sha256=G3zF5GPRzBhA3yOcsXf8gar892ackGDcwFk9wM6FA9s,8119
41
42
  tunacode/core/agents/agent_components/json_tool_parser.py,sha256=HuyNT0rs-ppx_gLAI2e0XMVGbR_F0WXZfP3sx38VoMg,3447
42
43
  tunacode/core/agents/agent_components/message_handler.py,sha256=KJGOtb9VhumgZpxxwO45HrKLhU9_MwuoWRsSQwJviNU,3704
43
- tunacode/core/agents/agent_components/node_processor.py,sha256=hl5n0M1QgBNbFB9-ME1otyw4se9MVVHbwh98lFK9p2A,21002
44
+ tunacode/core/agents/agent_components/node_processor.py,sha256=FmjIEJWkqc0uzRfgTINv8uJwKG7-w00mV5lgOS4Jcd8,20426
44
45
  tunacode/core/agents/agent_components/response_state.py,sha256=_C2loLeyZHMFHwjGny4h0dI02UoFJcJAVaabkh9H9JQ,343
45
46
  tunacode/core/agents/agent_components/result_wrapper.py,sha256=9CFK0wpsfZx2WT4PBHfkSv22GxL1gAQuUYVMlmYtCJU,1761
46
47
  tunacode/core/agents/agent_components/task_completion.py,sha256=BSnjNEFbxlzgzcXdjdTVGeCr1RpCiAaEp_D7f5FXa5Q,819
47
48
  tunacode/core/agents/agent_components/tool_buffer.py,sha256=09FNtC6zTjiJOL_2CY0b7KDgwdNayGPV6jbENKH6Unc,766
48
49
  tunacode/core/agents/agent_components/tool_executor.py,sha256=LlzDwgSLLawwPZQqJ4vfLf-16nhwIiuN8zm8iCeBf1Y,1849
50
+ tunacode/core/agents/agent_components/truncation_checker.py,sha256=XbJ3wwtdC4NhgIMIvFR0z_cfNnYMkiYAZo9zGDBPU8Y,2685
49
51
  tunacode/core/background/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
52
  tunacode/core/background/manager.py,sha256=AxNcuuE7T2pqeI2lLIGJgaS_jEw60YzBfZY9EOY54fc,1160
51
53
  tunacode/core/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -65,7 +67,7 @@ tunacode/core/setup/template_setup.py,sha256=0lDGhNVCvGN7ykqHnl3pj4CONH3I2PvMzkm
65
67
  tunacode/core/token_usage/api_response_parser.py,sha256=plLltHg4zGVzxjv3MFj45bbd-NOJeT_v3P0Ki4zlvn4,1831
66
68
  tunacode/core/token_usage/cost_calculator.py,sha256=RjO-O0JENBuGOrWP7QgBZlZxeXC-PAIr8tj_9p_BxOU,2058
67
69
  tunacode/core/token_usage/usage_tracker.py,sha256=G6lt9VXnS3JcXsiPTwuS3v1YptI_7gfV78f08jX22yU,5932
68
- tunacode/prompts/system.md,sha256=dGKTnJeNuYG4MyGbc5NPaMYSZ27fLhJOml86rp8AffU,23873
70
+ tunacode/prompts/system.md,sha256=jrPtKFLu2CD6WpNNFgN1nc0p3mec4En9VYmpRQxyZi8,24080
69
71
  tunacode/services/__init__.py,sha256=w_E8QK6RnvKSvU866eDe8BCRV26rAm4d3R-Yg06OWCU,19
70
72
  tunacode/services/mcp.py,sha256=R48X73KQjQ9vwhBrtbWHSBl-4K99QXmbIhh5J_1Gezo,3046
71
73
  tunacode/templates/__init__.py,sha256=ssEOPrPjyCywtKI-QFcoqcWhMjlfI5TbI8Ip0_wyqGM,241
@@ -74,7 +76,7 @@ tunacode/tools/__init__.py,sha256=ECBuUWWF1JjHW42CCceaPKgVTQyuljbz3RlhuA2fe2s,31
74
76
  tunacode/tools/base.py,sha256=DhlanZZZxU2JJaBOwwyGFKMUcoCWR_CzLuwVeSXC0Go,7297
75
77
  tunacode/tools/bash.py,sha256=mgZqugfDFevZ4BETuUv90pzXvtq7qKGUGFiuDxzmytk,8766
76
78
  tunacode/tools/glob.py,sha256=mQwVGC8dfvzwzUOeTikfnHhExnLcYnGQwDoHOWrt_fE,10342
77
- tunacode/tools/grep.py,sha256=kvfhO41k4gIg5rxyBECE-IWkyc3IwtWYly3Q8nN4SuM,17212
79
+ tunacode/tools/grep.py,sha256=SfpLazOMbizganPO16w7v6iHRcUn0cD6-6lyUwrl-3U,17834
78
80
  tunacode/tools/list_dir.py,sha256=1kNqzYCNlcA5rqXIEVqcjQy6QxlLZLj5AG6YIECfwio,7217
79
81
  tunacode/tools/read_file.py,sha256=z2omev9xzj4-0GG9mRssD13rj-Aa1c-pszFi2Z7Hxvk,3268
80
82
  tunacode/tools/read_file_async_poc.py,sha256=2v2ckLQlwahgPGWGdE2c5Es37B35Y7zWdseZwT46E1E,6453
@@ -89,16 +91,17 @@ tunacode/tools/grep_components/result_formatter.py,sha256=aa0tJitbG9IalWYWKG0nIn
89
91
  tunacode/tools/grep_components/search_result.py,sha256=xzb_htSANuPIPVWViPAqIMsCCWVA8loxWdaZOA8RqMs,869
90
92
  tunacode/ui/__init__.py,sha256=aRNE2pS50nFAX6y--rSGMNYwhz905g14gRd6g4BolYU,13
91
93
  tunacode/ui/completers.py,sha256=18f1Im5210-b-qNKyCoOMnSjW99FXNoF0DtgRvEWTm0,4901
92
- tunacode/ui/console.py,sha256=wLiJ9cVrWHS0zNadqbcXnsg0T2wj4xLACg17YAYLmU4,2574
94
+ tunacode/ui/console.py,sha256=HfE30vUy8ebXCobP7psFNJc17-dvH6APChg2tbi7aTw,2632
93
95
  tunacode/ui/constants.py,sha256=A76B_KpM8jCuBYRg4cPmhi8_j6LLyWttO7_jjv47r3w,421
94
96
  tunacode/ui/decorators.py,sha256=jJDNztO8MyX_IG1nqXAL8-sQUFjaAzBnc5BsM3ioX24,1955
95
97
  tunacode/ui/input.py,sha256=NCZlj5qzNPy0gsSeGKeDNdAOMKZVGph8Z-UBXhX-Sbk,3020
96
- tunacode/ui/keybindings.py,sha256=ylvZ2kj2IWfOMrxPWBSbckEy9YVow66dni7wkj8vzbw,3046
98
+ tunacode/ui/keybindings.py,sha256=YUyi6I0xXs9mNjT0qnKh_SXsfSYb6eNUD44pV_q5TVI,1685
97
99
  tunacode/ui/lexers.py,sha256=tmg4ic1enyTRLzanN5QPP7D_0n12YjX_8ZhsffzhXA4,1340
98
100
  tunacode/ui/logging_compat.py,sha256=5v6lcjVaG1CxdY1Zm9FAGr9H7Sy-tP6ihGfhP-5YvAY,1406
99
- tunacode/ui/output.py,sha256=vXfkPfQWmQzkmfGkY6snAk7auLgN8E7XEGUc-YVjTlM,5604
100
- tunacode/ui/panels.py,sha256=8D5w0dwzE1F3Li88Bkl-g6dHlK-Q-9DEl2n2EqMkVRk,9588
101
+ tunacode/ui/output.py,sha256=C2LHKAZxBySsIfk9saJ-jZrsZBE7f3WeP-RHpn5TChQ,6808
102
+ tunacode/ui/panels.py,sha256=wccIQ-exLs5oBedFZRU1lsY69fRqf-em_5gTTRM0Luc,11527
101
103
  tunacode/ui/prompt_manager.py,sha256=489r-WtuR3gdaugEr1lSV7SvtmXF2IlhDQckvzjYG2c,4676
104
+ tunacode/ui/tool_descriptions.py,sha256=vk61JPIXy7gHNfJ--77maXgK6WwNwxqY47QYsw_a2uw,4126
102
105
  tunacode/ui/tool_ui.py,sha256=bLydo5Y42b2gbUMP2kM6m_stIkj4Q1wbwaqO-1P6O1g,7198
103
106
  tunacode/ui/utils.py,sha256=yvoCTz8AOdRfV0XIqUX3sgg88g_wntV9yhnQP6WzAVs,114
104
107
  tunacode/ui/validators.py,sha256=MMIMT1I2v0l2jIy-gxX_4GSApvUTi8XWIOACr_dmoBA,758
@@ -115,9 +118,9 @@ tunacode/utils/system.py,sha256=J8KqJ4ZqQrNSnM5rrJxPeMk9z2xQQp6dWtI1SKBY1-0,1112
115
118
  tunacode/utils/text_utils.py,sha256=HAwlT4QMy41hr53cDbbNeNo05MI461TpI9b_xdIv8EY,7288
116
119
  tunacode/utils/token_counter.py,sha256=dmFuqVz4ywGFdLfAi5Mg9bAGf8v87Ek-mHU-R3fsYjI,2711
117
120
  tunacode/utils/user_configuration.py,sha256=Ilz8dpGVJDBE2iLWHAPT0xR8D51VRKV3kIbsAz8Bboc,3275
118
- tunacode_cli-0.0.53.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
119
- tunacode_cli-0.0.53.dist-info/METADATA,sha256=5vCcjz1MDQ2o3udvSQC2kmmNHdxbruvk2V5fqaZdhhI,10193
120
- tunacode_cli-0.0.53.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
121
- tunacode_cli-0.0.53.dist-info/entry_points.txt,sha256=hbkytikj4dGu6rizPuAd_DGUPBGF191RTnhr9wdhORY,51
122
- tunacode_cli-0.0.53.dist-info/top_level.txt,sha256=lKy2P6BWNi5XSA4DHFvyjQ14V26lDZctwdmhEJrxQbU,9
123
- tunacode_cli-0.0.53.dist-info/RECORD,,
121
+ tunacode_cli-0.0.55.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
122
+ tunacode_cli-0.0.55.dist-info/METADATA,sha256=nB8M3oUVfbFFUBxldQFl86PjnnuxhhL6KGeal1iE88g,10193
123
+ tunacode_cli-0.0.55.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
124
+ tunacode_cli-0.0.55.dist-info/entry_points.txt,sha256=hbkytikj4dGu6rizPuAd_DGUPBGF191RTnhr9wdhORY,51
125
+ tunacode_cli-0.0.55.dist-info/top_level.txt,sha256=lKy2P6BWNi5XSA4DHFvyjQ14V26lDZctwdmhEJrxQbU,9
126
+ tunacode_cli-0.0.55.dist-info/RECORD,,