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

Files changed (44) hide show
  1. tunacode/cli/commands.py +3 -4
  2. tunacode/cli/main.py +5 -4
  3. tunacode/cli/repl.py +2 -13
  4. tunacode/cli/textual_app.py +423 -0
  5. tunacode/cli/textual_bridge.py +158 -0
  6. tunacode/configuration/defaults.py +3 -4
  7. tunacode/configuration/models.py +3 -3
  8. tunacode/configuration/settings.py +2 -2
  9. tunacode/constants.py +2 -10
  10. tunacode/core/agents/main.py +3 -3
  11. tunacode/core/setup/__init__.py +0 -2
  12. tunacode/core/setup/agent_setup.py +3 -3
  13. tunacode/core/setup/base.py +3 -3
  14. tunacode/core/setup/config_setup.py +16 -6
  15. tunacode/core/setup/coordinator.py +2 -2
  16. tunacode/core/setup/environment_setup.py +2 -2
  17. tunacode/core/setup/git_safety_setup.py +1 -2
  18. tunacode/core/state.py +3 -3
  19. tunacode/setup.py +2 -3
  20. tunacode/tools/base.py +4 -43
  21. tunacode/tools/read_file.py +2 -2
  22. tunacode/tools/run_command.py +2 -2
  23. tunacode/tools/update_file.py +3 -3
  24. tunacode/tools/write_file.py +3 -3
  25. tunacode/ui/completers.py +1 -1
  26. tunacode/ui/console.py +2 -3
  27. tunacode/ui/constants.py +1 -1
  28. tunacode/ui/decorators.py +2 -2
  29. tunacode/ui/input.py +1 -1
  30. tunacode/ui/keybindings.py +1 -1
  31. tunacode/ui/output.py +11 -4
  32. tunacode/ui/panels.py +3 -4
  33. tunacode/ui/prompt_manager.py +1 -1
  34. tunacode/ui/validators.py +1 -1
  35. tunacode/utils/diff_utils.py +3 -3
  36. {tunacode_cli-0.0.10.dist-info → tunacode_cli-0.0.12.dist-info}/METADATA +115 -40
  37. tunacode_cli-0.0.12.dist-info/RECORD +65 -0
  38. tunacode/core/setup/undo_setup.py +0 -33
  39. tunacode/services/undo_service.py +0 -244
  40. tunacode_cli-0.0.10.dist-info/RECORD +0 -65
  41. {tunacode_cli-0.0.10.dist-info → tunacode_cli-0.0.12.dist-info}/WHEEL +0 -0
  42. {tunacode_cli-0.0.10.dist-info → tunacode_cli-0.0.12.dist-info}/entry_points.txt +0 -0
  43. {tunacode_cli-0.0.10.dist-info → tunacode_cli-0.0.12.dist-info}/licenses/LICENSE +0 -0
  44. {tunacode_cli-0.0.10.dist-info → tunacode_cli-0.0.12.dist-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.10
3
+ Version: 0.0.12
4
4
  Summary: Your agentic CLI developer.
5
5
  Author-email: larock22 <noreply@github.com>
6
6
  License-Expression: MIT
@@ -19,11 +19,11 @@ Classifier: Topic :: Utilities
19
19
  Requires-Python: >=3.10
20
20
  Description-Content-Type: text/markdown
21
21
  License-File: LICENSE
22
+ Requires-Dist: typer==0.15.3
22
23
  Requires-Dist: prompt_toolkit==3.0.51
23
24
  Requires-Dist: pydantic-ai[logfire]==0.2.6
24
25
  Requires-Dist: pygments==2.19.1
25
26
  Requires-Dist: rich==14.0.0
26
- Requires-Dist: typer==0.15.3
27
27
  Provides-Extra: dev
28
28
  Requires-Dist: build; extra == "dev"
29
29
  Requires-Dist: black; extra == "dev"
@@ -31,6 +31,7 @@ Requires-Dist: flake8; extra == "dev"
31
31
  Requires-Dist: isort; extra == "dev"
32
32
  Requires-Dist: pytest; extra == "dev"
33
33
  Requires-Dist: pytest-cov; extra == "dev"
34
+ Requires-Dist: textual-dev; extra == "dev"
34
35
  Dynamic: license-file
35
36
 
36
37
  # TunaCode
@@ -126,6 +127,27 @@ pip install tunacode-cli
126
127
  wget -qO- https://raw.githubusercontent.com/alchemiststudiosDOTai/tunacode/master/scripts/install_linux.sh | bash
127
128
  ```
128
129
 
130
+ ### Uninstallation
131
+
132
+ To completely remove TunaCode from your system:
133
+
134
+ ```bash
135
+ # Download and run the uninstall script
136
+ wget -qO- https://raw.githubusercontent.com/alchemiststudiosDOTai/tunacode/master/scripts/uninstall.sh | bash
137
+
138
+ # Or manually:
139
+ # 1. Remove the package
140
+ pipx uninstall tunacode # if installed via pipx
141
+ # OR
142
+ pip uninstall tunacode-cli # if installed via pip
143
+
144
+ # 2. Remove configuration files
145
+ rm -rf ~/.config/tunacode*
146
+
147
+ # 3. Remove any leftover binaries
148
+ rm -f ~/.local/bin/tunacode
149
+ ```
150
+
129
151
  ### Setup Options
130
152
 
131
153
  <details>
@@ -285,6 +307,97 @@ Create a `TUNACODE.md` file your project root to customize TunaCode's behavior:
285
307
 
286
308
  ---
287
309
 
310
+ ## Source Code Architecture
311
+
312
+ ### Directory Structure
313
+
314
+ ```
315
+ src/tunacode/
316
+ ├── cli/ # Command Line Interface
317
+ │ ├── commands.py # Command registry and implementations
318
+ │ ├── main.py # Entry point and CLI setup (Typer)
319
+ │ └── repl.py # Interactive REPL loop
320
+
321
+ ├── configuration/ # Configuration Management
322
+ │ ├── defaults.py # Default configuration values
323
+ │ ├── models.py # Configuration data models
324
+ │ └── settings.py # Settings loader and validator
325
+
326
+ ├── core/ # Core Application Logic
327
+ │ ├── agents/ # AI Agent System
328
+ │ │ └── main.py # Primary agent implementation (pydantic-ai)
329
+ │ ├── setup/ # Application Setup & Initialization
330
+ │ │ ├── agent_setup.py # Agent configuration
331
+ │ │ ├── base.py # Setup step base class
332
+ │ │ ├── config_setup.py # Configuration setup
333
+ │ │ ├── coordinator.py # Setup orchestration
334
+ │ │ ├── environment_setup.py # Environment validation
335
+ │ │ └── git_safety_setup.py # Git safety checks
336
+ │ ├── state.py # Application state management
337
+ │ └── tool_handler.py # Tool execution and validation
338
+
339
+ ├── services/ # External Services
340
+ │ ├── mcp.py # Model Context Protocol integration
341
+ │ └── undo_service.py # Undo operations (beta)
342
+
343
+ ├── tools/ # AI Agent Tools
344
+ │ ├── base.py # Tool base classes
345
+ │ ├── read_file.py # File reading tool
346
+ │ ├── run_command.py # Command execution tool
347
+ │ ├── update_file.py # File modification tool
348
+ │ └── write_file.py # File creation tool
349
+
350
+ ├── ui/ # User Interface Components
351
+ │ ├── completers.py # Tab completion
352
+ │ ├── console.py # Rich console setup
353
+ │ ├── input.py # Input handling
354
+ │ ├── keybindings.py # Keyboard shortcuts
355
+ │ ├── lexers.py # Syntax highlighting
356
+ │ ├── output.py # Output formatting and banner
357
+ │ ├── panels.py # UI panels and layouts
358
+ │ ├── prompt_manager.py # Prompt toolkit integration
359
+ │ ├── tool_ui.py # Tool confirmation dialogs
360
+ │ └── validators.py # Input validation
361
+
362
+ ├── utils/ # Utility Functions
363
+ │ ├── bm25.py # BM25 search algorithm(beta)
364
+ │ ├── diff_utils.py # Diff generation and formatting
365
+ │ ├── file_utils.py # File system operations
366
+ │ ├── ripgrep.py # Code search utilities
367
+ │ ├── system.py # System information
368
+ │ ├── text_utils.py # Text processing
369
+ │ └── user_configuration.py # User config management
370
+
371
+ ├── constants.py # Application constants
372
+ ├── context.py # Context management
373
+ ├── exceptions.py # Custom exceptions
374
+ ├── types.py # Type definitions
375
+ └── prompts/
376
+ └── system.txt # System prompts for AI agent
377
+ ```
378
+
379
+ ### Key Components
380
+
381
+ | Component | Purpose | Key Files |
382
+ | -------------------- | ------------------------ | ------------------------------- |
383
+ | **CLI Layer** | Command parsing and REPL | `cli/main.py`, `cli/repl.py` |
384
+ | **Agent System** | AI-powered assistance | `core/agents/main.py` |
385
+ | **Tool System** | File/command operations | `tools/*.py` |
386
+ | **State Management** | Session state tracking | `core/state.py` |
387
+ | **UI Framework** | Rich terminal interface | `ui/output.py`, `ui/console.py` |
388
+ | **Configuration** | User settings & models | `configuration/*.py` |
389
+ | **Setup System** | Initial configuration | `core/setup/*.py` |
390
+
391
+ ### Data Flow
392
+
393
+ ```
394
+ CLI Input → Command Registry → REPL → Agent → Tools → UI Output
395
+ ↓ ↓ ↓ ↓ ↓ ↑
396
+ State Manager ←────────────────────────────────────────┘
397
+ ```
398
+
399
+ ---
400
+
288
401
  ## Development
289
402
 
290
403
  ### Requirements
@@ -305,44 +418,6 @@ make lint
305
418
  make test
306
419
  ```
307
420
 
308
- ### Release Process
309
-
310
- <details>
311
- <summary><b>Click to expand release steps</b></summary>
312
-
313
- 1. **Update versions:**
314
-
315
- - `pyproject.toml`
316
- - `src/tunacode/constants.py` (APP_VERSION)
317
-
318
- 2. **Commit and tag:**
319
-
320
- ```bash
321
- git add pyproject.toml src/tunacode/constants.py
322
- git commit -m "chore: bump version to X.Y.Z"
323
- git tag vX.Y.Z
324
- git push origin vX.Y.Z
325
- ```
326
-
327
- 3. **Create release:**
328
- ```bash
329
- gh release create vX.Y.Z --title "vX.Y.Z" --notes "Release notes"
330
- ```
331
-
332
- </details>
333
-
334
- ### Commit Convention
335
-
336
- Following [Conventional Commits](https://www.conventionalcommits.org/):
337
-
338
- - `feat:` New features
339
- - `fix:` Bug fixes
340
- - `docs:` Documentation
341
- - `style:` Code formatting
342
- - `refactor:` Code refactoring
343
- - `test:` Tests
344
- - `chore:` Maintenance
345
-
346
421
  ---
347
422
 
348
423
  ## Links
@@ -0,0 +1,65 @@
1
+ tunacode/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ tunacode/constants.py,sha256=RPAd2a-jP0RifT8Rfj1EVfoG8i7U5viyk99HKLwPy5U,3807
3
+ tunacode/context.py,sha256=0ttsxxLAyD4pSoxw7S-pyzor0JUkhOFZh96aAf4Kqsg,2634
4
+ tunacode/exceptions.py,sha256=RFUH8wOsWEvSPGIYM2exr4t47YkEyZt4Fr-DfTo6_JY,2647
5
+ tunacode/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
+ tunacode/setup.py,sha256=dYn0NeAxtNIDSogWEmGSyjb9wsr8AonZ8vAo5sw9NIw,1909
7
+ tunacode/types.py,sha256=5mMJDgFqVcKzhtHh9unPISBFqkeNje6KISGUpRkqRjY,7146
8
+ tunacode/cli/__init__.py,sha256=zgs0UbAck8hfvhYsWhWOfBe5oK09ug2De1r4RuQZREA,55
9
+ tunacode/cli/commands.py,sha256=80GuUnzJs5JxOr-5Vf4mzkMSCWLST4neTqJKnAzfKOM,18431
10
+ tunacode/cli/main.py,sha256=mmJ-x5fUcW2349fz-85LSiNRf0hvKOw0TQfxtPWWbDg,1760
11
+ tunacode/cli/repl.py,sha256=AhLmKZBNqxyLCsQAiM9ef7qYjqlRzb4sE1130Cx74QA,8579
12
+ tunacode/cli/textual_app.py,sha256=EdeeKjIikrtj-3FleBtP5DX5KwnMjc_bPepUB5DDkvw,13202
13
+ tunacode/cli/textual_bridge.py,sha256=QoPNSCVwdzVoNE5WzcZiH0jk2JopAoEvCRXGifwCzYU,6417
14
+ tunacode/configuration/__init__.py,sha256=MbVXy8bGu0yKehzgdgZ_mfWlYGvIdb1dY2Ly75nfuPE,17
15
+ tunacode/configuration/defaults.py,sha256=x2SynAuIKSOEAdtn4md2B1tVUh3DqHC1wohLhu0tNU0,658
16
+ tunacode/configuration/models.py,sha256=XPobkLM_TzKTuMIWhK-svJfGRGFT9r2LhKEM6rv6QHk,3756
17
+ tunacode/configuration/settings.py,sha256=KoN0u6GG3Hh_TWt02D_wpRfbACYri3gCDTXHtJfHl2w,994
18
+ tunacode/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ tunacode/core/state.py,sha256=sf3xvc9NBnz98tkHiSi-mi1GgxuN-r5kERwjmuIKjq8,1344
20
+ tunacode/core/tool_handler.py,sha256=OKx7jM8pml6pSEnoARu33_uBY8awJBqvhbVeBn6T4ow,1804
21
+ tunacode/core/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
22
+ tunacode/core/agents/main.py,sha256=o6EJUWBbOMqg9Y9UVgn_3l2ZK8iJveK5UpAmWQQYz0E,4661
23
+ tunacode/core/setup/__init__.py,sha256=lzdpY6rIGf9DDlDBDGFvQZaSOQeFsNglHbkpq1-GtU8,376
24
+ tunacode/core/setup/agent_setup.py,sha256=trELO8cPnWo36BBnYmXDEnDPdhBg0p-VLnx9A8hSSSQ,1401
25
+ tunacode/core/setup/base.py,sha256=cbyT2-xK2mWgH4EO17VfM_OM2bj0kT895NW2jSXbe3c,968
26
+ tunacode/core/setup/config_setup.py,sha256=pAa6nLNuJPsMzDMxwZj_d0DxvT-rIJuPxflV4gkCPzU,12007
27
+ tunacode/core/setup/coordinator.py,sha256=Rdudp2znfAV240HdXjvXPAn_4VZt_pNZBgEY8v_uPHw,1652
28
+ tunacode/core/setup/environment_setup.py,sha256=n3IrObKEynHZSwtUJ1FddMg2C4sHz7ca42awemImV8s,2225
29
+ tunacode/core/setup/git_safety_setup.py,sha256=6sAQ0L74rRpayR7hWpnPyGKxCzW1Mk-2gm1BLt-fRyg,7170
30
+ tunacode/prompts/system.txt,sha256=6ecousLK6KvRj6wzIVyzRE7OPQVC5n7P6ceSbtmmaZQ,3207
31
+ tunacode/services/__init__.py,sha256=w_E8QK6RnvKSvU866eDe8BCRV26rAm4d3R-Yg06OWCU,19
32
+ tunacode/services/mcp.py,sha256=R48X73KQjQ9vwhBrtbWHSBl-4K99QXmbIhh5J_1Gezo,3046
33
+ tunacode/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ tunacode/tools/base.py,sha256=UioygDbXy0JY67EIcyEoYt2TBfX9-n9Usf_1huQ4zOE,7046
35
+ tunacode/tools/read_file.py,sha256=ZNX9PvaYcI2Hw_GeSpQ3_wEy26DQ3LqLwYlaCVYDXO0,3051
36
+ tunacode/tools/run_command.py,sha256=jI5TWi4SKukfUkCdcFpSWDULsAM4RQN2Du0VTttIWvs,3796
37
+ tunacode/tools/update_file.py,sha256=QQwdTHUbtfwjCa2sbbrf-d2uIfZY1SQH1wkvjKU9OlQ,4137
38
+ tunacode/tools/write_file.py,sha256=nSIr2yN3JWALm9GUxUwCh5B6C9ej64HHR4PC0BURvuQ,2818
39
+ tunacode/ui/__init__.py,sha256=aRNE2pS50nFAX6y--rSGMNYwhz905g14gRd6g4BolYU,13
40
+ tunacode/ui/completers.py,sha256=E3dUe3jHsrIwqWWfWQGCHWnnpo6NJAZXBhlzY3yDKPw,5051
41
+ tunacode/ui/console.py,sha256=2Su2y9o5zQVmOP-V1SMhTqMjqsiAMXXY-iB9QNHkvxM,1890
42
+ tunacode/ui/constants.py,sha256=A76B_KpM8jCuBYRg4cPmhi8_j6LLyWttO7_jjv47r3w,421
43
+ tunacode/ui/decorators.py,sha256=e2KM-_pI5EKHa2M045IjUe4rPkTboxaKHXJT0K3461g,1914
44
+ tunacode/ui/input.py,sha256=5jE7k97vEMuEDS4L2nn7DQe_0R5_GJbf-MzHQxXV1GM,2962
45
+ tunacode/ui/keybindings.py,sha256=SJ4Lbkh2Mi4i9WeTkIizqZXfgUJ89BM2dksK7ne_5IE,701
46
+ tunacode/ui/lexers.py,sha256=3qFwogyS_3zlS0NDxbc4e_sPvNHylNdCVMjPIIp85go,1507
47
+ tunacode/ui/output.py,sha256=ms9pS6noo7i5GAw36fSEwLiGTDH22Fcu3FnwwqWETl8,4259
48
+ tunacode/ui/panels.py,sha256=iDnOho-_ySMQummUEotAnpBqOez6_LFN8zhWAh56f2Y,5952
49
+ tunacode/ui/prompt_manager.py,sha256=2HBaRQWMOhsk_CmzcwxPN5UMfUPxhf32ZR8fP3KMwBc,4010
50
+ tunacode/ui/tool_ui.py,sha256=S5-k1HwRlSqiQ8shGQ_QYGXQbuzb6Pg7u3CTqZwffdQ,6533
51
+ tunacode/ui/validators.py,sha256=MMIMT1I2v0l2jIy-gxX_4GSApvUTi8XWIOACr_dmoBA,758
52
+ tunacode/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
+ tunacode/utils/bm25.py,sha256=yq7KFWP3g_zIsjUV7l2hFPXYCzXyNQUInLU7u4qsc_4,1909
54
+ tunacode/utils/diff_utils.py,sha256=V9QqQ0q4MfabVTnWptF3IXDp3estnfOKcJtDe_Sj14I,2372
55
+ tunacode/utils/file_utils.py,sha256=AXiAJ_idtlmXEi9pMvwtfPy9Ys3yK-F4K7qb_NpwonU,923
56
+ tunacode/utils/ripgrep.py,sha256=AXUs2FFt0A7KBV996deS8wreIlUzKOlAHJmwrcAr4No,583
57
+ tunacode/utils/system.py,sha256=FSoibTIH0eybs4oNzbYyufIiV6gb77QaeY2yGqW39AY,11381
58
+ tunacode/utils/text_utils.py,sha256=B9M1cuLTm_SSsr15WNHF6j7WdLWPvWzKZV0Lvfgdbjg,2458
59
+ tunacode/utils/user_configuration.py,sha256=uFrpSRTUf0CijZjw1rOp1sovqy1uyr0UNcn85S6jvdk,1790
60
+ tunacode_cli-0.0.12.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
61
+ tunacode_cli-0.0.12.dist-info/METADATA,sha256=cgYzSgQ7fjai-wCWUiETKaqpU-itmLUhIkM1ZUIK7bg,12837
62
+ tunacode_cli-0.0.12.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
63
+ tunacode_cli-0.0.12.dist-info/entry_points.txt,sha256=hbkytikj4dGu6rizPuAd_DGUPBGF191RTnhr9wdhORY,51
64
+ tunacode_cli-0.0.12.dist-info/top_level.txt,sha256=lKy2P6BWNi5XSA4DHFvyjQ14V26lDZctwdmhEJrxQbU,9
65
+ tunacode_cli-0.0.12.dist-info/RECORD,,
@@ -1,33 +0,0 @@
1
- """Module: sidekick.core.setup.undo_setup
2
-
3
- Undo system initialization for the Sidekick CLI.
4
- Sets up file tracking and state management for undo operations.
5
- """
6
-
7
- from tunacode.core.setup.base import BaseSetup
8
- from tunacode.core.state import StateManager
9
- from tunacode.services.undo_service import init_undo_system
10
-
11
-
12
- class UndoSetup(BaseSetup):
13
- """Setup step for undo system initialization."""
14
-
15
- def __init__(self, state_manager: StateManager):
16
- super().__init__(state_manager)
17
-
18
- @property
19
- def name(self) -> str:
20
- return "Undo System"
21
-
22
- async def should_run(self, force_setup: bool = False) -> bool:
23
- """Undo setup should run if not already initialized."""
24
- return not self.state_manager.session.undo_initialized
25
-
26
- async def execute(self, force_setup: bool = False) -> None:
27
- """Initialize the undo system."""
28
- self.state_manager.session.undo_initialized = init_undo_system(self.state_manager)
29
-
30
- async def validate(self) -> bool:
31
- """Validate that undo system setup completed (even if disabled)."""
32
- # Validation passes if setup was attempted, regardless of whether undo is enabled
33
- return True
@@ -1,244 +0,0 @@
1
- """
2
- Module: tunacode.services.undo_service
3
-
4
- Provides Git-based undo functionality for TunaCode operations.
5
- Manages automatic commits and rollback operations.
6
- """
7
-
8
- import subprocess
9
- import time
10
- from pathlib import Path
11
- from typing import Optional, Tuple
12
-
13
- from pydantic_ai.messages import ModelResponse, TextPart
14
-
15
- from tunacode.constants import (ERROR_UNDO_INIT, UNDO_DISABLED_HOME, UNDO_DISABLED_NO_GIT,
16
- UNDO_GIT_TIMEOUT, UNDO_INITIAL_COMMIT)
17
- from tunacode.core.state import StateManager
18
- from tunacode.exceptions import GitOperationError
19
- from tunacode.ui import console as ui
20
- from tunacode.utils.system import get_session_dir
21
-
22
-
23
- def is_in_git_project(directory: Optional[Path] = None) -> bool:
24
- """
25
- Recursively check if the given directory is inside a git project.
26
-
27
- Args:
28
- directory (Path, optional): Directory to check. Defaults to current working directory.
29
-
30
- Returns:
31
- bool: True if in a git project, False otherwise
32
- """
33
- if directory is None:
34
- directory = Path.cwd()
35
-
36
- if (directory / ".git").exists():
37
- return True
38
-
39
- if directory == directory.parent:
40
- return False
41
-
42
- return is_in_git_project(directory.parent)
43
-
44
-
45
- def init_undo_system(state_manager: StateManager) -> bool:
46
- """
47
- Initialize the undo system by creating a Git repository
48
- in the ~/.tunacode/sessions/<session-id> directory.
49
-
50
- Skip initialization if running from home directory or not in a git project.
51
-
52
- Args:
53
- state_manager: The StateManager instance.
54
-
55
- Returns:
56
- bool: True if the undo system was initialized, False otherwise.
57
- """
58
- cwd = Path.cwd()
59
- home_dir = Path.home()
60
-
61
- if cwd == home_dir:
62
- print(f"⚠️ {UNDO_DISABLED_HOME}")
63
- return False
64
-
65
- if not is_in_git_project():
66
- # Temporarily use sync print for warnings during init
67
- print("⚠️ Not in a git repository - undo functionality will be limited")
68
- print("💡 To enable undo functionality, run: git init")
69
- print(" File operations will still work, but can't be undone")
70
- return False
71
-
72
- # Get the session directory path
73
- session_dir = get_session_dir(state_manager)
74
- tunacode_git_dir = session_dir / ".git"
75
-
76
- # Check if already initialized
77
- if tunacode_git_dir.exists():
78
- return True
79
-
80
- # Initialize Git repository
81
- try:
82
- subprocess.run(
83
- ["git", "init", str(session_dir)], capture_output=True, check=True, timeout=5
84
- )
85
-
86
- # Make an initial commit
87
- git_dir_arg = f"--git-dir={tunacode_git_dir}"
88
-
89
- # Add all files
90
- subprocess.run(["git", git_dir_arg, "add", "."], capture_output=True, check=True, timeout=5)
91
-
92
- # Create initial commit
93
- subprocess.run(
94
- ["git", git_dir_arg, "commit", "-m", UNDO_INITIAL_COMMIT],
95
- capture_output=True,
96
- check=True,
97
- timeout=5,
98
- )
99
-
100
- return True
101
- except subprocess.TimeoutExpired as e:
102
- error = GitOperationError(operation="init", message=UNDO_GIT_TIMEOUT, original_error=e)
103
- print(f"⚠️ {str(error)}")
104
- return False
105
- except Exception as e:
106
- error = GitOperationError(operation="init", message=str(e), original_error=e)
107
- print(f"⚠️ {ERROR_UNDO_INIT.format(e=e)}")
108
- return False
109
-
110
-
111
- def commit_for_undo(
112
- message_prefix: str = "tunacode", state_manager: Optional[StateManager] = None
113
- ) -> bool:
114
- """
115
- Commit the current state to the undo repository.
116
-
117
- Args:
118
- message_prefix (str): Prefix for the commit message.
119
- state_manager: The StateManager instance.
120
-
121
- Returns:
122
- bool: True if the commit was successful, False otherwise.
123
- """
124
- # Get the session directory and git dir
125
- if state_manager is None:
126
- raise ValueError("state_manager is required for commit_for_undo")
127
- session_dir = get_session_dir(state_manager)
128
- tunacode_git_dir = session_dir / ".git"
129
-
130
- if not tunacode_git_dir.exists():
131
- return False
132
-
133
- try:
134
- git_dir_arg = f"--git-dir={tunacode_git_dir}"
135
-
136
- # Add all files
137
- subprocess.run(["git", git_dir_arg, "add", "."], capture_output=True, timeout=5)
138
-
139
- # Create commit with timestamp
140
- timestamp = time.strftime("%Y-%m-%d %H:%M:%S")
141
- commit_message = f"{message_prefix} - {timestamp}"
142
-
143
- result = subprocess.run(
144
- ["git", git_dir_arg, "commit", "-m", commit_message],
145
- capture_output=True,
146
- text=True,
147
- timeout=5,
148
- )
149
-
150
- # Handle case where there are no changes to commit
151
- if "nothing to commit" in result.stdout or "nothing to commit" in result.stderr:
152
- return False
153
-
154
- return True
155
- except subprocess.TimeoutExpired as e:
156
- error = GitOperationError(
157
- operation="commit", message="Git commit timed out", original_error=e
158
- )
159
- print(f"⚠️ {str(error)}")
160
- return False
161
- except Exception as e:
162
- error = GitOperationError(operation="commit", message=str(e), original_error=e)
163
- print(f"⚠️ Error creating undo commit: {e}")
164
- return False
165
-
166
-
167
- def perform_undo(state_manager: StateManager) -> Tuple[bool, str]:
168
- """
169
- Undo the most recent change by resetting to the previous commit.
170
- Also adds a system message to the chat history to inform the AI
171
- that the last changes were undone.
172
-
173
- Args:
174
- state_manager: The StateManager instance.
175
-
176
- Returns:
177
- tuple: (bool, str) - Success status and message
178
- """
179
- # Get the session directory and git dir
180
- session_dir = get_session_dir(state_manager)
181
- tunacode_git_dir = session_dir / ".git"
182
-
183
- if not tunacode_git_dir.exists():
184
- return False, "Undo system not initialized"
185
-
186
- try:
187
- git_dir_arg = f"--git-dir={tunacode_git_dir}"
188
-
189
- # Get commit log to check if we have commits to undo
190
- result = subprocess.run(
191
- ["git", git_dir_arg, "log", "--format=%H", "-n", "2"],
192
- capture_output=True,
193
- text=True,
194
- check=True,
195
- timeout=5,
196
- )
197
-
198
- commits = result.stdout.strip().split("\n")
199
- if len(commits) < 2:
200
- return False, "Nothing to undo"
201
-
202
- # Get the commit message of the commit we're undoing for context
203
- commit_msg_result = subprocess.run(
204
- ["git", git_dir_arg, "log", "--format=%B", "-n", "1"],
205
- capture_output=True,
206
- text=True,
207
- check=True,
208
- timeout=5,
209
- )
210
- commit_msg = commit_msg_result.stdout.strip()
211
-
212
- # Perform reset to previous commit
213
- subprocess.run(
214
- ["git", git_dir_arg, "reset", "--hard", "HEAD~1"],
215
- capture_output=True,
216
- check=True,
217
- timeout=5,
218
- )
219
-
220
- # Add a system message to the chat history to inform the AI
221
- # about the undo operation
222
- state_manager.session.messages.append(
223
- ModelResponse(
224
- parts=[
225
- TextPart(
226
- content=(
227
- "The last changes were undone. "
228
- f"Commit message of undone changes: {commit_msg}"
229
- )
230
- )
231
- ],
232
- kind="response",
233
- )
234
- )
235
-
236
- return True, "Successfully undid last change"
237
- except subprocess.TimeoutExpired as e:
238
- error = GitOperationError(
239
- operation="reset", message="Undo operation timed out", original_error=e
240
- )
241
- return False, str(error)
242
- except Exception as e:
243
- error = GitOperationError(operation="reset", message=str(e), original_error=e)
244
- return False, f"Error performing undo: {e}"
@@ -1,65 +0,0 @@
1
- tunacode/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- tunacode/constants.py,sha256=6sdwSsDllPvvZ7l2yGQLoOigIZBIMND34qa_01TWtH0,4235
3
- tunacode/context.py,sha256=0ttsxxLAyD4pSoxw7S-pyzor0JUkhOFZh96aAf4Kqsg,2634
4
- tunacode/exceptions.py,sha256=RFUH8wOsWEvSPGIYM2exr4t47YkEyZt4Fr-DfTo6_JY,2647
5
- tunacode/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
- tunacode/setup.py,sha256=4LIlYtDk5FzBoJzC9Uw_9VmVUkZ8ojmeNdrxspBa2BU,2016
7
- tunacode/types.py,sha256=5mMJDgFqVcKzhtHh9unPISBFqkeNje6KISGUpRkqRjY,7146
8
- tunacode/cli/__init__.py,sha256=zgs0UbAck8hfvhYsWhWOfBe5oK09ug2De1r4RuQZREA,55
9
- tunacode/cli/commands.py,sha256=6q2gRN9uSd_BQTBUQK7QGpFUR7i0QtBTs5n8BPHkFCo,18473
10
- tunacode/cli/main.py,sha256=BXsWm4b-XtmnJBh-9g4X0Dt5y6jNR-mIugzw9jPigNM,1721
11
- tunacode/cli/repl.py,sha256=oQ7w7SQ8TXi8V6fmxxy7WDpCWJueZUtIUBa14-yPfvk,9115
12
- tunacode/configuration/__init__.py,sha256=MbVXy8bGu0yKehzgdgZ_mfWlYGvIdb1dY2Ly75nfuPE,17
13
- tunacode/configuration/defaults.py,sha256=6CQbXUslZLShZCyRqak_Hz8d889jPxfB-QQ26qnIuUg,683
14
- tunacode/configuration/models.py,sha256=SclALgdHhL1ffxNMlSamTVA_EJvxlcTbtqdHJ502n5o,3781
15
- tunacode/configuration/settings.py,sha256=4vXHiRuhyU6vW1nvtxzxEMSnT5E0mhZ0RwtAiKtGcq8,991
16
- tunacode/core/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
17
- tunacode/core/state.py,sha256=0U_WU92yn5EQ27BLlHIkNIJJqjLMNHKNYSoba1rQqbQ,1376
18
- tunacode/core/tool_handler.py,sha256=OKx7jM8pml6pSEnoARu33_uBY8awJBqvhbVeBn6T4ow,1804
19
- tunacode/core/agents/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- tunacode/core/agents/main.py,sha256=ZGB-EUQ7ow-m3ohSAmfPZ5UN9XC2Gbz40rKjsZsWwrA,4669
21
- tunacode/core/setup/__init__.py,sha256=jlveyriTXRcnoBLU6_TJ7Z-3E6EXjT9L5GD1vW4dei0,427
22
- tunacode/core/setup/agent_setup.py,sha256=65FVtta4xE9Dg_rDgVBsUkIHsAjXEavhmvAy5eFS5IA,1411
23
- tunacode/core/setup/base.py,sha256=x9uYOITulrf4faP70NPTNBPb-wW1ZJGmcjAe0Sk5slk,961
24
- tunacode/core/setup/config_setup.py,sha256=xeEZu-xDFRwbCONshS0NHsc3eQH1IxpGaUC_wuDjQYo,11163
25
- tunacode/core/setup/coordinator.py,sha256=v_zJIPCGlJWEApY5I2S7VR5uKAQe0TVn5zI-NYq2m_c,1653
26
- tunacode/core/setup/environment_setup.py,sha256=c371l9ePPmI-3I4NCJVu3iQg_tgFZz_X7qWbc_Lld_k,2234
27
- tunacode/core/setup/git_safety_setup.py,sha256=1NuzSASi0b69wQRpcOgINKklGnq34Xh3itm_PEpjDus,7238
28
- tunacode/core/setup/undo_setup.py,sha256=uHy7YWXPnxQ-b_36SNKtMZNyDR_u-p4OPDARHAgp6Lo,1179
29
- tunacode/prompts/system.txt,sha256=6ecousLK6KvRj6wzIVyzRE7OPQVC5n7P6ceSbtmmaZQ,3207
30
- tunacode/services/__init__.py,sha256=w_E8QK6RnvKSvU866eDe8BCRV26rAm4d3R-Yg06OWCU,19
31
- tunacode/services/mcp.py,sha256=R48X73KQjQ9vwhBrtbWHSBl-4K99QXmbIhh5J_1Gezo,3046
32
- tunacode/services/undo_service.py,sha256=lb2IlSv7bMDOOz72iVAiAy-0U49T1MsCO9bhhNhdzww,7783
33
- tunacode/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
- tunacode/tools/base.py,sha256=5IXKgiHVnV7pPgWTiT0mhFLy2dA2vuryy8Ri_CHsZBY,8936
35
- tunacode/tools/read_file.py,sha256=QW97pPVcHvNJk48iPSwzOZ9Dbq_Ce8lQ7W0F82SXi7k,3051
36
- tunacode/tools/run_command.py,sha256=dspFV71g98gbOQV6CT9LsEoytQ_4zyVqqZD99zf__OY,3796
37
- tunacode/tools/update_file.py,sha256=oG7ELWX3uHboDs2BPy8hfZb6hh0bQOav-LlWIRynMO4,4145
38
- tunacode/tools/write_file.py,sha256=bV-Xz_Wy_SaCqU78PcxP2ttScfH7F7GGnvs4P7EDuAM,2821
39
- tunacode/ui/__init__.py,sha256=aRNE2pS50nFAX6y--rSGMNYwhz905g14gRd6g4BolYU,13
40
- tunacode/ui/completers.py,sha256=mWnZmm8tjTuIgDq7Y8znwjKEF_ZAvrkMKPx1DEdqLJQ,5060
41
- tunacode/ui/console.py,sha256=7ua1LaBP3ZCRHzV0SqVCkgNlgBuBcBTcvybRjWl5jew,1943
42
- tunacode/ui/constants.py,sha256=NxegAWaoDaEa4gzNZ7p67M0ZsHJJxZMtf2bW8E5WeZE,421
43
- tunacode/ui/decorators.py,sha256=I09tETtxPfcWdh1B3kEM0nJ8E6HvdBZAdYhRzYUa_p8,1901
44
- tunacode/ui/input.py,sha256=IZovxw_-1zEJ-OXMdb0O0T-bqn7Eo09NFc6M6yq3fp0,2962
45
- tunacode/ui/keybindings.py,sha256=uT23EYLLoso-b4ppN-RqbdYOYanGqMr5FKm8OphhhFs,701
46
- tunacode/ui/lexers.py,sha256=3qFwogyS_3zlS0NDxbc4e_sPvNHylNdCVMjPIIp85go,1507
47
- tunacode/ui/output.py,sha256=p9q5dTHaqvawtM2TTDi-mnIsAiY0WNMWcLF2pFQaFnM,3716
48
- tunacode/ui/panels.py,sha256=Ju4eOOfrazPVjySiyEcXkame7IXHiBb2HZFWKl5Re48,6008
49
- tunacode/ui/prompt_manager.py,sha256=i8LBDFalo72b9YP1-65X0v0DA62k-auSVEJMXXr31fs,4010
50
- tunacode/ui/tool_ui.py,sha256=S5-k1HwRlSqiQ8shGQ_QYGXQbuzb6Pg7u3CTqZwffdQ,6533
51
- tunacode/ui/validators.py,sha256=wkg-lQrP-Wjm5phUHKD3Mte8F1J3A2EjESQgPPtRcvQ,758
52
- tunacode/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
53
- tunacode/utils/bm25.py,sha256=yq7KFWP3g_zIsjUV7l2hFPXYCzXyNQUInLU7u4qsc_4,1909
54
- tunacode/utils/diff_utils.py,sha256=V9PM1Of0wvWNTVyw7iZYrNowFuRiKSyWiw5F39yRRYA,2394
55
- tunacode/utils/file_utils.py,sha256=AXiAJ_idtlmXEi9pMvwtfPy9Ys3yK-F4K7qb_NpwonU,923
56
- tunacode/utils/ripgrep.py,sha256=AXUs2FFt0A7KBV996deS8wreIlUzKOlAHJmwrcAr4No,583
57
- tunacode/utils/system.py,sha256=FSoibTIH0eybs4oNzbYyufIiV6gb77QaeY2yGqW39AY,11381
58
- tunacode/utils/text_utils.py,sha256=B9M1cuLTm_SSsr15WNHF6j7WdLWPvWzKZV0Lvfgdbjg,2458
59
- tunacode/utils/user_configuration.py,sha256=uFrpSRTUf0CijZjw1rOp1sovqy1uyr0UNcn85S6jvdk,1790
60
- tunacode_cli-0.0.10.dist-info/licenses/LICENSE,sha256=Btzdu2kIoMbdSp6OyCLupB1aRgpTCJ_szMimgEnpkkE,1056
61
- tunacode_cli-0.0.10.dist-info/METADATA,sha256=jPpFb8CYOsphFyiT-stgLBMTHhtyQorUFCDIsdIM1xU,8705
62
- tunacode_cli-0.0.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
63
- tunacode_cli-0.0.10.dist-info/entry_points.txt,sha256=hbkytikj4dGu6rizPuAd_DGUPBGF191RTnhr9wdhORY,51
64
- tunacode_cli-0.0.10.dist-info/top_level.txt,sha256=lKy2P6BWNi5XSA4DHFvyjQ14V26lDZctwdmhEJrxQbU,9
65
- tunacode_cli-0.0.10.dist-info/RECORD,,