tunacode-cli 0.0.49__tar.gz → 0.0.50__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 (181) hide show
  1. {tunacode_cli-0.0.49/src/tunacode_cli.egg-info → tunacode_cli-0.0.50}/PKG-INFO +1 -1
  2. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/pyproject.toml +1 -1
  3. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/constants.py +1 -1
  4. tunacode_cli-0.0.50/src/tunacode/core/logging/config.py +57 -0
  5. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/types.py +4 -0
  6. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50/src/tunacode_cli.egg-info}/PKG-INFO +1 -1
  7. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode_cli.egg-info/SOURCES.txt +1 -0
  8. tunacode_cli-0.0.50/tests/characterization/context/test_tunacode_logging.py +84 -0
  9. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/ui/test_async_ui.py +7 -5
  10. tunacode_cli-0.0.50/tests/test_logging_config.py +112 -0
  11. tunacode_cli-0.0.49/src/tunacode/core/logging/config.py +0 -28
  12. tunacode_cli-0.0.49/tests/characterization/context/test_tunacode_logging.py +0 -74
  13. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/CLAUDE.md +0 -0
  14. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/LICENSE +0 -0
  15. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/MANIFEST.in +0 -0
  16. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/README.md +0 -0
  17. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/TUNACODE.md +0 -0
  18. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/setup.cfg +0 -0
  19. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/setup.py +0 -0
  20. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/api/auth.py +0 -0
  21. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/api/users.py +0 -0
  22. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/__init__.py +0 -0
  23. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/cli/__init__.py +0 -0
  24. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/cli/commands/__init__.py +0 -0
  25. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/cli/commands/base.py +0 -0
  26. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/cli/commands/implementations/__init__.py +0 -0
  27. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/cli/commands/implementations/conversation.py +0 -0
  28. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/cli/commands/implementations/debug.py +0 -0
  29. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/cli/commands/implementations/development.py +0 -0
  30. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/cli/commands/implementations/model.py +0 -0
  31. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/cli/commands/implementations/system.py +0 -0
  32. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/cli/commands/implementations/todo.py +0 -0
  33. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/cli/commands/registry.py +0 -0
  34. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/cli/main.py +0 -0
  35. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/cli/repl.py +0 -0
  36. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/configuration/__init__.py +0 -0
  37. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/configuration/defaults.py +0 -0
  38. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/configuration/models.py +0 -0
  39. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/configuration/settings.py +0 -0
  40. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/context.py +0 -0
  41. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/__init__.py +0 -0
  42. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/agents/__init__.py +0 -0
  43. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/agents/main.py +0 -0
  44. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/agents/utils.py +0 -0
  45. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/background/__init__.py +0 -0
  46. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/background/manager.py +0 -0
  47. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/code_index.py +0 -0
  48. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/llm/__init__.py +0 -0
  49. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/logging/__init__.py +0 -0
  50. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/logging/formatters.py +0 -0
  51. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/logging/handlers.py +0 -0
  52. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/logging/logger.py +0 -0
  53. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/recursive/__init__.py +0 -0
  54. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/recursive/aggregator.py +0 -0
  55. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/recursive/budget.py +0 -0
  56. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/recursive/decomposer.py +0 -0
  57. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/recursive/executor.py +0 -0
  58. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/recursive/hierarchy.py +0 -0
  59. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/setup/__init__.py +0 -0
  60. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/setup/agent_setup.py +0 -0
  61. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/setup/base.py +0 -0
  62. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/setup/config_setup.py +0 -0
  63. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/setup/coordinator.py +0 -0
  64. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/setup/environment_setup.py +0 -0
  65. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/setup/git_safety_setup.py +0 -0
  66. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/state.py +0 -0
  67. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/token_usage/api_response_parser.py +0 -0
  68. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/token_usage/cost_calculator.py +0 -0
  69. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/token_usage/usage_tracker.py +0 -0
  70. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/core/tool_handler.py +0 -0
  71. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/exceptions.py +0 -0
  72. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/prompts/system.md +0 -0
  73. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/py.typed +0 -0
  74. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/services/__init__.py +0 -0
  75. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/services/mcp.py +0 -0
  76. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/setup.py +0 -0
  77. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/tools/__init__.py +0 -0
  78. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/tools/base.py +0 -0
  79. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/tools/bash.py +0 -0
  80. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/tools/glob.py +0 -0
  81. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/tools/grep.py +0 -0
  82. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/tools/list_dir.py +0 -0
  83. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/tools/read_file.py +0 -0
  84. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/tools/read_file_async_poc.py +0 -0
  85. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/tools/run_command.py +0 -0
  86. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/tools/todo.py +0 -0
  87. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/tools/update_file.py +0 -0
  88. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/tools/write_file.py +0 -0
  89. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/__init__.py +0 -0
  90. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/completers.py +0 -0
  91. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/console.py +0 -0
  92. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/constants.py +0 -0
  93. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/decorators.py +0 -0
  94. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/input.py +0 -0
  95. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/keybindings.py +0 -0
  96. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/lexers.py +0 -0
  97. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/logging_compat.py +0 -0
  98. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/output.py +0 -0
  99. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/panels.py +0 -0
  100. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/prompt_manager.py +0 -0
  101. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/recursive_progress.py +0 -0
  102. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/tool_ui.py +0 -0
  103. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/utils.py +0 -0
  104. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/ui/validators.py +0 -0
  105. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/utils/__init__.py +0 -0
  106. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/utils/bm25.py +0 -0
  107. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/utils/diff_utils.py +0 -0
  108. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/utils/file_utils.py +0 -0
  109. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/utils/import_cache.py +0 -0
  110. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/utils/message_utils.py +0 -0
  111. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/utils/retry.py +0 -0
  112. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/utils/ripgrep.py +0 -0
  113. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/utils/security.py +0 -0
  114. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/utils/system.py +0 -0
  115. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/utils/text_utils.py +0 -0
  116. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/utils/token_counter.py +0 -0
  117. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode/utils/user_configuration.py +0 -0
  118. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode_cli.egg-info/dependency_links.txt +0 -0
  119. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode_cli.egg-info/entry_points.txt +0 -0
  120. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode_cli.egg-info/requires.txt +0 -0
  121. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/src/tunacode_cli.egg-info/top_level.txt +0 -0
  122. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/agent/__init__.py +0 -0
  123. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/agent/conftest.py +0 -0
  124. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/agent/test_agent_creation.py +0 -0
  125. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/agent/test_json_tool_parsing.py +0 -0
  126. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/agent/test_process_node.py +0 -0
  127. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/agent/test_process_request.py +0 -0
  128. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/agent/test_tool_message_patching.py +0 -0
  129. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/background/test_background_edge_cases.py +0 -0
  130. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/background/test_cleanup.py +0 -0
  131. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/background/test_task_cancellation.py +0 -0
  132. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/background/test_task_creation.py +0 -0
  133. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/background/test_task_execution.py +0 -0
  134. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/code_index/test_cache_management.py +0 -0
  135. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/code_index/test_file_scanning.py +0 -0
  136. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/code_index/test_index_building.py +0 -0
  137. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/code_index/test_search_operations.py +0 -0
  138. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/code_index/test_symbol_extraction.py +0 -0
  139. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/commands/__init__.py +0 -0
  140. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/commands/test_init_command.py +0 -0
  141. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/conftest.py +0 -0
  142. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/context/__init__.py +0 -0
  143. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/context/test_context_acceptance.py +0 -0
  144. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/context/test_context_integration.py +0 -0
  145. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/context/test_context_loading.py +0 -0
  146. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/repl/test_command_parsing.py +0 -0
  147. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/repl/test_error_handling.py +0 -0
  148. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/repl/test_input_handling.py +0 -0
  149. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/repl/test_keyboard_interrupts.py +0 -0
  150. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/repl/test_multiline_input.py +0 -0
  151. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/repl/test_output_display_logic.py +0 -0
  152. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/repl/test_repl_initialization.py +0 -0
  153. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/repl/test_session_flow.py +0 -0
  154. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/services/test_error_recovery.py +0 -0
  155. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/services/test_llm_routing.py +0 -0
  156. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/services/test_mcp_integration.py +0 -0
  157. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/services/test_service_lifecycle.py +0 -0
  158. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/state/test_agent_tracking.py +0 -0
  159. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/state/test_message_history.py +0 -0
  160. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/state/test_permissions.py +0 -0
  161. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/state/test_session_management.py +0 -0
  162. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/state/test_state_initialization.py +0 -0
  163. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/state/test_user_config.py +0 -0
  164. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/test_characterization_commands.py +0 -0
  165. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/ui/test_console_output.py +0 -0
  166. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/ui/test_diff_display.py +0 -0
  167. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/ui/test_prompt_rendering.py +0 -0
  168. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/ui/test_tool_confirmations.py +0 -0
  169. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/utils/conftest.py +0 -0
  170. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/utils/test_expand_file_refs.py +0 -0
  171. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/utils/test_file_operations.py +0 -0
  172. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/utils/test_git_commands.py +0 -0
  173. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/utils/test_token_counting.py +0 -0
  174. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/characterization/utils/test_utils_edge_cases.py +0 -0
  175. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/conftest.py +0 -0
  176. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/test_agent_output_formatting.py +0 -0
  177. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/test_json_retry.py +0 -0
  178. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/test_prompt_changes_validation.py +0 -0
  179. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/test_security.py +0 -0
  180. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/test_tool_batching_retry.py +0 -0
  181. {tunacode_cli-0.0.49 → tunacode_cli-0.0.50}/tests/unit/test_recursive_executor.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tunacode-cli
