tunacode-cli 0.0.34__py3-none-any.whl → 0.0.36__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.

tunacode/ui/console.py CHANGED
@@ -9,11 +9,34 @@ from rich.markdown import Markdown
9
9
  # Import and re-export all functions from specialized modules
10
10
  from .input import formatted_text, input, multiline_input
11
11
  from .keybindings import create_key_bindings
12
- from .output import (banner, clear, info, line, muted, print, spinner, success, sync_print,
13
- update_available, usage, version, warning)
12
+ from .output import (
13
+ banner,
14
+ clear,
15
+ info,
16
+ line,
17
+ muted,
18
+ print,
19
+ spinner,
20
+ success,
21
+ sync_print,
22
+ update_available,
23
+ usage,
24
+ version,
25
+ warning,
26
+ )
27
+
14
28
  # Patch banner to use sync fast version
15
- from .panels import (agent, dump_messages, error, help, models, panel, sync_panel,
16
- sync_tool_confirm, tool_confirm)
29
+ from .panels import (
30
+ agent,
31
+ dump_messages,
32
+ error,
33
+ help,
34
+ models,
35
+ panel,
36
+ sync_panel,
37
+ sync_tool_confirm,
38
+ tool_confirm,
39
+ )
17
40
  from .prompt_manager import PromptConfig, PromptManager
18
41
  from .validators import ModelValidator
19
42
 
tunacode/ui/output.py CHANGED
@@ -5,8 +5,13 @@ from rich.console import Console
5
5
  from rich.padding import Padding
6
6
 
7
7
  from tunacode.configuration.settings import ApplicationSettings
8
- from tunacode.constants import (MSG_UPDATE_AVAILABLE, MSG_UPDATE_INSTRUCTION, MSG_VERSION_DISPLAY,
9
- UI_COLORS, UI_THINKING_MESSAGE)
8
+ from tunacode.constants import (
9
+ MSG_UPDATE_AVAILABLE,
10
+ MSG_UPDATE_INSTRUCTION,
11
+ MSG_VERSION_DISPLAY,
12
+ UI_COLORS,
13
+ UI_THINKING_MESSAGE,
14
+ )
10
15
  from tunacode.core.state import StateManager
11
16
  from tunacode.utils.file_utils import DotDict
12
17
 
tunacode/ui/panels.py CHANGED
@@ -10,11 +10,30 @@ from rich.pretty import Pretty
10
10
  from rich.table import Table
11
11
 
12
12
  from tunacode.configuration.models import ModelRegistry
13
- from tunacode.constants import (APP_NAME, CMD_CLEAR, CMD_COMPACT, CMD_DUMP, CMD_EXIT, CMD_HELP,
14
- CMD_MODEL, CMD_YOLO, DESC_CLEAR, DESC_COMPACT, DESC_DUMP, DESC_EXIT,
15
- DESC_HELP, DESC_MODEL, DESC_MODEL_DEFAULT, DESC_MODEL_SWITCH,
16
- DESC_YOLO, PANEL_AVAILABLE_COMMANDS, PANEL_ERROR,
17
- PANEL_MESSAGE_HISTORY, PANEL_MODELS, UI_COLORS)
13
+ from tunacode.constants import (
14
+ APP_NAME,
15
+ CMD_CLEAR,
16
+ CMD_COMPACT,
17
+ CMD_DUMP,
18
+ CMD_EXIT,
19
+ CMD_HELP,
20
+ CMD_MODEL,
21
+ CMD_YOLO,
22
+ DESC_CLEAR,
23
+ DESC_COMPACT,
24
+ DESC_DUMP,
25
+ DESC_EXIT,
26
+ DESC_HELP,
27
+ DESC_MODEL,
28
+ DESC_MODEL_DEFAULT,
29
+ DESC_MODEL_SWITCH,
30
+ DESC_YOLO,
31
+ PANEL_AVAILABLE_COMMANDS,
32
+ PANEL_ERROR,
33
+ PANEL_MESSAGE_HISTORY,
34
+ PANEL_MODELS,
35
+ UI_COLORS,
36
+ )
18
37
  from tunacode.core.state import StateManager
