tunacode-cli 0.0.17__tar.gz → 0.0.19__tar.gz

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.

Files changed (95) hide show
  1. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/PKG-INFO +68 -11
  2. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/README.md +67 -10
  3. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/pyproject.toml +1 -1
  4. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/cli/commands.py +73 -41
  5. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/cli/main.py +29 -26
  6. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/cli/repl.py +91 -37
  7. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/cli/textual_app.py +69 -66
  8. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/cli/textual_bridge.py +33 -32
  9. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/configuration/settings.py +2 -9
  10. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/constants.py +2 -4
  11. tunacode_cli-0.0.19/src/tunacode/core/agents/__init__.py +12 -0
  12. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/core/agents/main.py +89 -63
  13. tunacode_cli-0.0.19/src/tunacode/core/agents/orchestrator.py +99 -0
  14. tunacode_cli-0.0.19/src/tunacode/core/agents/planner_schema.py +9 -0
  15. tunacode_cli-0.0.19/src/tunacode/core/agents/readonly.py +51 -0
  16. tunacode_cli-0.0.19/src/tunacode/core/background/manager.py +36 -0
  17. tunacode_cli-0.0.19/src/tunacode/core/llm/planner.py +63 -0
  18. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/core/setup/config_setup.py +79 -44
  19. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/core/setup/coordinator.py +20 -13
  20. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/core/setup/git_safety_setup.py +35 -49
  21. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/core/state.py +2 -9
  22. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/exceptions.py +0 -2
  23. tunacode_cli-0.0.19/src/tunacode/prompts/system.txt +203 -0
  24. tunacode_cli-0.0.19/src/tunacode/tools/__init__.py +10 -0
  25. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/tools/base.py +1 -1
  26. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/tools/bash.py +5 -5
  27. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/tools/grep.py +210 -250
  28. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/tools/read_file.py +2 -8
  29. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/tools/run_command.py +4 -11
  30. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/tools/update_file.py +2 -6
  31. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/ui/completers.py +32 -31
  32. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/ui/console.py +3 -3
  33. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/ui/input.py +8 -5
  34. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/ui/keybindings.py +1 -3
  35. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/ui/lexers.py +16 -16
  36. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/ui/output.py +2 -2
  37. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/ui/panels.py +8 -8
  38. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/ui/prompt_manager.py +19 -7
  39. tunacode_cli-0.0.19/src/tunacode/utils/__init__.py +0 -0
  40. tunacode_cli-0.0.19/src/tunacode/utils/import_cache.py +11 -0
  41. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/utils/user_configuration.py +24 -2
  42. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode_cli.egg-info/PKG-INFO +68 -11
  43. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode_cli.egg-info/SOURCES.txt +19 -1
  44. tunacode_cli-0.0.19/tests/test_architect_integration.py +120 -0
  45. tunacode_cli-0.0.19/tests/test_architect_simple.py +125 -0
  46. tunacode_cli-0.0.19/tests/test_background_manager.py +26 -0
  47. tunacode_cli-0.0.19/tests/test_fast_glob_search.py +191 -0
  48. tunacode_cli-0.0.19/tests/test_file_reference_expansion.py +158 -0
  49. tunacode_cli-0.0.19/tests/test_json_tool_parsing.py +207 -0
  50. tunacode_cli-0.0.19/tests/test_orchestrator_file_references.py +146 -0
  51. tunacode_cli-0.0.19/tests/test_orchestrator_import.py +22 -0
  52. tunacode_cli-0.0.19/tests/test_orchestrator_planning_visibility.py +56 -0
  53. tunacode_cli-0.0.19/tests/test_react_thoughts.py +149 -0
  54. tunacode_cli-0.0.19/tests/test_update_command.py +47 -0
  55. tunacode_cli-0.0.17/src/tunacode/prompts/system.txt +0 -93
  56. tunacode_cli-0.0.17/src/tunacode/tools/__init__.py +0 -1
  57. tunacode_cli-0.0.17/tests/test_escape_mechanism.py +0 -184
  58. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/LICENSE +0 -0
  59. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/setup.cfg +0 -0
  60. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/setup.py +0 -0
  61. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/__init__.py +0 -0
  62. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/cli/__init__.py +0 -0
  63. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/configuration/__init__.py +0 -0
  64. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/configuration/defaults.py +0 -0
  65. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/configuration/models.py +0 -0
  66. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/context.py +1 -1
  67. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/core/__init__.py +0 -0
  68. {tunacode_cli-0.0.17/src/tunacode/core/agents → tunacode_cli-0.0.19/src/tunacode/core/background}/__init__.py +0 -0
  69. {tunacode_cli-0.0.17/src/tunacode/utils → tunacode_cli-0.0.19/src/tunacode/core/llm}/__init__.py +0 -0
  70. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/core/setup/__init__.py +0 -0
  71. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/core/setup/agent_setup.py +0 -0
  72. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/core/setup/base.py +0 -0
  73. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/core/setup/environment_setup.py +0 -0
  74. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/core/tool_handler.py +0 -0
  75. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/py.typed +0 -0
  76. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/services/__init__.py +0 -0
  77. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/services/mcp.py +0 -0
  78. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/setup.py +0 -0
  79. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/tools/write_file.py +0 -0
  80. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/types.py +0 -0
  81. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/ui/__init__.py +0 -0
  82. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/ui/constants.py +0 -0
  83. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/ui/decorators.py +0 -0
  84. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/ui/tool_ui.py +0 -0
  85. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/ui/validators.py +0 -0
  86. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/utils/bm25.py +0 -0
  87. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/utils/diff_utils.py +0 -0
  88. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/utils/file_utils.py +0 -0
  89. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/utils/ripgrep.py +0 -0
  90. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/utils/system.py +0 -0
  91. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode/utils/text_utils.py +0 -0
  92. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode_cli.egg-info/dependency_links.txt +0 -0
  93. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode_cli.egg-info/entry_points.txt +0 -0
  94. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode_cli.egg-info/requires.txt +0 -0
  95. {tunacode_cli-0.0.17 → tunacode_cli-0.0.19}/src/tunacode_cli.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tunacode-cli