3
- Version: 0.0.49
3
+ Version: 0.0.50
4
4
  Summary: Your agentic CLI developer.
5
5
  Author-email: larock22 <noreply@github.com>
6
6
  License: MIT
@@ -5,7 +5,7 @@ build-backend = "setuptools.build_meta"
5
5
  [project]
6
6
  name = "tunacode-cli"
7
7
 
8
- version = "0.0.49"
8
+ version = "0.0.50"
9
9
  description = "Your agentic CLI developer."
10
10
  keywords = ["cli", "agent", "development", "automation"]
11
11
  readme = "README.md"
@@ -7,7 +7,7 @@ Centralizes all magic strings, UI text, error messages, and application constant
7
7
 
8
8
  # Application info
9
9
  APP_NAME = "TunaCode"
10
- APP_VERSION = "0.0.49"
10
+ APP_VERSION = "0.0.50"
11
11
 
12
12
 
13
13
  # File patterns
@@ -0,0 +1,57 @@
1
+ import logging
2
+ import logging.config
3
+ import os
4
+
5
+ import yaml
6
+
7
+ from tunacode.utils import user_configuration
8
+
9
+ DEFAULT_CONFIG_PATH = os.path.join(
10
+ os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "config", "logging.yaml"
11
+ )
12
+
13
+
14
+ class LogConfig:
15
+ @staticmethod
16
+ def load(config_path=None):
17
+ """
18
+ Load logging configuration based on user preferences.
19
+ If logging is disabled (default), use minimal configuration.
20
+ """
21
+ # First check if user has enabled logging
22
+ user_config = user_configuration.load_config()
23
+ logging_enabled = False
24
+ custom_logging_config = None
25
+
26
+ if user_config:
27
+ logging_enabled = user_config.get("logging_enabled", False)
28
+ custom_logging_config = user_config.get("logging", None)
29
+
30
+ if not logging_enabled:
31
+ # Configure minimal logging - only critical errors to console
32
+ logging.basicConfig(level=logging.CRITICAL, handlers=[logging.NullHandler()])
33
+ # Ensure no file handlers are created
34
+ logging.getLogger().handlers = [logging.NullHandler()]
35
+ return
36
+
37
+ # Logging is enabled, load configuration
38
+ if custom_logging_config:
39
+ # Use user's custom logging configuration
40
+ try:
41
+ logging.config.dictConfig(custom_logging_config)
42
+ except Exception as e:
43
+ print(f"Failed to configure custom logging: {e}")
44
+ logging.basicConfig(level=logging.INFO)
45
+ else:
46
+ # Use default configuration from YAML file
47
+ path = config_path or DEFAULT_CONFIG_PATH
48
+ if not os.path.exists(path):
49
+ raise FileNotFoundError(f"Logging config file not found: {path}")
50
+ with open(path, "r") as f:
51
+ config = yaml.safe_load(f)
52
+ logging_config = config.get("logging", config)
53
+ try:
54
+ logging.config.dictConfig(logging_config)
55
+ except Exception as e:
56
+ print(f"Failed to configure logging: {e}")
57
+ logging.basicConfig(level=logging.INFO)
@@ -49,6 +49,10 @@ SessionId = str
49
49
  DeviceId = str