19
38
  from tunacode.utils.file_utils import DotDict
20
39
 
@@ -0,0 +1,208 @@
1
+ """
2
+ Security utilities for safe command execution and input validation.
3
+ Provides defensive measures against command injection attacks.
4
+ """
5
+
6
+ import logging
7
+ import re
8
+ import shlex
9
+ import subprocess
10
+ from typing import List, Optional
11
+
12
+ logger = logging.getLogger(__name__)
13
+
14
+ # Dangerous shell metacharacters that indicate potential injection
15
+ DANGEROUS_CHARS = [
16
+ ";",
17
+ "&",
18
+ "|",
19
+ "`",
20
+ "$",
21
+ "(",
22
+ ")",
23
+ "{",
24
+ "}",
25
+ "<",
26
+ ">",
27
+ "\n",
28
+ "\r",
29
+ "\\",
30
+ '"',
31
+ "'",
32
+ ]
33
+
34
+ # Common injection patterns
35
+ INJECTION_PATTERNS = [
36
+ r";\s*\w+", # Command chaining with semicolon
37
+ r"&&\s*\w+", # Command chaining with &&
38
+ r"\|\s*\w+", # Piping to another command
39
+ r"`[^`]+`", # Command substitution with backticks
40
+ r"\$\([^)]+\)", # Command substitution with $()
41
+ r">\s*[/\w]", # Output redirection
42
+ r"<\s*[/\w]", # Input redirection
43
+ ]
44
+
45
+
46
+ class CommandSecurityError(Exception):
47
+ """Raised when a command fails security validation."""
48
+
49
+ pass
50
+
51
+
52
+ def validate_command_safety(command: str, allow_shell_features: bool = False) -> None:
53
+ """
54
+ Validate that a command is safe to execute.
55
+
56
+ Args:
57
+ command: The command string to validate
58
+ allow_shell_features: If True, allows some shell features like pipes
59
+
60
+ Raises:
61
+ CommandSecurityError: If the command contains potentially dangerous patterns
62
+ """
63
+ if not command or not command.strip():
64
+ raise CommandSecurityError("Empty command not allowed")
65
+
66
+ # Log the command being validated
67
+ logger.info(f"Validating command: {command[:100]}...")
68
+
69
+ # Always check for the most dangerous patterns regardless of shell features
70
+ dangerous_patterns = [
71
+ r"rm\s+-rf\s+/", # Dangerous rm commands
72
+ r"sudo\s+rm", # Sudo rm commands
73
+ r">\s*/dev/sd[a-z]", # Writing to disk devices
74
+ r"dd\s+.*of=/dev/", # DD to devices
75
+ r"mkfs\.", # Format filesystem
76
+ r"fdisk", # Partition manipulation
77
+ r":\(\)\{.*\}\;", # Fork bomb pattern
78
+ ]
79
+
80
+ for pattern in dangerous_patterns:
81
+ if re.search(pattern, command, re.IGNORECASE):
82
+ logger.error(f"Highly dangerous pattern '{pattern}' detected in command")
83
+ raise CommandSecurityError("Command contains dangerous pattern and is blocked")
84
+
85
+ if not allow_shell_features:
86
+ # Check for dangerous characters (but allow some for CLI tools)
87
+ restricted_chars = [";", "&", "`", "$", "{", "}"] # More permissive for CLI
88
+ for char in restricted_chars:
89
+ if char in command:
90
+ logger.warning(f"Potentially dangerous character '{char}' detected in command")
91
+ raise CommandSecurityError(f"Potentially unsafe character '{char}' in command")
92
+
93
+ # Check for injection patterns (more selective)
94
+ strict_patterns = [
95
+ r";\s*rm\s+", # Command chaining to rm
96
+ r"&&\s*rm\s+", # Command chaining to rm
97
+ r"`[^`]*rm[^`]*`", # Command substitution with rm
98
+ r"\$\([^)]*rm[^)]*\)", # Command substitution with rm
99
+ ]
100
+
101
+ for pattern in strict_patterns:
102
+ if re.search(pattern, command):
103
+ logger.warning(f"Dangerous injection pattern '{pattern}' detected in command")
104
+ raise CommandSecurityError("Potentially unsafe pattern detected in command")
105
+
106
+
107
+ def sanitize_command_args(args: List[str]) -> List[str]:
108
+ """
109
+ Sanitize command arguments by shell-quoting them.
110
+
111
+ Args:
112
+ args: List of command arguments
113
+
114
+ Returns:
115
+ List of sanitized arguments
116
+ """
117
+ return [shlex.quote(arg) for arg in args]
118
+
119
+
120
+ def safe_subprocess_run(
121
+ command: str,
122
+ shell: bool = False,
123
+ validate: bool = True,
124
+ timeout: Optional[int] = None,
125
+ **kwargs,
126
+ ) -> subprocess.CompletedProcess:
127
+ """
128
+ Safely execute a subprocess with security validation.
129
+
130
+ Args:
131
+ command: Command to execute (string if shell=True, list if shell=False)
132
+ shell: Whether to use shell execution (discouraged)
133
+ validate: Whether to validate command safety
134
+ timeout: Timeout in seconds
135
+ **kwargs: Additional subprocess arguments
136
+
137
+ Returns:
138
+ CompletedProcess result
139
+
140
+ Raises:
141
+ CommandSecurityError: If command fails security validation
142
+ """
143
+ if validate and shell and isinstance(command, str):
144
+ validate_command_safety(command, allow_shell_features=shell)
145
+
146
+ # Log the command execution
147
+ logger.info(f"Executing command: {str(command)[:100]}...")
148
+
149
+ try:
150
+ if shell:
151
+ # When using shell=True, command should be a string
152
+ result = subprocess.run(command, shell=True, timeout=timeout, **kwargs)
153
+ else:
154
+ # When shell=False, command should be a list
155
+ if isinstance(command, str):
156
+ # Parse the string into a list
157
+ command_list = shlex.split(command)
158
+ else:
159
+ command_list = command
160
+
161
+ result = subprocess.run(command_list, shell=False, timeout=timeout, **kwargs)
162
+
163
+ logger.info(f"Command completed with return code: {result.returncode}")
164
+ return result
165
+
166
+ except subprocess.TimeoutExpired:
167
+ logger.error(f"Command timed out after {timeout} seconds")
168
+ raise
169
+ except Exception as e:
170
+ logger.error(f"Command execution failed: {str(e)}")
171
+ raise
172
+
173
+
174
+ def safe_subprocess_popen(
175
+ command: str, shell: bool = False, validate: bool = True, **kwargs
176
+ ) -> subprocess.Popen:
177
+ """
178
+ Safely create a subprocess.Popen with security validation.
179
+
180
+ Args:
181
+ command: Command to execute
182
+ shell: Whether to use shell execution (discouraged)
183
+ validate: Whether to validate command safety
184
+ **kwargs: Additional Popen arguments
185
+
186
+ Returns:
187
+ Popen process object
188
+
189
+ Raises:
190
+ CommandSecurityError: If command fails security validation
191
+ """
192
+ if validate and shell and isinstance(command, str):
193
+ validate_command_safety(command, allow_shell_features=shell)
194
+
195
+ # Log the command execution
196
+ logger.info(f"Creating Popen for command: {str(command)[:100]}...")
197
+
198
+ if shell:
199
+ # When using shell=True, command should be a string
200
+ return subprocess.Popen(command, shell=True, **kwargs)
201
+ else:
202
+ # When shell=False, command should be a list
203
+ if isinstance(command, str):
204
+ command_list = shlex.split(command)
205
+ else:
206
+ command_list = command
207
+
208
+ return subprocess.Popen(command_list, shell=False, **kwargs)
@@ -67,8 +67,12 @@ def expand_file_refs(text: str) -> Tuple[str, List[str]]:
67
67
  import os
68
68
  import re
69
69
 
70
- from tunacode.constants import (ERROR_FILE_NOT_FOUND, ERROR_FILE_TOO_LARGE, MAX_FILE_SIZE,
71
- MSG_FILE_SIZE_LIMIT)
70
+ from tunacode.constants import (
71
+ ERROR_FILE_NOT_FOUND,
72
+ ERROR_FILE_TOO_LARGE,
73
+ MAX_FILE_SIZE,
74
+ MSG_FILE_SIZE_LIMIT,
75
+ )
72
76
 
73
77
  pattern = re.compile(r"@([\w./_-]+)")
74
78
  expanded_files = []
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tunacode-cli
3
- Version: 0.0.34
3
+ Version: 0.0.36
4
4
  Summary: Your agentic CLI developer.
5
5
  Author-email: larock22 <noreply@github.com>
6
6
  License-Expression: MIT
@@ -1,26 +1,34 @@
1
1
  tunacode/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- tunacode/constants.py,sha256=SIhhV5x1ESvfVaAki0nJ9XVlKZOwwomqIMT73FLyjPY,4074
2
+ tunacode/constants.py,sha256=SUeDFVdhj0Z4SxhlMn5km_34uKHDAW6gQZqHDybEgfE,4074
3
3
  tunacode/context.py,sha256=6sterdRvPOyG3LU0nEAXpBsEPZbO3qtPyTlJBi-_VXE,2612
4
4
  tunacode/exceptions.py,sha256=mTWXuWyr1k16CGLWN2tsthDGi7lbx1JK0ekIqogYDP8,3105
5
5
  tunacode/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- tunacode/setup.py,sha256=dYn0NeAxtNIDSogWEmGSyjb9wsr8AonZ8vAo5sw9NIw,1909
6
+ tunacode/setup.py,sha256=XPt4eAK-qcIZQv64jGZ_ryxcImDwps9OmXjJfIS1xcs,1899
7
7
  tunacode/types.py,sha256=BciT-uxnQ44iC-4QiDY72OD23LOtqSyMOuK_N0ttlaA,7676
8
8
  tunacode/cli/__init__.py,sha256=zgs0UbAck8hfvhYsWhWOfBe5oK09ug2De1r4RuQZREA,55
9
- tunacode/cli/commands.py,sha256=DEEfDVNzDmMRUhA7JfWGh8antnMeb3G6LmaJLqNVsoI,31293
10
9
  tunacode/cli/main.py,sha256=PIcFnfmIoI_pmK2y-zB_ouJbzR5fbSI7zsKQNPB_J8o,2406
11
- tunacode/cli/repl.py,sha256=o3bn9BYQsy3TFCWJq-fzeHKLrM2KInSrMF5E5_RqSOY,13736
10
+ tunacode/cli/repl.py,sha256=ELnJBk3Vn2almXmmCIjGfgi7J5kNNVnO0o4KNYGXF9Q,14556
12
11
  tunacode/cli/textual_app.py,sha256=14-Nt0IIETmyHBrNn9uwSF3EwCcutwTp6gdoKgNm0sY,12593
13
12
  tunacode/cli/textual_bridge.py,sha256=LvqiTtF0hu3gNujzpKaW9h-m6xzEP3OH2M8KL2pCwRc,6333
13
+ tunacode/cli/commands/__init__.py,sha256=YMrLz7szrmseJCRZGGX6_TyO3dJU8_QDCOFEhRAztzo,1634
14
+ tunacode/cli/commands/base.py,sha256=GxUuDsDSpz0iXryy8MrEw88UM3C3yxL__kDK1QhshoA,2517
15
+ tunacode/cli/commands/registry.py,sha256=9m8rbtrjd9oaVPnCeU4UhIWR8qa7QpPUrWDR2aqFyzE,8079
16
+ tunacode/cli/commands/implementations/__init__.py,sha256=B0w124eXbcI3Aaai9nllbciFOWvLFTPlZ0RdLlCLP3M,875
17
+ tunacode/cli/commands/implementations/conversation.py,sha256=EsnsZB6yyVI_sbNNMvk37tCz3iAj4E85R9ev696qeqg,4683
18
+ tunacode/cli/commands/implementations/debug.py,sha256=TdP72Dpd3Nq3lwwyj0qZEdbSjDDmRyFu-0t6ttPFNno,6769
19
+ tunacode/cli/commands/implementations/development.py,sha256=kZRdVgReVmGU0uijFxtPio2RYkTrYMufOwgI1Aj1_NU,2729
20
+ tunacode/cli/commands/implementations/model.py,sha256=uthx6IX9KwgwywNTDklkJpqCbaTX9h1_p-eVmqL73WQ,2245
21
+ tunacode/cli/commands/implementations/system.py,sha256=AuUfZ2cMGlzMpT7yh2Yr5HnpY6DhcjmXZCrd3NkzVz4,6435
14
22
  tunacode/configuration/__init__.py,sha256=MbVXy8bGu0yKehzgdgZ_mfWlYGvIdb1dY2Ly75nfuPE,17
15
23
  tunacode/configuration/defaults.py,sha256=lNeJUW1S8zj4-XTCkMP9UaDc-tHWXLff9K8t0uPA_oE,801
16
24
  tunacode/configuration/models.py,sha256=XPobkLM_TzKTuMIWhK-svJfGRGFT9r2LhKEM6rv6QHk,3756
17
- tunacode/configuration/settings.py,sha256=lm2ov8rG1t4C5JIXMOhIKik5FAsjpuLVYtFmnE1ZQ3k,995
25
+ tunacode/configuration/settings.py,sha256=KoN0u6GG3Hh_TWt02D_wpRfbACYri3gCDTXHtJfHl2w,994
18
26
  tunacode/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
27
  tunacode/core/code_index.py,sha256=jgAx3lSWP_DwnyiP5Jkm1YvX4JJyI4teMzlNrJSpEOA,15661
20
- tunacode/core/state.py,sha256=PHGCGjx_X03I5jO-T1JkREQm4cwYEXQty59JJlnk24c,1608
28
+ tunacode/core/state.py,sha256=x0ZHqfaz8P5EhJoqeVNBa7O9BRytuzFCHK7wFao2R_E,1611
21
29
  tunacode/core/tool_handler.py,sha256=BPjR013OOO0cLXPdLeL2FDK0ixUwOYu59FfHdcdFhp4,2277
22
30
  tunacode/core/agents/__init__.py,sha256=UUJiPYb91arwziSpjd7vIk7XNGA_4HQbsOIbskSqevA,149
23
- tunacode/core/agents/main.py,sha256=-QwKSKoPLdD-JlKPjwMUSxNu_TSrj-pdUleWR2FN-A0,39441
31
+ tunacode/core/agents/main.py,sha256=s1B5oGKDjdUCH5xpL-Cy6i3cAr-tPM9_RDByOs7-qtE,39456
24
32
  tunacode/core/background/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
33
  tunacode/core/background/manager.py,sha256=rJdl3eDLTQwjbT7VhxXcJbZopCNR3M8ZGMbmeVnwwMc,1126
26
34
  tunacode/core/llm/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -40,21 +48,21 @@ tunacode/tools/bash.py,sha256=mgZqugfDFevZ4BETuUv90pzXvtq7qKGUGFiuDxzmytk,8766
40
48
  tunacode/tools/glob.py,sha256=TSgVK79ewZgGw8ucYkkiHgVqRgkw-wZrhP8j52nm_gQ,10334
41
49
  tunacode/tools/grep.py,sha256=jboEVA2ATv0YI8zg9dF89emZ_HWy2vVtsQ_-hDhlr7g,26337
42
50
  tunacode/tools/list_dir.py,sha256=1kNqzYCNlcA5rqXIEVqcjQy6QxlLZLj5AG6YIECfwio,7217
43
- tunacode/tools/read_file.py,sha256=BqHxPspZBYotz5wtjuP-zve61obsx98z5TU-aw5BJHg,3273
44
- tunacode/tools/read_file_async_poc.py,sha256=0rSfYCmoNcvWk8hB1z86l32-tomSc9yOM4tR4nrty_o,6267
45
- tunacode/tools/run_command.py,sha256=kYg_Re397OmZdKtUSjpNfYYNDBjd0vsS1xMK0yP181I,3776
51
+ tunacode/tools/read_file.py,sha256=z2omev9xzj4-0GG9mRssD13rj-Aa1c-pszFi2Z7Hxvk,3268
52
+ tunacode/tools/read_file_async_poc.py,sha256=2v2ckLQlwahgPGWGdE2c5Es37B35Y7zWdseZwT46E1E,6453
53
+ tunacode/tools/run_command.py,sha256=7UvXjFQI1Av4vceXx48MbQCTrsFNj4PlygTAAhNDYIA,4376
46
54
  tunacode/tools/update_file.py,sha256=bW1MhTzRjBDjJzqQ6A1yCVEbkr1oIqtEC8uqcg_rfY4,3957
47
55
  tunacode/tools/write_file.py,sha256=prL6u8XOi9ZyPU-YNlG9YMLbSLrDJXDRuDX73ncXh-k,2699
48
56
  tunacode/ui/__init__.py,sha256=aRNE2pS50nFAX6y--rSGMNYwhz905g14gRd6g4BolYU,13
49
57
  tunacode/ui/completers.py,sha256=Jx1zyCESwdm_4ZopvCBtb0bCJF-bRy8aBWG2yhPQtDc,4878
50
- tunacode/ui/console.py,sha256=LTEWQLdRP0JkhbEPIHIDrSX3ZZld9iJI2aZ3-eGliOc,1930
58
+ tunacode/ui/console.py,sha256=8Z_GqmxgjSy-k7hrEMiT6NRSW9-pv0LVAWiEaun0UKw,1983
51
59
  tunacode/ui/constants.py,sha256=A76B_KpM8jCuBYRg4cPmhi8_j6LLyWttO7_jjv47r3w,421
52
60
  tunacode/ui/decorators.py,sha256=e2KM-_pI5EKHa2M045IjUe4rPkTboxaKHXJT0K3461g,1914
53
61
  tunacode/ui/input.py,sha256=6LlEwKIXYXusNDI2PD0DDjRymQgu5mf2v06TsHbUln0,2957
54
62
  tunacode/ui/keybindings.py,sha256=h0MlD73CW_3i2dQzb9EFSPkqy0raZ_isgjxUiA9u6ts,691
55
63
  tunacode/ui/lexers.py,sha256=tmg4ic1enyTRLzanN5QPP7D_0n12YjX_8ZhsffzhXA4,1340
56
- tunacode/ui/output.py,sha256=wCLvAZb-OeKyLeR7KxD9WSW_GkHk0iX0PDAJilR0Upw,4508
57
- tunacode/ui/panels.py,sha256=_8B1rGOhPnSLekGM4ZzDJw-dCuaPeacsaCmmCggqxwE,5950
64
+ tunacode/ui/output.py,sha256=kjVklUZumGwjV8LeB7aX1WjcwAbURnuudZZY1t4qsN4,4499
65
+ tunacode/ui/panels.py,sha256=iyV8W85PQbmXe1dCUi_NdCqy9NsBXvQvAVO1mEldfmg,5913
58
66
  tunacode/ui/prompt_manager.py,sha256=U2cntB34vm-YwOj3gzFRUK362zccrz8pigQfpxr5sv8,4650
59
67
  tunacode/ui/tool_ui.py,sha256=S5-k1HwRlSqiQ8shGQ_QYGXQbuzb6Pg7u3CTqZwffdQ,6533
60
68
  tunacode/ui/validators.py,sha256=MMIMT1I2v0l2jIy-gxX_4GSApvUTi8XWIOACr_dmoBA,758
@@ -64,13 +72,14 @@ tunacode/utils/diff_utils.py,sha256=V9QqQ0q4MfabVTnWptF3IXDp3estnfOKcJtDe_Sj14I,
64
72
  tunacode/utils/file_utils.py,sha256=AXiAJ_idtlmXEi9pMvwtfPy9Ys3yK-F4K7qb_NpwonU,923
65
73
  tunacode/utils/import_cache.py,sha256=q_xjJbtju05YbFopLDSkIo1hOtCx3DOTl3GQE5FFDgs,295
66
74
  tunacode/utils/ripgrep.py,sha256=AXUs2FFt0A7KBV996deS8wreIlUzKOlAHJmwrcAr4No,583
75
+ tunacode/utils/security.py,sha256=e_zo9VmcOKFjgFMr9GOBIFhAmND4PBlJZgY7zqnsGjI,6548
67
76
  tunacode/utils/system.py,sha256=FSoibTIH0eybs4oNzbYyufIiV6gb77QaeY2yGqW39AY,11381
68
- tunacode/utils/text_utils.py,sha256=zRBaorvtyd7HBEWtIfCH1Wce1L6rhsQwpORUEGBFMjA,2981
77
+ tunacode/utils/text_utils.py,sha256=IiRviMqz5uoAbid8emkRXxgvQz6KE27ZeQom-qh9ymI,2984
69
78
  tunacode/utils/token_counter.py,sha256=nGCWwrHHFbKywqeDCEuJnADCkfJuzysWiB6cCltJOKI,648
70
79
  tunacode/utils/user_configuration.py,sha256=Ilz8dpGVJDBE2iLWHAPT0xR8D51VRKV3kIbsAz8Bboc,3275
71
- tunacode_cli-0.0.34.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
72
- tunacode_cli-0.0.34.dist-info/METADATA,sha256=uZKr-BnaxT_7vB1gTSIMEnWx1tfOSbBtPAt7gY4pibY,4943
73
- tunacode_cli-0.0.34.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
74
- tunacode_cli-0.0.34.dist-info/entry_points.txt,sha256=hbkytikj4dGu6rizPuAd_DGUPBGF191RTnhr9wdhORY,51
75
- tunacode_cli-0.0.34.dist-info/top_level.txt,sha256=lKy2P6BWNi5XSA4DHFvyjQ14V26lDZctwdmhEJrxQbU,9
76
- tunacode_cli-0.0.34.dist-info/RECORD,,
80
+ tunacode_cli-0.0.36.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
81
+ tunacode_cli-0.0.36.dist-info/METADATA,sha256=tEeGgHlHzd2exCxoGz8VPTmefH9kvGhNsOYWeJyjKic,4943
82
+ tunacode_cli-0.0.36.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
83
+ tunacode_cli-0.0.36.dist-info/entry_points.txt,sha256=hbkytikj4dGu6rizPuAd_DGUPBGF191RTnhr9wdhORY,51
84
+ tunacode_cli-0.0.36.dist-info/top_level.txt,sha256=lKy2P6BWNi5XSA4DHFvyjQ14V26lDZctwdmhEJrxQbU,9
85
+ tunacode_cli-0.0.36.dist-info/RECORD,,