3
- Version: 0.0.17
3
+ Version: 0.0.19
4
4
  Summary: Your agentic CLI developer.
5
5
  Author-email: larock22 <noreply@github.com>
6
6
  License-Expression: MIT
@@ -58,14 +58,20 @@ Dynamic: license-file
58
58
 
59
59
  ---
60
60
 
61
- ### Recent Updates (v0.0.14)
62
-
63
- - **🔧 JSON Tool Parsing Fallback**: Automatic recovery when API providers fail with structured tool calling
64
- - **⚡ Enhanced Reliability**: Fixed parameter naming issues that caused tool schema errors
65
- - **🔄 Configuration Management**: New `/refresh` command to reload config without restart
66
- - **🧠 Improved ReAct Reasoning**: Enhanced iteration limits (now defaults to 20) and better thought processing
67
- - **🛠️ New Debug Commands**: `/parsetools` for manual JSON parsing, `/iterations` for controlling reasoning depth
68
- - **📊 Better Error Recovery**: Multiple fallback mechanisms for various failure scenarios
61
+ ### Recent Updates (v0.0.18)
62
+
63
+ - **Advanced Agent Orchestration**: New orchestrator system for complex multi-step tasks with planning visibility
64
+ - **Background Task Manager**: Asynchronous background processing for long-running operations
65
+ - **Read-Only Agent**: Specialized agent for safe codebase exploration without modification risks
66
+ - **Planning Transparency**: See the AI's planning process before execution with detailed task breakdowns
67
+ - **Shell Command Support**: Execute shell commands directly with `!command` or open interactive shell with `!`
68
+ - **Enhanced Bash Tool**: Advanced bash execution with timeouts, working directory, and environment variables
69
+ - **JSON Tool Parsing Fallback**: Automatic recovery when API providers fail with structured tool calling
70
+ - **Enhanced Reliability**: Fixed parameter naming issues that caused tool schema errors
71
+ - **Configuration Management**: New `/refresh` command to reload config without restart
72
+ - **Improved ReAct Reasoning**: Enhanced iteration limits (now defaults to 20) and better thought processing
73
+ - **New Debug Commands**: `/parsetools` for manual JSON parsing, `/iterations` for controlling reasoning depth
74
+ - **Better Error Recovery**: Multiple fallback mechanisms for various failure scenarios
69
75
 
70
76
  ### Core Features
71
77
 
@@ -84,6 +90,7 @@ Dynamic: license-file
84
90
  ### **Developer Tools**
85
91
 
86
92
  - 6 core tools: bash, grep, read_file, write_file, update_file, run_command
93
+ - Direct shell command execution with `!` prefix
87
94
  - MCP (Model Context Protocol) support
88
95
  - File operation confirmations with diffs
89
96
  - Per-project context guides (TUNACODE.md)