50
50
  InputSessions = Dict[str, Any]
51
51
 
52
+ # Logging configuration types
53
+ LoggingConfig = Dict[str, Any]
54
+ LoggingEnabled = bool
55
+
52
56
  # =============================================================================
53
57
  # Configuration Types
54
58
  # =============================================================================
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: tunacode-cli
3
- Version: 0.0.49
3
+ Version: 0.0.50
4
4
  Summary: Your agentic CLI developer.
5
5
  Author-email: larock22 <noreply@github.com>
6
6
  License: MIT
@@ -115,6 +115,7 @@ src/tunacode_cli.egg-info/top_level.txt
115
115
  tests/conftest.py
116
116
  tests/test_agent_output_formatting.py
117
117
  tests/test_json_retry.py
118
+ tests/test_logging_config.py
118
119
  tests/test_prompt_changes_validation.py
119
120
  tests/test_security.py
120
121
  tests/test_tool_batching_retry.py
@@ -0,0 +1,84 @@
1
+ """Test TUNACODE.md logging when thoughts are enabled."""
2
+
3
+ import os
4
+ import tempfile
5
+ from pathlib import Path
6
+ from unittest.mock import patch
7
+
8
+ import pytest
9
+
10
+
11
+ @pytest.mark.asyncio
12
+ async def test_tunacode_loading_message_displayed():
13
+ """Test that TUNACODE.md loading message is logged when found."""
14
+ # Create a temporary directory with TUNACODE.md
15
+ with tempfile.TemporaryDirectory() as tmpdir:
16
+ tunacode_path = Path(tmpdir) / "TUNACODE.md"
17
+ tunacode_content = """# TUNACODE.md
18
+
19
+ This file provides guidance to AI assistants.
20
+
21
+ ## Build Commands
22
+ - Run tests: `make test`
23
+ - Run single test: `pytest tests/test_file.py::test_name`
24
+ - Lint: `make lint`
25
+
26
+ ## Code Style
27
+ - Use type hints for all functions
28
+ - Follow PEP 8 conventions
29
+ - Prefer guard clauses over nested conditionals
30
+ """
31
+ tunacode_path.write_text(tunacode_content)
32
+
33
+ # Change to temp directory
34
+ original_cwd = os.getcwd()
35
+ try:
36
+ os.chdir(tmpdir)
37
+
38
+ # Mock the logger to capture calls
39
+ with patch("tunacode.core.agents.main.logger") as mock_logger:
40
+ from tunacode.core.agents.main import get_or_create_agent
41
+ from tunacode.core.state import StateManager
42
+
43
+ # Create state manager with thoughts enabled
44
+ state_manager = StateManager()
45
+ state_manager.session.show_thoughts = True
46
+
47
+ # Create agent (this should log the message)
48
+ get_or_create_agent("openai:gpt-4", state_manager)
49
+
50
+ # Check that the logger was called with the expected message
51
+ mock_logger.info.assert_called_with("📄 TUNACODE.md located: Loading context...")
52
+
53
+ finally:
54
+ os.chdir(original_cwd)
55
+
56
+
57
+ @pytest.mark.asyncio
58
+ async def test_tunacode_not_found_message():
59
+ """Test that TUNACODE.md not found message is logged when file doesn't exist."""
60
+ # Create a temporary directory WITHOUT TUNACODE.md
61
+ with tempfile.TemporaryDirectory() as tmpdir:
62
+ # Change to temp directory
63
+ original_cwd = os.getcwd()
64
+ try:
65
+ os.chdir(tmpdir)
66
+
67
+ # Mock the logger to capture calls
68
+ with patch("tunacode.core.agents.main.logger") as mock_logger:
69
+ from tunacode.core.agents.main import get_or_create_agent
70
+ from tunacode.core.state import StateManager
71
+
72
+ # Create state manager
73
+ state_manager = StateManager()
74
+
75
+ # Create agent (should log not found message)
76
+ get_or_create_agent("openai:gpt-4", state_manager)
77
+
78
+ # Check that the logger was called with the expected message
79
+ mock_logger.info.assert_called_with(
80
+ "📄 TUNACODE.md not found: Using default context"
81
+ )
82
+
83
+ finally:
84
+ os.chdir(original_cwd)
@@ -3,7 +3,7 @@ Characterization tests for TunaCode UI async UI updates.
3
3
  Covers: async output functions and async-safe UI flows.
