tunacode-cli 0.0.26__py3-none-any.whl → 0.0.28__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/cli/commands.py +83 -4
- tunacode/constants.py +1 -1
- tunacode/core/agents/main.py +27 -3
- tunacode/core/agents/orchestrator.py +5 -3
- tunacode/ui/output.py +1 -1
- tunacode_cli-0.0.28.dist-info/METADATA +121 -0
- {tunacode_cli-0.0.26.dist-info → tunacode_cli-0.0.28.dist-info}/RECORD +11 -11
- tunacode_cli-0.0.26.dist-info/METADATA +0 -567
- {tunacode_cli-0.0.26.dist-info → tunacode_cli-0.0.28.dist-info}/WHEEL +0 -0
- {tunacode_cli-0.0.26.dist-info → tunacode_cli-0.0.28.dist-info}/entry_points.txt +0 -0
- {tunacode_cli-0.0.26.dist-info → tunacode_cli-0.0.28.dist-info}/licenses/LICENSE +0 -0
- {tunacode_cli-0.0.26.dist-info → tunacode_cli-0.0.28.dist-info}/top_level.txt +0 -0
tunacode/cli/commands.py
CHANGED
|
@@ -521,13 +521,92 @@ class CompactCommand(SimpleCommand):
|
|
|
521
521
|
await ui.error("Compact command not available - process_request not configured")
|
|
522
522
|
return
|
|
523
523
|
|
|
524
|
-
#
|
|
525
|
-
|
|
526
|
-
|
|
524
|
+
# Count current messages
|
|
525
|
+
original_count = len(context.state_manager.session.messages)
|
|
526
|
+
|
|
527
|
+
# Generate summary with output captured
|
|
528
|
+
summary_prompt = (
|
|
529
|
+
"Summarize the conversation so far in a concise paragraph, "
|
|
530
|
+
"focusing on the main topics discussed and any important context "
|
|
531
|
+
"that should be preserved."
|
|
527
532
|
)
|
|
528
|
-
await
|
|
533
|
+
result = await process_request(
|
|
534
|
+
summary_prompt,
|
|
535
|
+
context.state_manager,
|
|
536
|
+
output=False, # We'll handle the output ourselves
|
|
537
|
+
)
|
|
538
|
+
|
|
539
|
+
# Extract summary text from result
|
|
540
|
+
summary_text = ""
|
|
541
|
+
|
|
542
|
+
# First try: standard result structure
|
|
543
|
+
if (
|
|
544
|
+
result
|
|
545
|
+
and hasattr(result, "result")
|
|
546
|
+
and result.result
|
|
547
|
+
and hasattr(result.result, "output")
|
|
548
|
+
):
|
|
549
|
+
summary_text = result.result.output
|
|
550
|
+
|
|
551
|
+
# Second try: check messages for assistant response
|
|
552
|
+
if not summary_text:
|
|
553
|
+
messages = context.state_manager.session.messages
|
|
554
|
+
# Look through new messages in reverse order
|
|
555
|
+
for i in range(len(messages) - 1, original_count - 1, -1):
|
|
556
|
+
msg = messages[i]
|
|
557
|
+
# Handle ModelResponse objects
|
|
558
|
+
if hasattr(msg, "parts") and msg.parts:
|
|
559
|
+
for part in msg.parts:
|
|
560
|
+
if hasattr(part, "content") and part.content:
|
|
561
|
+
content = part.content
|
|
562
|
+
# Skip JSON thought objects
|
|
563
|
+
if content.strip().startswith('{"thought"'):
|
|
564
|
+
lines = content.split("\n")
|
|
565
|
+
# Find the actual summary after the JSON
|
|
566
|
+
for i, line in enumerate(lines):
|
|
567
|
+
if (
|
|
568
|
+
line.strip()
|
|
569
|
+
and not line.strip().startswith("{")
|
|
570
|
+
and not line.strip().endswith("}")
|
|
571
|
+
):
|
|
572
|
+
summary_text = "\n".join(lines[i:]).strip()
|
|
573
|
+
break
|
|
574
|
+
else:
|
|
575
|
+
summary_text = content
|
|
576
|
+
if summary_text:
|
|
577
|
+
break
|
|
578
|
+
# Handle dict-style messages
|
|
579
|
+
elif isinstance(msg, dict):
|
|
580
|
+
if msg.get("role") == "assistant" and msg.get("content"):
|
|
581
|
+
summary_text = msg["content"]
|
|
582
|
+
break
|
|
583
|
+
# Handle other message types
|
|
584
|
+
elif hasattr(msg, "content") and hasattr(msg, "role"):
|
|
585
|
+
if getattr(msg, "role", None) == "assistant":
|
|
586
|
+
summary_text = msg.content
|
|
587
|
+
break
|
|
588
|
+
|
|
589
|
+
if summary_text:
|
|
590
|
+
break
|
|
591
|
+
|
|
592
|
+
if not summary_text:
|
|
593
|
+
await ui.error("Failed to generate summary - no assistant response found")
|
|
594
|
+
return
|
|
595
|
+
|
|
596
|
+
# Display summary in a formatted panel
|
|
597
|
+
from tunacode.ui import panels
|
|
598
|
+
|
|
599
|
+
await panels.panel("Conversation Summary", summary_text, border_style="cyan")
|
|
600
|
+
|
|
601
|
+
# Show statistics
|
|
602
|
+
await ui.info(f"Current message count: {original_count}")
|
|
603
|
+
await ui.info("After compaction: 3 (summary + last 2 messages)")
|
|
604
|
+
|
|
605
|
+
# Truncate the conversation history
|
|
529
606
|
context.state_manager.session.messages = context.state_manager.session.messages[-2:]
|
|
530
607
|
|
|
608
|
+
await ui.success("Context history has been summarized and truncated.")
|
|
609
|
+
|
|
531
610
|
|
|
532
611
|
class UpdateCommand(SimpleCommand):
|
|
533
612
|
"""Update TunaCode to the latest version."""
|
tunacode/constants.py
CHANGED
tunacode/core/agents/main.py
CHANGED
|
@@ -370,6 +370,8 @@ async def process_request(
|
|
|
370
370
|
|
|
371
371
|
await ui.warning(f"⚠️ Reached maximum iterations ({max_iterations})")
|
|
372
372
|
break
|
|
373
|
+
|
|
374
|
+
# If we need to add a fallback response, create a wrapper
|
|
373
375
|
if not response_state.has_user_response and i >= max_iterations and fallback_enabled:
|
|
374
376
|
patch_tool_messages("Task incomplete", state_manager=state_manager)
|
|
375
377
|
response_state.has_final_synthesis = True
|
|
@@ -378,6 +380,28 @@ async def process_request(
|
|
|
378
380
|
progress=f"{i}/{max_iterations} iterations completed",
|
|
379
381
|
)
|
|
380
382
|
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
383
|
+
# Create a wrapper object that mimics AgentRun with the required attributes
|
|
384
|
+
class AgentRunWrapper:
|
|
385
|
+
def __init__(self, wrapped_run, fallback_result):
|
|
386
|
+
self._wrapped = wrapped_run
|
|
387
|
+
self.result = fallback_result
|
|
388
|
+
self.response_state = response_state
|
|
389
|
+
|
|
390
|
+
def __getattr__(self, name):
|
|
391
|
+
# Delegate all other attributes to the wrapped object
|
|
392
|
+
return getattr(self._wrapped, name)
|
|
393
|
+
|
|
394
|
+
return AgentRunWrapper(agent_run, SimpleResult(fallback.summary))
|
|
395
|
+
|
|
396
|
+
# For non-fallback cases, we still need to handle the response_state
|
|
397
|
+
# Create a minimal wrapper just to add response_state
|
|
398
|
+
class AgentRunWithState:
|
|
399
|
+
def __init__(self, wrapped_run):
|
|
400
|
+
self._wrapped = wrapped_run
|
|
401
|
+
self.response_state = response_state
|
|
402
|
+
|
|
403
|
+
def __getattr__(self, name):
|
|
404
|
+
# Delegate all other attributes to the wrapped object
|
|
405
|
+
return getattr(self._wrapped, name)
|
|
406
|
+
|
|
407
|
+
return AgentRunWithState(agent_run)
|
|
@@ -108,8 +108,10 @@ class OrchestratorAgent:
|
|
|
108
108
|
def __init__(self, output: str):
|
|
109
109
|
self.output = output
|
|
110
110
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
class SynthRun:
|
|
112
|
+
def __init__(self):
|
|
113
|
+
self.result = SynthResult(summary)
|
|
114
|
+
|
|
115
|
+
results.append(SynthRun())
|
|
114
116
|
|
|
115
117
|
return results
|
tunacode/ui/output.py
CHANGED
|
@@ -24,7 +24,7 @@ BANNER = """[bold cyan]
|
|
|
24
24
|
██║ ╚██████╔╝██║ ╚████║██║ ██║
|
|
25
25
|
╚═╝ ╚═════╝ ╚═╝ ╚═══╝╚═╝ ╚═╝
|
|
26
26
|
|
|
27
|
-
██████╗ ██████╗ ██████╗ ███████╗
|
|
27
|
+
██████╗ ██████╗ ██████╗ ███████╗ dev
|
|
28
28
|
██╔════╝██╔═══██╗██╔══██╗██╔════╝
|
|
29
29
|
██║ ██║ ██║██║ ██║█████╗
|
|
30
30
|
██║ ██║ ██║██║ ██║██╔══╝
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: tunacode-cli
|
|
3
|
+
Version: 0.0.28
|
|
4
|
+
Summary: Your agentic CLI developer.
|
|
5
|
+
Author-email: larock22 <noreply@github.com>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/larock22/tunacode
|
|
8
|
+
Project-URL: Repository, https://github.com/larock22/tunacode
|
|
9
|
+
Keywords: cli,agent,development,automation
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: Intended Audience :: Developers
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
+
Classifier: Topic :: Software Development
|
|
18
|
+
Classifier: Topic :: Utilities
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
License-File: LICENSE
|
|
22
|
+
Requires-Dist: typer==0.15.3
|
|
23
|
+
Requires-Dist: prompt_toolkit==3.0.51
|
|
24
|
+
Requires-Dist: pydantic-ai[logfire]==0.2.6
|
|
25
|
+
Requires-Dist: pygments==2.19.1
|
|
26
|
+
Requires-Dist: rich==14.0.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: build; extra == "dev"
|
|
29
|
+
Requires-Dist: black; extra == "dev"
|
|
30
|
+
Requires-Dist: flake8; extra == "dev"
|
|
31
|
+
Requires-Dist: isort; extra == "dev"
|
|
32
|
+
Requires-Dist: pytest; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-cov; extra == "dev"
|
|
34
|
+
Requires-Dist: textual-dev; extra == "dev"
|
|
35
|
+
Dynamic: license-file
|
|
36
|
+
|
|
37
|
+
# TunaCode
|
|
38
|
+
|
|
39
|
+
<div align="center">
|
|
40
|
+
|
|
41
|
+
[](https://badge.fury.io/py/tunacode-cli)
|
|
42
|
+
[](https://www.python.org/downloads/)
|
|
43
|
+
[](https://opensource.org/licenses/MIT)
|
|
44
|
+
|
|
45
|
+
**AI-powered CLI coding assistant**
|
|
46
|
+
|
|
47
|
+

|
|
48
|
+
|
|
49
|
+
</div>
|
|
50
|
+
|
|
51
|
+
---
|
|
52
|
+
|
|
53
|
+
## Quick Install
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
# Option 1: One-line install (Linux/macOS)
|
|
57
|
+
wget -qO- https://raw.githubusercontent.com/alchemiststudiosDOTai/tunacode/master/scripts/install_linux.sh | bash
|
|
58
|
+
|
|
59
|
+
# Option 2: pip install
|
|
60
|
+
pip install tunacode-cli
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
## Configuration
|
|
64
|
+
|
|
65
|
+
Choose your AI provider and set your API key:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
# OpenAI
|
|
69
|
+
tunacode --model "openai:gpt-4o" --key "sk-your-openai-key"
|
|
70
|
+
|
|
71
|
+
# Anthropic Claude
|
|
72
|
+
tunacode --model "anthropic:claude-3.5-sonnet" --key "sk-ant-your-anthropic-key"
|
|
73
|
+
|
|
74
|
+
# OpenRouter (100+ models)
|
|
75
|
+
tunacode --model "openrouter:openai/gpt-4o" --key "sk-or-your-openrouter-key"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Your config is saved to `~/.config/tunacode.json`
|
|
79
|
+
|
|
80
|
+
## Start Coding
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
tunacode
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Basic Commands
|
|
87
|
+
|
|
88
|
+
| Command | Description |
|
|
89
|
+
| ------- | ----------- |
|
|
90
|
+
| `/help` | Show all commands |
|
|
91
|
+
| `/model <provider:name>` | Switch model |
|
|
92
|
+
| `/clear` | Clear message history |
|
|
93
|
+
| `/compact` | Summarize conversation |
|
|
94
|
+
| `/branch <name>` | Create Git branch |
|
|
95
|
+
| `/yolo` | Skip confirmations |
|
|
96
|
+
| `!<command>` | Run shell command |
|
|
97
|
+
| `exit` | Exit TunaCode |
|
|
98
|
+
|
|
99
|
+
## Safety First
|
|
100
|
+
|
|
101
|
+
⚠️ **Important**: TunaCode can modify your codebase. Always:
|
|
102
|
+
- Use Git branches before making changes
|
|
103
|
+
- Review file modifications before confirming
|
|
104
|
+
- Keep backups of important work
|
|
105
|
+
|
|
106
|
+
## Documentation
|
|
107
|
+
|
|
108
|
+
- [**Features**](documentation/FEATURES.md) - All features, tools, and commands
|
|
109
|
+
- [**Advanced Configuration**](documentation/ADVANCED-CONFIG.md) - Provider setup, MCP, customization
|
|
110
|
+
- [**Architecture**](documentation/ARCHITECTURE.md) - Source code organization and design
|
|
111
|
+
- [**Development**](documentation/DEVELOPMENT.md) - Contributing and development setup
|
|
112
|
+
|
|
113
|
+
## Links
|
|
114
|
+
|
|
115
|
+
- [PyPI Package](https://pypi.org/project/tunacode-cli/)
|
|
116
|
+
- [GitHub Repository](https://github.com/alchemiststudiosDOTai/tunacode)
|
|
117
|
+
- [Report Issues](https://github.com/alchemiststudiosDOTai/tunacode/issues)
|
|
118
|
+
|
|
119
|
+
---
|
|
120
|
+
|
|
121
|
+
MIT License - see [LICENSE](LICENSE) file
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
tunacode/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
tunacode/constants.py,sha256=
|
|
2
|
+
tunacode/constants.py,sha256=br_qbqbT1sFcUxA2mpTclUyQn-jsVMr2hrsReyBP8Rc,3799
|
|
3
3
|
tunacode/context.py,sha256=6sterdRvPOyG3LU0nEAXpBsEPZbO3qtPyTlJBi-_VXE,2612
|
|
4
4
|
tunacode/exceptions.py,sha256=_Dyj6cC0868dMABekdQHXCg5XhucJumbGUMXaSDzgB4,2645
|
|
5
5
|
tunacode/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
6
|
tunacode/setup.py,sha256=dYn0NeAxtNIDSogWEmGSyjb9wsr8AonZ8vAo5sw9NIw,1909
|
|
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=
|
|
9
|
+
tunacode/cli/commands.py,sha256=OD3ZnNd5_TjJSAIuDT4rNgruTH_OOuAaR5OAoa8poFQ,34062
|
|
10
10
|
tunacode/cli/main.py,sha256=PIcFnfmIoI_pmK2y-zB_ouJbzR5fbSI7zsKQNPB_J8o,2406
|
|
11
11
|
tunacode/cli/repl.py,sha256=sXtRHYameAlMjlee82ix8P2JjRyWLrdFfHwxfaMKPb8,13722
|
|
12
12
|
tunacode/cli/textual_app.py,sha256=14-Nt0IIETmyHBrNn9uwSF3EwCcutwTp6gdoKgNm0sY,12593
|
|
@@ -19,8 +19,8 @@ tunacode/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
|
19
19
|
tunacode/core/state.py,sha256=n1claG-gVVDMBCCS8cDmgas4XbKLJJwKRc-8CtXeTS8,1376
|
|
20
20
|
tunacode/core/tool_handler.py,sha256=OKx7jM8pml6pSEnoARu33_uBY8awJBqvhbVeBn6T4ow,1804
|
|
21
21
|
tunacode/core/agents/__init__.py,sha256=TiXwymGRNMuOqQaRLpNCAt7bZArg8rkadIRs4Nw21SQ,275
|
|
22
|
-
tunacode/core/agents/main.py,sha256=
|
|
23
|
-
tunacode/core/agents/orchestrator.py,sha256=
|
|
22
|
+
tunacode/core/agents/main.py,sha256=bfm_TS1Z9rpy3phIUb7d1lLbYK99xJwrtBy4PWPSEOE,16673
|
|
23
|
+
tunacode/core/agents/orchestrator.py,sha256=t_eXtCO_QkIz687uT88RpDCmaE0-UkrUaczuTEJOrYQ,4154
|
|
24
24
|
tunacode/core/agents/planner_schema.py,sha256=pu2ehQVALjiJ5HJD7EN6xuZHCknsrXO9z0xHuVdlKW8,345
|
|
25
25
|
tunacode/core/agents/readonly.py,sha256=NOPfqPWu53fJy77k5uqwKWmZ6yzqnDOZpBeQjGy0AG8,1624
|
|
26
26
|
tunacode/core/background/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
@@ -53,7 +53,7 @@ tunacode/ui/decorators.py,sha256=e2KM-_pI5EKHa2M045IjUe4rPkTboxaKHXJT0K3461g,191
|
|
|
53
53
|
tunacode/ui/input.py,sha256=6LlEwKIXYXusNDI2PD0DDjRymQgu5mf2v06TsHbUln0,2957
|
|
54
54
|
tunacode/ui/keybindings.py,sha256=h0MlD73CW_3i2dQzb9EFSPkqy0raZ_isgjxUiA9u6ts,691
|
|
55
55
|
tunacode/ui/lexers.py,sha256=tmg4ic1enyTRLzanN5QPP7D_0n12YjX_8ZhsffzhXA4,1340
|
|
56
|
-
tunacode/ui/output.py,sha256=
|
|
56
|
+
tunacode/ui/output.py,sha256=wCLvAZb-OeKyLeR7KxD9WSW_GkHk0iX0PDAJilR0Upw,4508
|
|
57
57
|
tunacode/ui/panels.py,sha256=_8B1rGOhPnSLekGM4ZzDJw-dCuaPeacsaCmmCggqxwE,5950
|
|
58
58
|
tunacode/ui/prompt_manager.py,sha256=U2cntB34vm-YwOj3gzFRUK362zccrz8pigQfpxr5sv8,4650
|
|
59
59
|
tunacode/ui/tool_ui.py,sha256=S5-k1HwRlSqiQ8shGQ_QYGXQbuzb6Pg7u3CTqZwffdQ,6533
|
|
@@ -67,9 +67,9 @@ tunacode/utils/ripgrep.py,sha256=AXUs2FFt0A7KBV996deS8wreIlUzKOlAHJmwrcAr4No,583
|
|
|
67
67
|
tunacode/utils/system.py,sha256=FSoibTIH0eybs4oNzbYyufIiV6gb77QaeY2yGqW39AY,11381
|
|
68
68
|
tunacode/utils/text_utils.py,sha256=B9M1cuLTm_SSsr15WNHF6j7WdLWPvWzKZV0Lvfgdbjg,2458
|
|
69
69
|
tunacode/utils/user_configuration.py,sha256=IGvUH37wWtZ4M5xpukZEWYhtuKKyKcl6DaeObGXdleU,2610
|
|
70
|
-
tunacode_cli-0.0.
|
|
71
|
-
tunacode_cli-0.0.
|
|
72
|
-
tunacode_cli-0.0.
|
|
73
|
-
tunacode_cli-0.0.
|
|
74
|
-
tunacode_cli-0.0.
|
|
75
|
-
tunacode_cli-0.0.
|
|
70
|
+
tunacode_cli-0.0.28.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
|
|
71
|
+
tunacode_cli-0.0.28.dist-info/METADATA,sha256=QAmjxfmzJELeyebnE3H5wCkgGILFP7COYWRcKkl6JFA,3619
|
|
72
|
+
tunacode_cli-0.0.28.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
73
|
+
tunacode_cli-0.0.28.dist-info/entry_points.txt,sha256=hbkytikj4dGu6rizPuAd_DGUPBGF191RTnhr9wdhORY,51
|
|
74
|
+
tunacode_cli-0.0.28.dist-info/top_level.txt,sha256=lKy2P6BWNi5XSA4DHFvyjQ14V26lDZctwdmhEJrxQbU,9
|
|
75
|
+
tunacode_cli-0.0.28.dist-info/RECORD,,
|
|
@@ -1,567 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: tunacode-cli
|
|
3
|
-
Version: 0.0.26
|
|
4
|
-
Summary: Your agentic CLI developer.
|
|
5
|
-
Author-email: larock22 <noreply@github.com>
|
|
6
|
-
License-Expression: MIT
|
|
7
|
-
Project-URL: Homepage, https://github.com/larock22/tunacode
|
|
8
|
-
Project-URL: Repository, https://github.com/larock22/tunacode
|
|
9
|
-
Keywords: cli,agent,development,automation
|
|
10
|
-
Classifier: Development Status :: 4 - Beta
|
|
11
|
-
Classifier: Intended Audience :: Developers
|
|
12
|
-
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
14
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
15
|
-
Classifier: Programming Language :: Python :: 3.12
|
|
16
|
-
Classifier: Programming Language :: Python :: 3.13
|
|
17
|
-
Classifier: Topic :: Software Development
|
|
18
|
-
Classifier: Topic :: Utilities
|
|
19
|
-
Requires-Python: >=3.10
|
|
20
|
-
Description-Content-Type: text/markdown
|
|
21
|
-
License-File: LICENSE
|
|
22
|
-
Requires-Dist: typer==0.15.3
|
|
23
|
-
Requires-Dist: prompt_toolkit==3.0.51
|
|
24
|
-
Requires-Dist: pydantic-ai[logfire]==0.2.6
|
|
25
|
-
Requires-Dist: pygments==2.19.1
|
|
26
|
-
Requires-Dist: rich==14.0.0
|
|
27
|
-
Provides-Extra: dev
|
|
28
|
-
Requires-Dist: build; extra == "dev"
|
|
29
|
-
Requires-Dist: black; extra == "dev"
|
|
30
|
-
Requires-Dist: flake8; extra == "dev"
|
|
31
|
-
Requires-Dist: isort; extra == "dev"
|
|
32
|
-
Requires-Dist: pytest; extra == "dev"
|
|
33
|
-
Requires-Dist: pytest-cov; extra == "dev"
|
|
34
|
-
Requires-Dist: textual-dev; extra == "dev"
|
|
35
|
-
Dynamic: license-file
|
|
36
|
-
|
|
37
|
-
# TunaCode
|
|
38
|
-
|
|
39
|
-
<div align="center">
|
|
40
|
-
|
|
41
|
-
[](https://badge.fury.io/py/tunacode-cli)
|
|
42
|
-
[](https://www.python.org/downloads/)
|
|
43
|
-
[](https://opensource.org/licenses/MIT)
|
|
44
|
-
|
|
45
|
-
**Your AI-powered CLI coding assistant**
|
|
46
|
-
|
|
47
|
-

|
|
48
|
-
|
|
49
|
-
[Quick Start](#quick-start) • [Features](#features) • [Configuration](#configuration) • [Documentation](#documentation)
|
|
50
|
-
|
|
51
|
-
</div>
|
|
52
|
-
|
|
53
|
-
---
|
|
54
|
-
|
|
55
|
-
## Overview
|
|
56
|
-
|
|
57
|
-
> **⚠️ Safety First**: TunaCode can modify your codebase. Always use git branches before making major changes. The `/undo` command has been removed - use git for version control.
|
|
58
|
-
|
|
59
|
-
> **Beta Notice**: TunaCode is currently in beta. [Report issues](https://github.com/alchemiststudiosDOTai/tunacode/issues) or share feedback to help us improve!
|
|
60
|
-
|
|
61
|
-
---
|
|
62
|
-
|
|
63
|
-
### Recent Updates (v0.0.18)
|
|
64
|
-
|
|
65
|
-
- **Advanced Agent Orchestration**: New orchestrator system for complex multi-step tasks with planning visibility
|
|
66
|
-
- **Background Task Manager**: Asynchronous background processing for long-running operations
|
|
67
|
-
- **Read-Only Agent**: Specialized agent for safe codebase exploration without modification risks
|
|
68
|
-
- **Planning Transparency**: See the AI's planning process before execution with detailed task breakdowns
|
|
69
|
-
- **Shell Command Support**: Execute shell commands directly with `!command` or open interactive shell with `!`
|
|
70
|
-
- **Enhanced Bash Tool**: Advanced bash execution with timeouts, working directory, and environment variables
|
|
71
|
-
- **JSON Tool Parsing Fallback**: Automatic recovery when API providers fail with structured tool calling
|
|
72
|
-
- **Enhanced Reliability**: Fixed parameter naming issues that caused tool schema errors
|
|
73
|
-
- **Configuration Management**: New `/refresh` command to reload config without restart
|
|
74
|
-
- **Improved ReAct Reasoning**: Enhanced iteration limits (now defaults to 20) and better thought processing
|
|
75
|
-
- **New Debug Commands**: `/parsetools` for manual JSON parsing, `/iterations` for controlling reasoning depth
|
|
76
|
-
- **Better Error Recovery**: Multiple fallback mechanisms for various failure scenarios
|
|
77
|
-
|
|
78
|
-
### Core Features
|
|
79
|
-
|
|
80
|
-
<table>
|
|
81
|
-
<tr>
|
|
82
|
-
<td width="50%">
|
|
83
|
-
|
|
84
|
-
### **Multi-Provider Support**
|
|
85
|
-
|
|
86
|
-
- Anthropic Claude
|
|
87
|
-
- OpenAI GPT
|
|
88
|
-
- Google Gemini
|
|
89
|
-
- OpenRouter (100+ models)
|
|
90
|
-
- Any OpenAI-compatible API
|
|
91
|
-
|
|
92
|
-
### **Developer Tools**
|
|
93
|
-
|
|
94
|
-
- 6 core tools: bash, grep, read_file, write_file, update_file, run_command
|
|
95
|
-
- Direct shell command execution with `!` prefix
|
|
96
|
-
- MCP (Model Context Protocol) support
|
|
97
|
-
- File operation confirmations with diffs
|
|
98
|
-
- Per-project context guides (TUNACODE.md)
|
|
99
|
-
- JSON tool parsing fallback for API compatibility
|
|
100
|
-
|
|
101
|
-
</td>
|
|
102
|
-
<td width="50%">
|
|
103
|
-
|
|
104
|
-
### **Safety & Control**
|
|
105
|
-
|
|
106
|
-
- Git branch integration (`/branch`)
|
|
107
|
-
- No automatic commits
|
|
108
|
-
- Explicit file operation confirmations
|
|
109
|
-
- Permission tracking per session
|
|
110
|
-
- `/yolo` mode for power users
|
|
111
|
-
|
|
112
|
-
### **Architecture**
|
|
113
|
-
|
|
114
|
-
- Built on pydantic-ai
|
|
115
|
-
- Async throughout
|
|
116
|
-
- Modular command system
|
|
117
|
-
- Rich UI with syntax highlighting
|
|
118
|
-
- ReAct reasoning patterns
|
|
119
|
-
|
|
120
|
-
</td>
|
|
121
|
-
</tr>
|
|
122
|
-
</table>
|
|
123
|
-
|
|
124
|
-
---
|
|
125
|
-
|
|
126
|
-
## Quick Start
|
|
127
|
-
|
|
128
|
-
### Installation
|
|
129
|
-
|
|
130
|
-
#### PyPI
|
|
131
|
-
|
|
132
|
-
```bash
|
|
133
|
-
pip install tunacode-cli
|
|
134
|
-
```
|
|
135
|
-
|
|
136
|
-
#### Development Installation
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
# Clone the repository
|
|
140
|
-
git clone https://github.com/larock22/tunacode.git
|
|
141
|
-
cd tunacode
|
|
142
|
-
|
|
143
|
-
# Run the setup script
|
|
144
|
-
./scripts/setup_dev_env.sh
|
|
145
|
-
|
|
146
|
-
# Or manually:
|
|
147
|
-
python3 -m venv venv
|
|
148
|
-
source venv/bin/activate
|
|
149
|
-
pip install -e ".[dev]"
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
See [CONTRIBUTING.md](CONTRIBUTING.md) for detailed development setup.
|
|
153
|
-
|
|
154
|
-
#### One-line Install (Linux/macOS)
|
|
155
|
-
|
|
156
|
-
```bash
|
|
157
|
-
wget -qO- https://raw.githubusercontent.com/alchemiststudiosDOTai/tunacode/master/scripts/install_linux.sh | bash
|
|
158
|
-
```
|
|
159
|
-
|
|
160
|
-
### Uninstallation
|
|
161
|
-
|
|
162
|
-
To completely remove TunaCode from your system:
|
|
163
|
-
|
|
164
|
-
```bash
|
|
165
|
-
# Download and run the uninstall script
|
|
166
|
-
wget -qO- https://raw.githubusercontent.com/alchemiststudiosDOTai/tunacode/master/scripts/uninstall.sh | bash
|
|
167
|
-
|
|
168
|
-
# Or manually:
|
|
169
|
-
# 1. Remove the package
|
|
170
|
-
pipx uninstall tunacode # if installed via pipx
|
|
171
|
-
# OR
|
|
172
|
-
pip uninstall tunacode-cli # if installed via pip
|
|
173
|
-
|
|
174
|
-
# 2. Remove configuration files
|
|
175
|
-
rm -rf ~/.config/tunacode*
|
|
176
|
-
|
|
177
|
-
# 3. Remove any leftover binaries
|
|
178
|
-
rm -f ~/.local/bin/tunacode
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### Setup Options
|
|
182
|
-
|
|
183
|
-
<details>
|
|
184
|
-
<summary><b>Option 1: Interactive Setup (Beginner-friendly)</b></summary>
|
|
185
|
-
|
|
186
|
-
```bash
|
|
187
|
-
tunacode
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
Follow the interactive prompts to configure your preferred LLM provider.
|
|
191
|
-
|
|
192
|
-
</details>
|
|
193
|
-
|
|
194
|
-
<details>
|
|
195
|
-
<summary><b>Option 2: Direct CLI Setup (Recommended)</b></summary>
|
|
196
|
-
|
|
197
|
-
```bash
|
|
198
|
-
# OpenAI
|
|
199
|
-
tunacode --model "openai:gpt-4.1" --key "your-openai-key"
|
|
200
|
-
|
|
201
|
-
# Anthropic Claude
|
|
202
|
-
tunacode --model "anthropic:claude-3-opus" --key "your-anthropic-key"
|
|
203
|
-
|
|
204
|
-
# OpenRouter (Access to multiple models)
|
|
205
|
-
tunacode --baseurl "https://openrouter.ai/api/v1" \
|
|
206
|
-
--model "openrouter:openai/gpt-4.1" \
|
|
207
|
-
--key "your-openrouter-key"
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
</details>
|
|
211
|
-
|
|
212
|
-
> **Important**: Model names require provider prefixes (e.g., `openai:gpt-4.1`, not `gpt-4.1`)
|
|
213
|
-
|
|
214
|
-
---
|
|
215
|
-
|
|
216
|
-
## Configuration
|
|
217
|
-
|
|
218
|
-
### Config Location
|
|
219
|
-
|
|
220
|
-
Configuration is stored in `~/.config/tunacode.json`
|
|
221
|
-
|
|
222
|
-
### Model Format
|
|
223
|
-
|
|
224
|
-
```
|
|
225
|
-
provider:model-name
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
**Examples:**
|
|
229
|
-
|
|
230
|
-
- `openai:gpt-4.1`
|
|
231
|
-
- `anthropic:claude-3-opus`
|
|
232
|
-
- `google-gla:gemini-2.0-flash`
|
|
233
|
-
- `openrouter:mistralai/devstral-small`
|
|
234
|
-
|
|
235
|
-
### OpenRouter Integration
|
|
236
|
-
|
|
237
|
-
<details>
|
|
238
|
-
<summary><b>Click to expand OpenRouter setup</b></summary>
|
|
239
|
-
|
|
240
|
-
[OpenRouter](https://openrouter.ai) provides access to 100+ models through a single API:
|
|
241
|
-
|
|
242
|
-
```bash
|
|
243
|
-
tunacode --baseurl "https://openrouter.ai/api/v1" \
|
|
244
|
-
--model "openrouter:openai/gpt-4.1" \
|
|
245
|
-
--key "your-openrouter-key"
|
|
246
|
-
```
|
|
247
|
-
|
|
248
|
-
**Manual Configuration:**
|
|
249
|
-
|
|
250
|
-
```json
|
|
251
|
-
{
|
|
252
|
-
"env": {
|
|
253
|
-
"OPENROUTER_API_KEY": "<YOUR_KEY>",
|
|
254
|
-
"OPENAI_BASE_URL": "https://openrouter.ai/api/v1"
|
|
255
|
-
},
|
|
256
|
-
"default_model": "openrouter:openai/gpt-4.1"
|
|
257
|
-
}
|
|
258
|
-
```
|
|
259
|
-
|
|
260
|
-
**Popular Models:**
|
|
261
|
-
|
|
262
|
-
- `openrouter:mistralai/devstral-small`
|
|
263
|
-
- `openrouter:openai/gpt-4.1-mini`
|
|
264
|
-
- `openrouter:codex-mini-latest`
|
|
265
|
-
|
|
266
|
-
</details>
|
|
267
|
-
|
|
268
|
-
### MCP (Model Context Protocol) Support
|
|
269
|
-
|
|
270
|
-
<details>
|
|
271
|
-
<summary><b>Click to expand MCP configuration</b></summary>
|
|
272
|
-
|
|
273
|
-
Extend your AI's capabilities with MCP servers:
|
|
274
|
-
|
|
275
|
-
```json
|
|
276
|
-
{
|
|
277
|
-
"mcpServers": {
|
|
278
|
-
"fetch": {
|
|
279
|
-
"command": "uvx",
|
|
280
|
-
"args": ["mcp-server-fetch"]
|
|
281
|
-
},
|
|
282
|
-
"github": {
|
|
283
|
-
"command": "npx",
|
|
284
|
-
"args": ["-y", "@modelcontextprotocol/server-github"],
|
|
285
|
-
"env": {
|
|
286
|
-
"GITHUB_PERSONAL_ACCESS_TOKEN": "<YOUR_TOKEN>"
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
Learn more at [modelcontextprotocol.io](https://modelcontextprotocol.io/)
|
|
294
|
-
|
|
295
|
-
</details>
|
|
296
|
-
|
|
297
|
-
---
|
|
298
|
-
|
|
299
|
-
## Commands Reference
|
|
300
|
-
|
|
301
|
-
### Core Commands
|
|
302
|
-
|
|
303
|
-
| Command | Description |
|
|
304
|
-
| -------------------------------- | -------------------------------- |
|
|
305
|
-
| `/help` | Show available commands |
|
|
306
|
-
| `/yolo` | Toggle confirmation skipping |
|
|
307
|
-
| `/clear` | Clear message history |
|
|
308
|
-
| `/compact` | Summarize and clear old messages |
|
|
309
|
-
| `/model` | Show current model |
|
|
310
|
-
| `/model <provider:name>` | Switch model |
|
|
311
|
-
| `/model <provider:name> default` | Set default model |
|
|
312
|
-
| `/branch <name>` | Create and switch Git branch |
|
|
313
|
-
| `/dump` | Show message history (debug) |
|
|
314
|
-
| `!<command>` | Run shell command |
|
|
315
|
-
| `!` | Open interactive shell |
|
|
316
|
-
| `exit` | Exit application |
|
|
317
|
-
|
|
318
|
-
### Debug & Recovery Commands
|
|
319
|
-
|
|
320
|
-
| Command | Description |
|
|
321
|
-
| -------------------------------- | -------------------------------- |
|
|
322
|
-
| `/thoughts` | Toggle ReAct thought display |
|
|
323
|
-
| `/iterations <1-50>` | Set max reasoning iterations |
|
|
324
|
-
| `/parsetools` | Parse JSON tool calls manually |
|
|
325
|
-
| `/fix` | Fix orphaned tool calls |
|
|
326
|
-
| `/refresh` | Reload configuration from defaults |
|
|
327
|
-
|
|
328
|
-
---
|
|
329
|
-
|
|
330
|
-
## Available Tools
|
|
331
|
-
|
|
332
|
-
### Bash Tool
|
|
333
|
-
The enhanced bash tool provides advanced shell command execution with safety features:
|
|
334
|
-
|
|
335
|
-
- **Working Directory Support**: Execute commands in specific directories
|
|
336
|
-
- **Environment Variables**: Set custom environment variables for commands
|
|
337
|
-
- **Timeout Control**: Configurable timeouts (1-300 seconds) to prevent hanging
|
|
338
|
-
- **Output Capture**: Full stdout/stderr capture with truncation for large outputs
|
|
339
|
-
- **Safety Checks**: Warns about potentially destructive commands
|
|
340
|
-
- **Error Guidance**: Helpful error messages for common issues (command not found, permission denied, etc.)
|
|
341
|
-
|
|
342
|
-
**Example usage by the AI:**
|
|
343
|
-
```python
|
|
344
|
-
# Simple command
|
|
345
|
-
await bash("ls -la")
|
|
346
|
-
|
|
347
|
-
# With working directory
|
|
348
|
-
await bash("npm install", cwd="/path/to/project")
|
|
349
|
-
|
|
350
|
-
# With timeout for long operations
|
|
351
|
-
await bash("npm run build", timeout=120)
|
|
352
|
-
|
|
353
|
-
# With environment variables
|
|
354
|
-
await bash("python script.py", env={"API_KEY": "secret"})
|
|
355
|
-
```
|
|
356
|
-
|
|
357
|
-
### Other Core Tools
|
|
358
|
-
- **grep**: Fast parallel content search across files
|
|
359
|
-
- **read_file**: Read file contents with line numbers
|
|
360
|
-
- **write_file**: Create new files (fails if file exists)
|
|
361
|
-
- **update_file**: Modify existing files with precise replacements
|
|
362
|
-
- **run_command**: Basic command execution (simpler than bash)
|
|
363
|
-
|
|
364
|
-
---
|
|
365
|
-
|
|
366
|
-
## Reliability Features
|
|
367
|
-
|
|
368
|
-
### JSON Tool Parsing Fallback
|
|
369
|
-
|
|
370
|
-
TunaCode automatically handles API provider failures with robust JSON parsing:
|
|
371
|
-
|
|
372
|
-
- **Automatic Recovery**: When structured tool calling fails, TunaCode parses JSON from text responses
|
|
373
|
-
- **Multiple Formats**: Supports inline JSON, code blocks, and complex nested structures
|
|
374
|
-
- **Manual Recovery**: Use `/parsetools` when automatic parsing needs assistance
|
|
375
|
-
- **Visual Feedback**: See `🔧 Recovered using JSON tool parsing` messages during fallback
|
|
376
|
-
|
|
377
|
-
### Enhanced Error Handling
|
|
378
|
-
|
|
379
|
-
- **Tool Schema Fixes**: Consistent parameter naming across all tools
|
|
380
|
-
- **Orphaned Tool Call Recovery**: Automatic cleanup with `/fix` command
|
|
381
|
-
- **Configuration Refresh**: Update settings without restart using `/refresh`
|
|
382
|
-
- **ReAct Reasoning**: Configurable iteration limits for complex problem solving
|
|
383
|
-
|
|
384
|
-
---
|
|
385
|
-
|
|
386
|
-
## Customization
|
|
387
|
-
|
|
388
|
-
### Project Guides
|
|
389
|
-
|
|
390
|
-
Create a `TUNACODE.md` file in your project root to customize TunaCode's behavior:
|
|
391
|
-
|
|
392
|
-
```markdown
|
|
393
|
-
# Project Guide
|
|
394
|
-
|
|
395
|
-
## Tech Stack
|
|
396
|
-
|
|
397
|
-
- Python 3.11
|
|
398
|
-
- FastAPI
|
|
399
|
-
- PostgreSQL
|
|
400
|
-
|
|
401
|
-
## Preferences
|
|
402
|
-
|
|
403
|
-
- Use type hints
|
|
404
|
-
- Follow PEP 8
|
|
405
|
-
- Write tests for new features
|
|
406
|
-
```
|
|
407
|
-
|
|
408
|
-
---
|
|
409
|
-
|
|
410
|
-
## Source Code Architecture
|
|
411
|
-
|
|
412
|
-
### Directory Structure
|
|
413
|
-
|
|
414
|
-
```
|
|
415
|
-
src/tunacode/
|
|
416
|
-
├── cli/ # Command Line Interface
|
|
417
|
-
│ ├── commands.py # Command registry and implementations
|
|
418
|
-
│ ├── main.py # Entry point and CLI setup (Typer)
|
|
419
|
-
│ └── repl.py # Interactive REPL loop
|
|
420
|
-
│
|
|
421
|
-
├── configuration/ # Configuration Management
|
|
422
|
-
│ ├── defaults.py # Default configuration values
|
|
423
|
-
│ ├── models.py # Configuration data models
|
|
424
|
-
│ └── settings.py # Settings loader and validator
|
|
425
|
-
│
|
|
426
|
-
├── core/ # Core Application Logic
|
|
427
|
-
│ ├── agents/ # AI Agent System
|
|
428
|
-
│ │ ├── main.py # Primary agent implementation (pydantic-ai)
|
|
429
|
-
│ │ ├── orchestrator.py # Complex task orchestration and planning
|
|
430
|
-
│ │ ├── planner_schema.py # Planning data models
|
|
431
|
-
│ │ └── readonly.py # Read-only agent for safe exploration
|
|
432
|
-
│ ├── background/ # Background Task Management
|
|
433
|
-
│ │ └── manager.py # Async background task execution
|
|
434
|
-
│ ├── llm/ # LLM Integration
|
|
435
|
-
│ │ └── planner.py # LLM-based task planning
|
|
436
|
-
│ ├── setup/ # Application Setup & Initialization
|
|
437
|
-
│ │ ├── agent_setup.py # Agent configuration
|
|
438
|
-
│ │ ├── base.py # Setup step base class
|
|
439
|
-
│ │ ├── config_setup.py # Configuration setup
|
|
440
|
-
│ │ ├── coordinator.py # Setup orchestration
|
|
441
|
-
│ │ ├── environment_setup.py # Environment validation
|
|
442
|
-
│ │ └── git_safety_setup.py # Git safety checks
|
|
443
|
-
│ ├── state.py # Application state management
|
|
444
|
-
│ └── tool_handler.py # Tool execution and validation
|
|
445
|
-
│
|
|
446
|
-
├── services/ # External Services
|
|
447
|
-
│ └── mcp.py # Model Context Protocol integration
|
|
448
|
-
│
|
|
449
|
-
├── tools/ # AI Agent Tools
|
|
450
|
-
│ ├── base.py # Tool base classes
|
|
451
|
-
│ ├── bash.py # Enhanced shell command execution
|
|
452
|
-
│ ├── grep.py # Parallel content search tool
|
|
453
|
-
│ ├── read_file.py # File reading tool
|
|
454
|
-
│ ├── run_command.py # Basic command execution tool
|
|
455
|
-
│ ├── update_file.py # File modification tool
|
|
456
|
-
│ └── write_file.py # File creation tool
|
|
457
|
-
│
|
|
458
|
-
├── ui/ # User Interface Components
|
|
459
|
-
│ ├── completers.py # Tab completion
|
|
460
|
-
│ ├── console.py # Rich console setup
|
|
461
|
-
│ ├── input.py # Input handling
|
|
462
|
-
│ ├── keybindings.py # Keyboard shortcuts
|
|
463
|
-
│ ├── lexers.py # Syntax highlighting
|
|
464
|
-
│ ├── output.py # Output formatting and banner
|
|
465
|
-
│ ├── panels.py # UI panels and layouts
|
|
466
|
-
│ ├── prompt_manager.py # Prompt toolkit integration
|
|
467
|
-
│ ├── tool_ui.py # Tool confirmation dialogs
|
|
468
|
-
│ └── validators.py # Input validation
|
|
469
|
-
│
|
|
470
|
-
├── utils/ # Utility Functions
|
|
471
|
-
│ ├── bm25.py # BM25 search algorithm (beta)
|
|
472
|
-
│ ├── diff_utils.py # Diff generation and formatting
|
|
473
|
-
│ ├── file_utils.py # File system operations
|
|
474
|
-
│ ├── ripgrep.py # Code search utilities
|
|
475
|
-
│ ├── system.py # System information
|
|
476
|
-
│ ├── text_utils.py # Text processing
|
|
477
|
-
│ └── user_configuration.py # User config management
|
|
478
|
-
│
|
|
479
|
-
├── constants.py # Application constants
|
|
480
|
-
├── context.py # Context management
|
|
481
|
-
├── exceptions.py # Custom exceptions
|
|
482
|
-
├── types.py # Type definitions
|
|
483
|
-
└── prompts/
|
|
484
|
-
└── system.md # System prompts for AI agent
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
### Key Components
|
|
488
|
-
|
|
489
|
-
| Component | Purpose | Key Files |
|
|
490
|
-
| -------------------- | ------------------------ | ------------------------------- |
|
|
491
|
-
| **CLI Layer** | Command parsing and REPL | `cli/main.py`, `cli/repl.py` |
|
|
492
|
-
| **Agent System** | AI-powered assistance | `core/agents/main.py` |
|
|
493
|
-
| **Orchestrator** | Complex task planning | `core/agents/orchestrator.py` |
|
|
494
|
-
| **Background Tasks** | Async task execution | `core/background/manager.py` |
|
|
495
|
-
| **Tool System** | File/command operations | `tools/*.py` |
|
|
496
|
-
| **State Management** | Session state tracking | `core/state.py` |
|
|
497
|
-
| **UI Framework** | Rich terminal interface | `ui/output.py`, `ui/console.py` |
|
|
498
|
-
| **Configuration** | User settings & models | `configuration/*.py` |
|
|
499
|
-
| **Setup System** | Initial configuration | `core/setup/*.py` |
|
|
500
|
-
|
|
501
|
-
### Data Flow
|
|
502
|
-
|
|
503
|
-
```
|
|
504
|
-
CLI Input → Command Registry → REPL → Agent → Tools → UI Output
|
|
505
|
-
↓ ↓ ↓ ↓ ↓ ↑
|
|
506
|
-
State Manager ←────────────────────────────────────────┘
|
|
507
|
-
```
|
|
508
|
-
|
|
509
|
-
---
|
|
510
|
-
|
|
511
|
-
## Development
|
|
512
|
-
|
|
513
|
-
### Requirements
|
|
514
|
-
|
|
515
|
-
- Python 3.10+
|
|
516
|
-
- Git (for version control)
|
|
517
|
-
|
|
518
|
-
### Development Setup
|
|
519
|
-
|
|
520
|
-
```bash
|
|
521
|
-
# Install development dependencies
|
|
522
|
-
make install
|
|
523
|
-
|
|
524
|
-
# Run linting
|
|
525
|
-
make lint
|
|
526
|
-
|
|
527
|
-
# Run tests
|
|
528
|
-
make test
|
|
529
|
-
```
|
|
530
|
-
|
|
531
|
-
---
|
|
532
|
-
|
|
533
|
-
## Links
|
|
534
|
-
|
|
535
|
-
<div align="center">
|
|
536
|
-
|
|
537
|
-
[](https://pypi.org/project/tunacode-cli/)
|
|
538
|
-
[](https://github.com/alchemiststudiosDOTai/tunacode)
|
|
539
|
-
[](https://github.com/alchemiststudiosDOTai/tunacode/issues)
|
|
540
|
-
|
|
541
|
-
</div>
|
|
542
|
-
|
|
543
|
-
---
|
|
544
|
-
|
|
545
|
-
## License
|
|
546
|
-
|
|
547
|
-
MIT License - see [LICENSE](LICENSE) file for details.
|
|
548
|
-
|
|
549
|
-
## Acknowledgments
|
|
550
|
-
|
|
551
|
-
TunaCode is a fork of [sidekick-cli](https://github.com/geekforbrains/sidekick-cli). Special thanks to the sidekick-cli team for creating the foundation that made TunaCode possible.
|
|
552
|
-
|
|
553
|
-
### Key Differences from sidekick-cli
|
|
554
|
-
|
|
555
|
-
While TunaCode builds on the foundation of sidekick-cli, we've made several architectural changes for our workflow:
|
|
556
|
-
|
|
557
|
-
- **JSON Tool Parsing Fallback**: Added fallback parsing for when API providers fail with structured tool calling
|
|
558
|
-
- **Parallel Search Tools**: New `bash` and `grep` tools with parallel execution for codebase navigation
|
|
559
|
-
- **Agent Orchestration**: Advanced orchestrator for complex multi-step tasks with planning transparency
|
|
560
|
-
- **Background Processing**: Asynchronous task manager for long-running operations
|
|
561
|
-
- **Read-Only Agent**: Safe exploration mode that prevents accidental modifications
|
|
562
|
-
- **ReAct Reasoning**: Implemented ReAct (Reasoning + Acting) patterns with configurable iteration limits
|
|
563
|
-
- **Dynamic Configuration**: Added `/refresh` command and modified configuration management
|
|
564
|
-
- **Safety Changes**: Removed automatic git commits and `/undo` command - requires explicit git usage
|
|
565
|
-
- **Error Recovery**: Multiple fallback mechanisms and orphaned tool call recovery
|
|
566
|
-
- **Tool System Rewrite**: Complete overhaul of internal tools with atomic operations and different confirmation UIs
|
|
567
|
-
- **Debug Commands**: Added `/parsetools`, `/thoughts`, `/iterations` for debugging
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|