@@ -284,6 +291,8 @@ Learn more at [modelcontextprotocol.io](https://modelcontextprotocol.io/)
284
291
  | `/model <provider:name> default` | Set default model |
285
292
  | `/branch <name>` | Create and switch Git branch |
286
293
  | `/dump` | Show message history (debug) |
294
+ | `!<command>` | Run shell command |
295
+ | `!` | Open interactive shell |
287
296
  | `exit` | Exit application |
288
297
 
289
298
  ### Debug & Recovery Commands
@@ -298,6 +307,42 @@ Learn more at [modelcontextprotocol.io](https://modelcontextprotocol.io/)
298
307
 
299
308
  ---
300
309
 
310
+ ## Available Tools
311
+
312
+ ### Bash Tool
313
+ The enhanced bash tool provides advanced shell command execution with safety features:
314
+
315
+ - **Working Directory Support**: Execute commands in specific directories
316
+ - **Environment Variables**: Set custom environment variables for commands
317
+ - **Timeout Control**: Configurable timeouts (1-300 seconds) to prevent hanging
318
+ - **Output Capture**: Full stdout/stderr capture with truncation for large outputs
319
+ - **Safety Checks**: Warns about potentially destructive commands
320
+ - **Error Guidance**: Helpful error messages for common issues (command not found, permission denied, etc.)
321
+
322
+ **Example usage by the AI:**
323
+ ```python
324
+ # Simple command
325
+ await bash("ls -la")
326
+
327
+ # With working directory
328
+ await bash("npm install", cwd="/path/to/project")
329
+
330
+ # With timeout for long operations
331
+ await bash("npm run build", timeout=120)
332
+
333
+ # With environment variables
334
+ await bash("python script.py", env={"API_KEY": "secret"})
335
+ ```
336
+
337
+ ### Other Core Tools
338
+ - **grep**: Fast parallel content search across files
339
+ - **read_file**: Read file contents with line numbers
340
+ - **write_file**: Create new files (fails if file exists)
341
+ - **update_file**: Modify existing files with precise replacements
342
+ - **run_command**: Basic command execution (simpler than bash)
343
+
344
+ ---
345
+
301
346
  ## Reliability Features
302
347
 
303
348
  ### JSON Tool Parsing Fallback
@@ -360,7 +405,14 @@ src/tunacode/
360
405
 
361
406
  ├── core/ # Core Application Logic
362
407
  │ ├── agents/ # AI Agent System
363
- │ │ └── main.py # Primary agent implementation (pydantic-ai)
408
+ │ │ ├── main.py # Primary agent implementation (pydantic-ai)
409
+ │ │ ├── orchestrator.py # Complex task orchestration and planning
410
+ │ │ ├── planner_schema.py # Planning data models
411
+ │ │ └── readonly.py # Read-only agent for safe exploration
412
+ │ ├── background/ # Background Task Management
413
+ │ │ └── manager.py # Async background task execution
414
+ │ ├── llm/ # LLM Integration
415
+ │ │ └── planner.py # LLM-based task planning
364
416
  │ ├── setup/ # Application Setup & Initialization
365
417
  │ │ ├── agent_setup.py # Agent configuration
366
418
  │ │ ├── base.py # Setup step base class
@@ -409,7 +461,7 @@ src/tunacode/
409
461
  ├── exceptions.py # Custom exceptions
410
462
  ├── types.py # Type definitions
411
463
  └── prompts/
412
- └── system.txt # System prompts for AI agent
464
+ └── system.md # System prompts for AI agent
413
465
  ```
414
466
 
415
467
  ### Key Components
@@ -418,6 +470,8 @@ src/tunacode/
418
470
  | -------------------- | ------------------------ | ------------------------------- |
419
471
  | **CLI Layer** | Command parsing and REPL | `cli/main.py`, `cli/repl.py` |
420
472
  | **Agent System** | AI-powered assistance | `core/agents/main.py` |
473
+ | **Orchestrator** | Complex task planning | `core/agents/orchestrator.py` |
474
+ | **Background Tasks** | Async task execution | `core/background/manager.py` |
421
475
  | **Tool System** | File/command operations | `tools/*.py` |
422
476
  | **State Management** | Session state tracking | `core/state.py` |
423
477
  | **UI Framework** | Rich terminal interface | `ui/output.py`, `ui/console.py` |
@@ -482,6 +536,9 @@ While TunaCode builds on the foundation of sidekick-cli, we've made several arch
482
536
 
483
537
  - **JSON Tool Parsing Fallback**: Added fallback parsing for when API providers fail with structured tool calling
484
538
  - **Parallel Search Tools**: New `bash` and `grep` tools with parallel execution for codebase navigation
539
+ - **Agent Orchestration**: Advanced orchestrator for complex multi-step tasks with planning transparency
540
+ - **Background Processing**: Asynchronous task manager for long-running operations
541
+ - **Read-Only Agent**: Safe exploration mode that prevents accidental modifications
485
542
  - **ReAct Reasoning**: Implemented ReAct (Reasoning + Acting) patterns with configurable iteration limits
486
543
  - **Dynamic Configuration**: Added `/refresh` command and modified configuration management
487
544
  - **Safety Changes**: Removed automatic git commits and `/undo` command - requires explicit git usage
@@ -22,14 +22,20 @@
22
22
 
23
23
  ---
24
24
 
25
- ### Recent Updates (v0.0.14)
26
-
27
- - **🔧 JSON Tool Parsing Fallback**: Automatic recovery when API providers fail with structured tool calling
28
- - **⚡ Enhanced Reliability**: Fixed parameter naming issues that caused tool schema errors
29
- - **🔄 Configuration Management**: New `/refresh` command to reload config without restart
30
- - **🧠 Improved ReAct Reasoning**: Enhanced iteration limits (now defaults to 20) and better thought processing
31
- - **🛠️ New Debug Commands**: `/parsetools` for manual JSON parsing, `/iterations` for controlling reasoning depth
32
- - **📊 Better Error Recovery**: Multiple fallback mechanisms for various failure scenarios
25
+ ### Recent Updates (v0.0.18)
26
+
27
+ - **Advanced Agent Orchestration**: New orchestrator system for complex multi-step tasks with planning visibility
28
+ - **Background Task Manager**: Asynchronous background processing for long-running operations
29
+ - **Read-Only Agent**: Specialized agent for safe codebase exploration without modification risks
30
+ - **Planning Transparency**: See the AI's planning process before execution with detailed task breakdowns
31
+ - **Shell Command Support**: Execute shell commands directly with `!command` or open interactive shell with `!`
32
+ - **Enhanced Bash Tool**: Advanced bash execution with timeouts, working directory, and environment variables
33
+ - **JSON Tool Parsing Fallback**: Automatic recovery when API providers fail with structured tool calling
34
+ - **Enhanced Reliability**: Fixed parameter naming issues that caused tool schema errors
35
+ - **Configuration Management**: New `/refresh` command to reload config without restart
36
+ - **Improved ReAct Reasoning**: Enhanced iteration limits (now defaults to 20) and better thought processing
37
+ - **New Debug Commands**: `/parsetools` for manual JSON parsing, `/iterations` for controlling reasoning depth
38
+ - **Better Error Recovery**: Multiple fallback mechanisms for various failure scenarios
33
39
 
34
40
  ### Core Features
35
41
 
@@ -48,6 +54,7 @@
48
54
  ### **Developer Tools**
49
55
 
50
56
  - 6 core tools: bash, grep, read_file, write_file, update_file, run_command
57
+ - Direct shell command execution with `!` prefix
51
58
  - MCP (Model Context Protocol) support
52
59
  - File operation confirmations with diffs
53
60
  - Per-project context guides (TUNACODE.md)
@@ -248,6 +255,8 @@ Learn more at [modelcontextprotocol.io](https://modelcontextprotocol.io/)
248
255
  | `/model <provider:name> default` | Set default model |
249
256
  | `/branch <name>` | Create and switch Git branch |
250
257
  | `/dump` | Show message history (debug) |
258
+ | `!<command>` | Run shell command |
259
+ | `!` | Open interactive shell |
251
260
  | `exit` | Exit application |
252
261
 
253
262
  ### Debug & Recovery Commands
@@ -262,6 +271,42 @@ Learn more at [modelcontextprotocol.io](https://modelcontextprotocol.io/)
262
271
 
263
272
  ---
264
273
 
274
+ ## Available Tools
275
+
276
+ ### Bash Tool
277
+ The enhanced bash tool provides advanced shell command execution with safety features:
278
+
279
+ - **Working Directory Support**: Execute commands in specific directories
280
+ - **Environment Variables**: Set custom environment variables for commands
281
+ - **Timeout Control**: Configurable timeouts (1-300 seconds) to prevent hanging
282
+ - **Output Capture**: Full stdout/stderr capture with truncation for large outputs
283
+ - **Safety Checks**: Warns about potentially destructive commands
284
+ - **Error Guidance**: Helpful error messages for common issues (command not found, permission denied, etc.)
285
+
286
+ **Example usage by the AI:**
287
+ ```python
288
+ # Simple command
289
+ await bash("ls -la")
290
+
291
+ # With working directory
292
+ await bash("npm install", cwd="/path/to/project")
293
+
294
+ # With timeout for long operations
295
+ await bash("npm run build", timeout=120)
296
+
297
+ # With environment variables
298
+ await bash("python script.py", env={"API_KEY": "secret"})
299
+ ```
300
+
301
+ ### Other Core Tools
302
+ - **grep**: Fast parallel content search across files
303
+ - **read_file**: Read file contents with line numbers
304
+ - **write_file**: Create new files (fails if file exists)
305
+ - **update_file**: Modify existing files with precise replacements
306
+ - **run_command**: Basic command execution (simpler than bash)
307
+
308
+ ---
309
+
265
310
  ## Reliability Features
266
311
 
267
312
  ### JSON Tool Parsing Fallback
@@ -324,7 +369,14 @@ src/tunacode/
324
369
 
325
370
  ├── core/ # Core Application Logic
326
371
  │ ├── agents/ # AI Agent System
327
- │ │ └── main.py # Primary agent implementation (pydantic-ai)
372
+ │ │ ├── main.py # Primary agent implementation (pydantic-ai)
373
+ │ │ ├── orchestrator.py # Complex task orchestration and planning
374
+ │ │ ├── planner_schema.py # Planning data models
375
+ │ │ └── readonly.py # Read-only agent for safe exploration
376
+ │ ├── background/ # Background Task Management
377
+ │ │ └── manager.py # Async background task execution
378
+ │ ├── llm/ # LLM Integration
379
+ │ │ └── planner.py # LLM-based task planning
328
380
  │ ├── setup/ # Application Setup & Initialization
329
381
  │ │ ├── agent_setup.py # Agent configuration
330
382
  │ │ ├── base.py # Setup step base class
@@ -373,7 +425,7 @@ src/tunacode/
373
425
  ├── exceptions.py # Custom exceptions
374
426
  ├── types.py # Type definitions
375
427
  └── prompts/
376
- └── system.txt # System prompts for AI agent
428
+ └── system.md # System prompts for AI agent
377
429
  ```
378
430
 
379
431
  ### Key Components
@@ -382,6 +434,8 @@ src/tunacode/
382
434
  | -------------------- | ------------------------ | ------------------------------- |
383
435
  | **CLI Layer** | Command parsing and REPL | `cli/main.py`, `cli/repl.py` |
384
436
  | **Agent System** | AI-powered assistance | `core/agents/main.py` |
437
+ | **Orchestrator** | Complex task planning | `core/agents/orchestrator.py` |
438
+ | **Background Tasks** | Async task execution | `core/background/manager.py` |
385
439
  | **Tool System** | File/command operations | `tools/*.py` |
386
440
  | **State Management** | Session state tracking | `core/state.py` |
387
441
  | **UI Framework** | Rich terminal interface | `ui/output.py`, `ui/console.py` |
@@ -446,6 +500,9 @@ While TunaCode builds on the foundation of sidekick-cli, we've made several arch
446
500
 
447
501
  - **JSON Tool Parsing Fallback**: Added fallback parsing for when API providers fail with structured tool calling
448
502
  - **Parallel Search Tools**: New `bash` and `grep` tools with parallel execution for codebase navigation
503
+ - **Agent Orchestration**: Advanced orchestrator for complex multi-step tasks with planning transparency
504
+ - **Background Processing**: Asynchronous task manager for long-running operations
505
+ - **Read-Only Agent**: Safe exploration mode that prevents accidental modifications
449
506
  - **ReAct Reasoning**: Implemented ReAct (Reasoning + Acting) patterns with configurable iteration limits
450
507
  - **Dynamic Configuration**: Added `/refresh` command and modified configuration management
451
508
  - **Safety Changes**: Removed automatic git commits and `/undo` command - requires explicit git usage
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "tunacode-cli"
7
- version = "0.0.17"
7
+ version = "0.0.19"
8
8
  description = "Your agentic CLI developer."
9
9
  keywords = ["cli", "agent", "development", "automation"]
10
10
  readme = "README.md"
@@ -6,7 +6,6 @@ from enum import Enum
6
6
  from typing import Any, Dict, List, Optional, Type
7
7
 
8
8
  from .. import utils
9
- from ..configuration.models import ModelRegistry
10
9
  from ..exceptions import ValidationError
11
10
  from ..types import CommandArgs, CommandContext, CommandResult, ProcessRequestCallback
12
11
  from ..ui import console as ui
@@ -116,9 +115,9 @@ class YoloCommand(SimpleCommand):
116
115
  state = context.state_manager.session
117
116
  state.yolo = not state.yolo
118
117
  if state.yolo:
119
- await ui.success("Ooh shit, its YOLO time!\n")
118
+ await ui.success("All tools are now active ⚡ Please proceed with caution.\n")
120
119
  else:
121
- await ui.info("Pfft, boring...\n")
120
+ await ui.info("Tool confirmations re-enabled for safety.\n")
122
121
 
123
122
 
124
123
  class DumpCommand(SimpleCommand):
@@ -168,6 +167,39 @@ class ThoughtsCommand(SimpleCommand):
168
167
  await ui.success(f"Thought display {status}")
169
168
 
170
169
 
170
+ class ArchitectCommand(SimpleCommand):
171
+ """Toggle architect mode for task planning and orchestration."""
172
+
173
+ def __init__(self):
174
+ super().__init__(
175
+ CommandSpec(
176
+ name="architect",
177
+ aliases=["/architect"],
178
+ description="Toggle architect mode (task planning & orchestration)",
179
+ category=CommandCategory.DEBUG,
180
+ )
181
+ )
182
+
183
+ async def execute(self, args: List[str], context: CommandContext) -> None:
184
+ state = context.state_manager.session
185
+ if args:
186
+ arg = args[0].lower()
187
+ if arg in {"on", "1", "true"}:
188
+ state.architect_mode = True
189
+ elif arg in {"off", "0", "false"}:
190
+ state.architect_mode = False
191
+ else:
192
+ await ui.error("Usage: /architect [on|off]")
193
+ return
194
+ else:
195
+ state.architect_mode = not getattr(state, 'architect_mode', False)
196
+ status = "ON" if state.architect_mode else "OFF"
197
+ if state.architect_mode:
198
+ await ui.success(f"Architect mode {status} - Requests will be planned before execution")
199
+ else:
200
+ await ui.success(f"Architect mode {status} - Using direct execution")
201
+
202
+
171
203
  class IterationsCommand(SimpleCommand):
172
204
  """Configure maximum agent iterations for ReAct reasoning."""
173
205
 
@@ -189,12 +221,12 @@ class IterationsCommand(SimpleCommand):
189
221
  if new_limit < 1 or new_limit > 50:
190
222
  await ui.error("Iterations must be between 1 and 50")
191
223
  return
192
-
224
+
193
225
  # Update the user config
194
226
  if "settings" not in state.user_config:
195
227
  state.user_config["settings"] = {}
196
228
  state.user_config["settings"]["max_iterations"] = new_limit
197
-
229
+
198
230
  await ui.success(f"Maximum iterations set to {new_limit}")
199
231
  await ui.muted("Higher values allow more complex reasoning but may be slower")
200
232
  except ValueError:
@@ -221,8 +253,9 @@ class ClearCommand(SimpleCommand):
221
253
  async def execute(self, args: List[str], context: CommandContext) -> None:
222
254
  # Patch any orphaned tool calls before clearing
223
255
  from tunacode.core.agents.main import patch_tool_messages
256
+
224
257
  patch_tool_messages("Conversation cleared", context.state_manager)
225
-
258
+
226
259
  await ui.clear()
227
260
  context.state_manager.session.messages = []
228
261
  await ui.success("Message history cleared")
@@ -243,17 +276,17 @@ class FixCommand(SimpleCommand):
243
276
 
244
277
  async def execute(self, args: List[str], context: CommandContext) -> None:
245
278
  from tunacode.core.agents.main import patch_tool_messages
246
-
279
+
247
280
  # Count current messages
248
281
  before_count = len(context.state_manager.session.messages)
249
-
282
+
250
283
  # Patch orphaned tool calls
251
284
  patch_tool_messages("Tool call resolved by /fix command", context.state_manager)
252
-
285
+
253
286
  # Count after patching
254
287
  after_count = len(context.state_manager.session.messages)
255
288
  patched_count = after_count - before_count
256
-
289
+
257
290
  if patched_count > 0:
258
291
  await ui.success(f"Fixed {patched_count} orphaned tool call(s)")
259
292
  await ui.muted("You can now continue the conversation normally")
@@ -269,36 +302,37 @@ class ParseToolsCommand(SimpleCommand):
269
302
  CommandSpec(
270
303
  name="parsetools",
271
304
  aliases=["/parsetools"],
272
- description="Parse JSON tool calls from last response when structured calling fails",
305
+ description=(
306
+ "Parse JSON tool calls from last response when structured calling fails"
307
+ ),
273
308
  category=CommandCategory.DEBUG,
274
309
  )
275
310
  )
276
311
 
277
312
  async def execute(self, args: List[str], context: CommandContext) -> None:
278
313
  from tunacode.core.agents.main import extract_and_execute_tool_calls
279
-
314
+
280
315
  # Find the last model response in messages
281
316
  messages = context.state_manager.session.messages
282
317
  if not messages:
283
318
  await ui.error("No message history found")
284
319
  return
285
-
320
+
286
321
  # Look for the most recent response with text content
287
322
  found_content = False
288
323
  for msg in reversed(messages):
289
- if hasattr(msg, 'parts'):
324
+ if hasattr(msg, "parts"):
290
325
  for part in msg.parts:
291
- if hasattr(part, 'content') and isinstance(part.content, str):
326
+ if hasattr(part, "content") and isinstance(part.content, str):
292
327
  # Create tool callback
293
328
  from tunacode.cli.repl import _tool_handler
329
+
294
330
  def tool_callback_with_state(part, node):
295
331
  return _tool_handler(part, node, context.state_manager)
296
-
332
+
297
333
  try:
298
334
  await extract_and_execute_tool_calls(
299
- part.content,
300
- tool_callback_with_state,
301
- context.state_manager
335
+ part.content, tool_callback_with_state, context.state_manager
302
336
  )
303
337
  await ui.success("JSON tool parsing completed")
304
338
  found_content = True
@@ -306,7 +340,7 @@ class ParseToolsCommand(SimpleCommand):
306
340
  except Exception as e:
307
341
  await ui.error(f"Failed to parse tools: {str(e)}")
308
342
  return
309
-
343
+
310
344
  if not found_content:
311
345
  await ui.error("No parseable content found in recent messages")
312
346
 
@@ -326,7 +360,7 @@ class RefreshConfigCommand(SimpleCommand):
326
360
 
327
361
  async def execute(self, args: List[str], context: CommandContext) -> None:
328
362
  from tunacode.configuration.defaults import DEFAULT_USER_CONFIG
329
-
363
+
330
364
  # Update current session config with latest defaults
331
365
  for key, value in DEFAULT_USER_CONFIG.items():
332
366
  if key not in context.state_manager.session.user_config:
@@ -336,9 +370,11 @@ class RefreshConfigCommand(SimpleCommand):
336
370
  for subkey, subvalue in value.items():
337
371
  if subkey not in context.state_manager.session.user_config[key]:
338
372
  context.state_manager.session.user_config[key][subkey] = subvalue
339
-
373
+
340
374
  # Show updated max_iterations
341
- max_iterations = context.state_manager.session.user_config.get("settings", {}).get("max_iterations", 20)
375
+ max_iterations = context.state_manager.session.user_config.get("settings", {}).get(
376
+ "max_iterations", 20
377
+ )
342
378
  await ui.success(f"Configuration refreshed - max iterations: {max_iterations}")
343
379
 
344
380
 
@@ -507,23 +543,20 @@ class UpdateCommand(SimpleCommand):
507
543
  )
508
544
 
509
545
  async def execute(self, args: List[str], context: CommandContext) -> None:
546
+ import shutil
510
547
  import subprocess
511
548
  import sys
512
- import shutil
513
549
 
514
550
  await ui.info("Checking for TunaCode updates...")
515
551
 
516
552
  # Detect installation method
517
553
  installation_method = None
518
-
554
+
519
555
  # Check if installed via pipx
520
556
  if shutil.which("pipx"):
521
557
  try:
522
558
  result = subprocess.run(
523
- ["pipx", "list"],
524
- capture_output=True,
525
- text=True,
526
- timeout=10
559
+ ["pipx", "list"], capture_output=True, text=True, timeout=10
527
560
  )
528
561
  if "tunacode" in result.stdout.lower():
529
562
  installation_method = "pipx"
@@ -534,10 +567,10 @@ class UpdateCommand(SimpleCommand):
534
567
  if not installation_method:
535
568
  try:
536
569
  result = subprocess.run(
537
- [sys.executable, "-m", "pip", "show", "tunacode-cli"],
538
- capture_output=True,
539
- text=True,
540
- timeout=10
570
+ [sys.executable, "-m", "pip", "show", "tunacode-cli"],
571
+ capture_output=True,
572
+ text=True,
573
+ timeout=10,
541
574
  )
542
575
  if result.returncode == 0:
543
576
  installation_method = "pip"
@@ -556,10 +589,7 @@ class UpdateCommand(SimpleCommand):
556
589
  if installation_method == "pipx":
557
590
  await ui.info("Updating via pipx...")
558
591
  result = subprocess.run(
559
- ["pipx", "upgrade", "tunacode"],
560
- capture_output=True,
561
- text=True,
562
- timeout=60
592
+ ["pipx", "upgrade", "tunacode"], capture_output=True, text=True, timeout=60
563
593
  )
564
594
  else: # pip
565
595
  await ui.info("Updating via pip...")
@@ -567,16 +597,16 @@ class UpdateCommand(SimpleCommand):
567
597
  [sys.executable, "-m", "pip", "install", "--upgrade", "tunacode-cli"],
568
598
  capture_output=True,
569
599
  text=True,
570
- timeout=60
600
+ timeout=60,
571
601
  )
572
602
 
573
603
  if result.returncode == 0:
574
604
  await ui.success("TunaCode updated successfully!")
575
605
  await ui.muted("Restart TunaCode to use the new version")
576
-
606
+
577
607
  # Show update output if available
578
608
  if result.stdout.strip():
579
- output_lines = result.stdout.strip().split('\n')
609
+ output_lines = result.stdout.strip().split("\n")
580
610
  for line in output_lines[-5:]: # Show last 5 lines
581
611
  if line.strip():
582
612
  await ui.muted(f" {line}")
@@ -723,6 +753,7 @@ class CommandRegistry:
723
753
  YoloCommand,
724
754
  DumpCommand,
725
755
  ThoughtsCommand,
756
+ ArchitectCommand,
726
757
  IterationsCommand,
727
758
  ClearCommand,
728
759
  FixCommand,
@@ -798,8 +829,9 @@ class CommandRegistry:
798
829
  return await command.execute(args, context)
799
830
  else:
800
831
  # Ambiguous - show possibilities
832
+ matches_str = ", ".join(sorted(set(matches)))
801
833
  raise ValidationError(
802
- f"Ambiguous command '{command_name}'. Did you mean: {', '.join(sorted(set(matches)))}?"
834
+ f"Ambiguous command '{command_name}'. Did you mean: {matches_str}?"
803
835
  )
804
836
 
805
837
  def find_matching_commands(self, partial_command: str) -> List[str]:
@@ -24,36 +24,39 @@ state_manager = StateManager()
24
24
  def main(
25
25
  version: bool = typer.Option(False, "--version", "-v", help="Show version and exit."),
26
26
  run_setup: bool = typer.Option(False, "--setup", help="Run setup process."),
27
- baseurl: str = typer.Option(None, "--baseurl", help="API base URL (e.g., https://openrouter.ai/api/v1)"),
27
+ baseurl: str = typer.Option(
28
+ None, "--baseurl", help="API base URL (e.g., https://openrouter.ai/api/v1)"
29
+ ),
28
30
  model: str = typer.Option(None, "--model", help="Default model to use (e.g., openai/gpt-4)"),
29
31
  key: str = typer.Option(None, "--key", help="API key for the provider"),
30
32
  ):
31
33
  """🚀 Start TunaCode - Your AI-powered development assistant"""
32
-
33
- if version:
34
- asyncio.run(ui.version())
35
- return
36
-
37
- asyncio.run(ui.banner())
38
-
39
- has_update, latest_version = check_for_updates()
40
- if has_update:
41
- asyncio.run(ui.show_update_message(latest_version))
42
-
43
- # Pass CLI args to setup
44
- cli_config = {}
45
- if baseurl or model or key:
46
- cli_config = {
47
- "baseurl": baseurl,
48
- "model": model,
49
- "key": key
50
- }
51
-
52
- try:
53
- asyncio.run(setup(run_setup, state_manager, cli_config))
54
- asyncio.run(repl(state_manager))
55
- except Exception as e:
56
- asyncio.run(ui.error(str(e)))
34
+
35
+ async def async_main():
36
+ if version:
37
+ await ui.version()
38
+ return
39
+
40
+ await ui.banner()
41
+
42
+ # Start update check in background
43
+ update_task = asyncio.to_thread(check_for_updates)
44
+
45
+ cli_config = {}
46
+ if baseurl or model or key:
47
+ cli_config = {"baseurl": baseurl, "model": model, "key": key}
48
+
49
+ try:
50
+ await setup(run_setup, state_manager, cli_config)
51
+ await repl(state_manager)
52
+ except Exception as e:
53
+ await ui.error(str(e))
54
+
55
+ has_update, latest_version = await update_task
56
+ if has_update:
57
+ await ui.update_available(latest_version)
58
+
59
+ asyncio.run(async_main())
57
60
 
58
61
 
59
62
  if __name__ == "__main__":