4
4
  """
5
5
 
6
- from unittest.mock import patch
6
+ from unittest.mock import AsyncMock, patch
7
7
 
8
8
  import pytest
9
9
 
@@ -24,7 +24,9 @@ async def test_async_print_calls_console_print():
24
24
 
25
25
 
26
26
  @pytest.mark.asyncio
27
- async def test_async_info_formats_and_prints(caplog):
28
- # info() now goes through ui_logger, let's test that
29
- await output_mod.info("Test info")
30
- assert "Test info" in caplog.text
27
+ async def test_async_info_formats_and_prints():
28
+ # info() now goes through ui_logger, let's test that it's called
29
+ with patch("tunacode.ui.output.ui_logger") as mock_logger:
30
+ mock_logger.info = AsyncMock()
31
+ await output_mod.info("Test info")
32
+ mock_logger.info.assert_called_once_with("Test info")
@@ -0,0 +1,112 @@
1
+ """Test logging configuration with user preferences."""
2
+
3
+ import logging
4
+ from unittest.mock import patch
5
+
6
+ import pytest
7
+
8
+ from tunacode.core.logging.config import LogConfig
9
+
10
+
11
+ class TestLoggingConfiguration:
12
+ """Test cases for logging configuration based on user preferences."""
13
+
14
+ def test_logging_disabled_by_default(self, tmp_path):
15
+ """Test that logging is disabled when no config exists."""
16
+ with patch("tunacode.utils.user_configuration.load_config", return_value=None):
17
+ LogConfig.load()
18
+
19
+ # Check that root logger has only NullHandler
20
+ root_logger = logging.getLogger()
21
+ assert len(root_logger.handlers) == 1
22
+ assert isinstance(root_logger.handlers[0], logging.NullHandler)
23
+
24
+ def test_logging_explicitly_disabled(self, tmp_path):
25
+ """Test that logging stays disabled when explicitly set to false."""
26
+ config = {"default_model": "test:model", "logging_enabled": False}
27
+
28
+ with patch("tunacode.utils.user_configuration.load_config", return_value=config):
29
+ LogConfig.load()
30
+
31
+ # Check that root logger has only NullHandler
32
+ root_logger = logging.getLogger()
33
+ assert len(root_logger.handlers) == 1
34
+ assert isinstance(root_logger.handlers[0], logging.NullHandler)
35
+
36
+ def test_logging_enabled_with_defaults(self, tmp_path):
37
+ """Test that default logging config is used when enabled without custom config."""
38
+ config = {"default_model": "test:model", "logging_enabled": True}
39
+
40
+ with patch("tunacode.utils.user_configuration.load_config", return_value=config):
41
+ # This will load from the default YAML file
42
+ try:
43
+ LogConfig.load()
44
+ # If YAML exists, it should configure handlers
45
+ root_logger = logging.getLogger()
46
+ # Should have more than just NullHandler
47
+ assert not all(isinstance(h, logging.NullHandler) for h in root_logger.handlers)
48
+ except FileNotFoundError:
49
+ # If YAML doesn't exist in test environment, that's expected
50
+ pass
51
+
52
+ def test_logging_enabled_with_custom_config(self, tmp_path):
53
+ """Test that custom logging configuration is applied correctly."""
54
+ # Create a test log file path
55
+ log_file = tmp_path / "test.log"
56
+
57
+ config = {
58
+ "default_model": "test:model",
59
+ "logging_enabled": True,
60
+ "logging": {
61
+ "version": 1,
62
+ "disable_existing_loggers": False,
63
+ "formatters": {"simple": {"format": "[TEST] %(message)s"}},
64
+ "handlers": {
65
+ "test_file": {
66
+ "class": "logging.FileHandler",
67
+ "level": "DEBUG",
68
+ "formatter": "simple",
69
+ "filename": str(log_file),
70
+ }
71
+ },
72
+ "root": {"level": "DEBUG", "handlers": ["test_file"]},
73
+ },
74
+ }
75
+
76
+ with patch("tunacode.utils.user_configuration.load_config", return_value=config):
77
+ # Clear existing handlers first
78
+ logging.getLogger().handlers = []
79
+
80
+ LogConfig.load()
81
+
82
+ # Test that logging works with custom config
83
+ test_logger = logging.getLogger("test")
84
+ test_logger.debug("Test message")
85
+
86
+ # Check that log file was created and contains our message
87
+ assert log_file.exists()
88
+ content = log_file.read_text()
89
+ assert "[TEST] Test message" in content
90
+
91
+ def test_invalid_custom_config_fallback(self, tmp_path):
92
+ """Test that invalid custom config falls back to basic config."""
93
+ config = {
94
+ "default_model": "test:model",
95
+ "logging_enabled": True,
96
+ "logging": {"invalid": "config"},
97
+ }
98
+
99
+ # Clear any existing handlers
100
+ logging.getLogger().handlers = []
101
+
102
+ with patch("tunacode.utils.user_configuration.load_config", return_value=config):
103
+ # Should not raise exception
104
+ LogConfig.load()
105
+
106
+ # Should have some configuration (not NullHandler)
107
+ root_logger = logging.getLogger()
108
+ assert len(root_logger.handlers) > 0
109
+
110
+
111
+ if __name__ == "__main__":
112
+ pytest.main([__file__, "-v"])
@@ -1,28 +0,0 @@
1
- import logging
2
- import logging.config
3
- import os
4
-
5
- import yaml
6
-
7
- DEFAULT_CONFIG_PATH = os.path.join(
8
- os.path.dirname(os.path.dirname(os.path.dirname(__file__))), "config", "logging.yaml"
9
- )
10
-
11
-
12
- class LogConfig:
13
- @staticmethod
14
- def load(config_path=None):
15
- """
16
- Load logging configuration from YAML file and apply it.
17
- """
18
- path = config_path or DEFAULT_CONFIG_PATH
19
- if not os.path.exists(path):
20
- raise FileNotFoundError(f"Logging config file not found: {path}")
21
- with open(path, "r") as f:
22
- config = yaml.safe_load(f)
23
- logging_config = config.get("logging", config)
24
- try:
25
- logging.config.dictConfig(logging_config)
26
- except Exception as e:
27
- print(f"Failed to configure logging: {e}")
28
- logging.basicConfig(level=logging.INFO)
@@ -1,74 +0,0 @@
1
- """Test TUNACODE.md logging when thoughts are enabled."""
2
-
3
- import os
4
- import tempfile
5
- from pathlib import Path
6
-
7
- import pytest
8
-
9
- from tunacode.core.agents.main import get_or_create_agent
10
- from tunacode.core.state import StateManager
11
-
12
-
13
- @pytest.mark.asyncio
14
- async def test_tunacode_loading_message_displayed(caplog):
15
- """Test that TUNACODE.md loading message is displayed when found."""
16
- # Create a temporary directory with TUNACODE.md
17
- with tempfile.TemporaryDirectory() as tmpdir:
18
- tunacode_path = Path(tmpdir) / "TUNACODE.md"
19
- tunacode_content = """# TUNACODE.md
20
-
21
- This file provides guidance to AI assistants.
22
-
23
- ## Build Commands
24
- - Run tests: `make test`
25
- - Run single test: `pytest tests/test_file.py::test_name`
26
- - Lint: `make lint`
27
-
28
- ## Code Style
29
- - Use type hints for all functions
30
- - Follow PEP 8 conventions
31
- - Prefer guard clauses over nested conditionals
32
- """
33
- tunacode_path.write_text(tunacode_content)
34
-
35
- # Change to temp directory
36
- original_cwd = os.getcwd()
37
- try:
38
- os.chdir(tmpdir)
39
-
40
- # Create state manager with thoughts enabled
41
- state_manager = StateManager()
42
- state_manager.session.show_thoughts = True
43
-
44
- # Create agent (this should log the message)
45
- get_or_create_agent("openai:gpt-4", state_manager)
46
-
47
- # Check the log messages
48
- assert "📄 TUNACODE.md located: Loading context..." in caplog.text
49
-
50
- finally:
51
- os.chdir(original_cwd)
52
-
53
-
54
- @pytest.mark.asyncio
55
- async def test_tunacode_not_found_message(caplog):
56
- """Test that TUNACODE.md not found message is displayed when file doesn't exist."""
57
- # Create a temporary directory WITHOUT TUNACODE.md
58
- with tempfile.TemporaryDirectory() as tmpdir:
59
- # Change to temp directory
60
- original_cwd = os.getcwd()
61
- try:
62
- os.chdir(tmpdir)
63
-
64
- # Create state manager
65
- state_manager = StateManager()
66
-
67
- # Create agent (should log not found message)
68
- get_or_create_agent("openai:gpt-4", state_manager)
69
-
70
- # Check the log messages
71
- assert "📄 TUNACODE.md not found: Using default context" in caplog.text
72
-
73
- finally:
74
- os.chdir(original_cwd)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes