shotgun-sh 0.2.9.dev1__tar.gz → 0.2.10.dev1__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 shotgun-sh might be problematic. Click here for more details.

Files changed (157) hide show
  1. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/PKG-INFO +2 -1
  2. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/README.md +84 -0
  3. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/pyproject.toml +2 -1
  4. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/main.py +64 -10
  5. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/app.py +142 -5
  6. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/screens/chat.py +20 -1
  7. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/.gitignore +0 -0
  8. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/LICENSE +0 -0
  9. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/README_PYPI.md +0 -0
  10. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/hatch_build.py +0 -0
  11. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/__init__.py +0 -0
  12. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/__init__.py +0 -0
  13. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/agent_manager.py +0 -0
  14. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/common.py +0 -0
  15. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/config/__init__.py +0 -0
  16. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/config/constants.py +0 -0
  17. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/config/manager.py +0 -0
  18. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/config/models.py +0 -0
  19. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/config/provider.py +0 -0
  20. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/conversation_history.py +0 -0
  21. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/conversation_manager.py +0 -0
  22. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/export.py +0 -0
  23. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/__init__.py +0 -0
  24. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/compaction.py +0 -0
  25. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/constants.py +0 -0
  26. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/context_extraction.py +0 -0
  27. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/history_building.py +0 -0
  28. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/history_processors.py +0 -0
  29. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/message_utils.py +0 -0
  30. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/token_counting/__init__.py +0 -0
  31. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/token_counting/anthropic.py +0 -0
  32. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/token_counting/base.py +0 -0
  33. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/token_counting/openai.py +0 -0
  34. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/token_counting/sentencepiece_counter.py +0 -0
  35. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/token_counting/tokenizer_cache.py +0 -0
  36. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/token_counting/utils.py +0 -0
  37. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/history/token_estimation.py +0 -0
  38. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/llm.py +0 -0
  39. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/messages.py +0 -0
  40. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/models.py +0 -0
  41. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/plan.py +0 -0
  42. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/research.py +0 -0
  43. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/specify.py +0 -0
  44. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tasks.py +0 -0
  45. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tools/__init__.py +0 -0
  46. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tools/codebase/__init__.py +0 -0
  47. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tools/codebase/codebase_shell.py +0 -0
  48. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tools/codebase/directory_lister.py +0 -0
  49. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tools/codebase/file_read.py +0 -0
  50. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tools/codebase/models.py +0 -0
  51. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tools/codebase/query_graph.py +0 -0
  52. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tools/codebase/retrieve_code.py +0 -0
  53. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tools/file_management.py +0 -0
  54. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tools/web_search/__init__.py +0 -0
  55. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tools/web_search/anthropic.py +0 -0
  56. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tools/web_search/gemini.py +0 -0
  57. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tools/web_search/openai.py +0 -0
  58. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/tools/web_search/utils.py +0 -0
  59. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/agents/usage_manager.py +0 -0
  60. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/api_endpoints.py +0 -0
  61. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/build_constants.py +0 -0
  62. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/cli/__init__.py +0 -0
  63. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/cli/codebase/__init__.py +0 -0
  64. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/cli/codebase/commands.py +0 -0
  65. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/cli/codebase/models.py +0 -0
  66. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/cli/config.py +0 -0
  67. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/cli/export.py +0 -0
  68. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/cli/feedback.py +0 -0
  69. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/cli/models.py +0 -0
  70. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/cli/plan.py +0 -0
  71. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/cli/research.py +0 -0
  72. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/cli/specify.py +0 -0
  73. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/cli/tasks.py +0 -0
  74. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/cli/update.py +0 -0
  75. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/cli/utils.py +0 -0
  76. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/codebase/__init__.py +0 -0
  77. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/codebase/core/__init__.py +0 -0
  78. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/codebase/core/change_detector.py +0 -0
  79. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/codebase/core/code_retrieval.py +0 -0
  80. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/codebase/core/cypher_models.py +0 -0
  81. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/codebase/core/ingestor.py +0 -0
  82. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/codebase/core/language_config.py +0 -0
  83. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/codebase/core/manager.py +0 -0
  84. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/codebase/core/nl_query.py +0 -0
  85. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/codebase/core/parser_loader.py +0 -0
  86. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/codebase/models.py +0 -0
  87. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/codebase/service.py +0 -0
  88. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/llm_proxy/__init__.py +0 -0
  89. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/llm_proxy/clients.py +0 -0
  90. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/llm_proxy/constants.py +0 -0
  91. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/logging_config.py +0 -0
  92. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/posthog_telemetry.py +0 -0
  93. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/__init__.py +0 -0
  94. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/agents/__init__.py +0 -0
  95. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/agents/export.j2 +0 -0
  96. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/agents/partials/codebase_understanding.j2 +0 -0
  97. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/agents/partials/common_agent_system_prompt.j2 +0 -0
  98. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/agents/partials/content_formatting.j2 +0 -0
  99. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/agents/partials/interactive_mode.j2 +0 -0
  100. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/agents/plan.j2 +0 -0
  101. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/agents/research.j2 +0 -0
  102. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/agents/specify.j2 +0 -0
  103. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/agents/state/codebase/codebase_graphs_available.j2 +0 -0
  104. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/agents/state/system_state.j2 +0 -0
  105. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/agents/tasks.j2 +0 -0
  106. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/codebase/__init__.py +0 -0
  107. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/codebase/cypher_query_patterns.j2 +0 -0
  108. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/codebase/cypher_system.j2 +0 -0
  109. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/codebase/enhanced_query_context.j2 +0 -0
  110. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/codebase/partials/cypher_rules.j2 +0 -0
  111. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/codebase/partials/graph_schema.j2 +0 -0
  112. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/codebase/partials/temporal_context.j2 +0 -0
  113. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/history/__init__.py +0 -0
  114. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/history/incremental_summarization.j2 +0 -0
  115. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/history/summarization.j2 +0 -0
  116. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/loader.py +0 -0
  117. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/prompts/tools/web_search.j2 +0 -0
  118. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/py.typed +0 -0
  119. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/sdk/__init__.py +0 -0
  120. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/sdk/codebase.py +0 -0
  121. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/sdk/exceptions.py +0 -0
  122. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/sdk/models.py +0 -0
  123. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/sdk/services.py +0 -0
  124. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/sentry_telemetry.py +0 -0
  125. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/shotgun_web/__init__.py +0 -0
  126. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/shotgun_web/client.py +0 -0
  127. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/shotgun_web/constants.py +0 -0
  128. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/shotgun_web/models.py +0 -0
  129. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/telemetry.py +0 -0
  130. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/__init__.py +0 -0
  131. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/commands/__init__.py +0 -0
  132. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/components/prompt_input.py +0 -0
  133. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/components/spinner.py +0 -0
  134. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/components/splash.py +0 -0
  135. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/components/vertical_tail.py +0 -0
  136. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/filtered_codebase_service.py +0 -0
  137. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/screens/chat.tcss +0 -0
  138. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/screens/chat_screen/__init__.py +0 -0
  139. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/screens/chat_screen/command_providers.py +0 -0
  140. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/screens/chat_screen/hint_message.py +0 -0
  141. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/screens/chat_screen/history.py +0 -0
  142. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/screens/directory_setup.py +0 -0
  143. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/screens/feedback.py +0 -0
  144. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/screens/model_picker.py +0 -0
  145. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/screens/provider_config.py +0 -0
  146. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/screens/shotgun_auth.py +0 -0
  147. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/screens/splash.py +0 -0
  148. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/screens/welcome.py +0 -0
  149. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/styles.tcss +0 -0
  150. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/utils/__init__.py +0 -0
  151. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/tui/utils/mode_progress.py +0 -0
  152. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/utils/__init__.py +0 -0
  153. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/utils/datetime_utils.py +0 -0
  154. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/utils/env_utils.py +0 -0
  155. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/utils/file_system_utils.py +0 -0
  156. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/utils/source_detection.py +0 -0
  157. {shotgun_sh-0.2.9.dev1 → shotgun_sh-0.2.10.dev1}/src/shotgun/utils/update_checker.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: shotgun-sh
3
- Version: 0.2.9.dev1
3
+ Version: 0.2.10.dev1
4
4
  Summary: AI-powered research, planning, and task management CLI tool
5
5
  Project-URL: Homepage, https://shotgun.sh/
6
6
  Project-URL: Repository, https://github.com/shotgun-sh/shotgun
@@ -36,6 +36,7 @@ Requires-Dist: sentencepiece>=0.2.0
36
36
  Requires-Dist: sentry-sdk[pure-eval]>=2.0.0
37
37
  Requires-Dist: tenacity>=8.0.0
38
38
  Requires-Dist: textual-dev>=1.7.0
39
+ Requires-Dist: textual-serve>=0.1.0
39
40
  Requires-Dist: textual>=6.1.0
40
41
  Requires-Dist: tiktoken>=0.7.0
41
42
  Requires-Dist: tree-sitter-go>=0.23.0
@@ -408,6 +408,90 @@ export SENTRY_DSN=your-sentry-dsn
408
408
  - **Opt-in for development**: Telemetry requires explicit environment variables
409
409
  - **Automatic in production**: Production builds include telemetry for error tracking
410
410
 
411
+ ## Docker
412
+
413
+ Run Shotgun in a Docker container with web access.
414
+
415
+ ### Using Pre-built Images (Recommended)
416
+
417
+ Pull the official image from GitHub Container Registry:
418
+
419
+ ```bash
420
+ # Pull latest stable version
421
+ docker pull ghcr.io/shotgun-sh/shotgun:latest
422
+
423
+ # Or pull a specific version
424
+ docker pull ghcr.io/shotgun-sh/shotgun:v0.1.0
425
+
426
+ # Or pull development version
427
+ docker pull ghcr.io/shotgun-sh/shotgun:dev
428
+ ```
429
+
430
+ Then run:
431
+
432
+ ```bash
433
+ docker run -p 8000:8000 \
434
+ -v $(pwd):/workspace \
435
+ -v ~/.shotgun-sh:/home/shotgun/.shotgun-sh \
436
+ ghcr.io/shotgun-sh/shotgun:latest --no-update-check
437
+ ```
438
+
439
+ **Note:** The Docker image automatically includes `--force-reindex` to ensure fresh indexing on startup. You don't need to add any additional flags.
440
+
441
+ ### Building from Source (Optional)
442
+
443
+ If you prefer to build the image yourself:
444
+
445
+ ```bash
446
+ docker build -t shotgun:latest .
447
+ ```
448
+
449
+ ### Run the Container
450
+
451
+ The container requires two volume mounts:
452
+ 1. Your codebase/workspace directory (mounted to `/workspace`)
453
+ 2. Config directory for API keys and settings (mounted to `/home/shotgun/.shotgun-sh`)
454
+
455
+ ```bash
456
+ # Basic usage (serves on port 8000)
457
+ docker run -p 8000:8000 \
458
+ -v $(pwd):/workspace \
459
+ -v ~/.shotgun-sh:/home/shotgun/.shotgun-sh \
460
+ ghcr.io/shotgun-sh/shotgun:latest --no-update-check
461
+
462
+ # Custom port
463
+ docker run -p 3000:3000 \
464
+ -v $(pwd):/workspace \
465
+ -v ~/.shotgun-sh:/home/shotgun/.shotgun-sh \
466
+ ghcr.io/shotgun-sh/shotgun:latest --no-update-check --port 3000
467
+
468
+ # Different codebase directory
469
+ docker run -p 8000:8000 \
470
+ -v /path/to/your/project:/workspace \
471
+ -v ~/.shotgun-sh:/home/shotgun/.shotgun-sh \
472
+ ghcr.io/shotgun-sh/shotgun:latest --no-update-check
473
+
474
+ # Run in background with auto-restart
475
+ docker run -d --restart unless-stopped \
476
+ --name shotgun-web \
477
+ -p 8000:8000 \
478
+ -v $(pwd):/workspace \
479
+ -v ~/.shotgun-sh:/home/shotgun/.shotgun-sh \
480
+ ghcr.io/shotgun-sh/shotgun:latest --no-update-check
481
+ ```
482
+
483
+ **All Docker commands automatically include `--force-reindex`** - you don't need to specify it. The flag is baked into the Docker image's ENTRYPOINT to ensure reliable codebase indexing in containerized environments.
484
+
485
+ ### Configuration
486
+
487
+ On first run, configure your API keys through the web UI. The configuration will persist in the mounted `~/.shotgun-sh` directory.
488
+
489
+ Access the web interface at `http://localhost:8000` (or your custom port).
490
+
491
+ ### Codebase Indexing in Docker
492
+
493
+ The Docker image automatically prompts you to index the codebase on each startup. This ensures you're always working with up-to-date code analysis, even if the container restarts or you mount a different directory. Simply click "Index now" when prompted.
494
+
411
495
  ## Support
412
496
 
413
497
  Join our discord https://discord.gg/5RmY6J2N7s
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "shotgun-sh"
3
- version = "0.2.9.dev1"
3
+ version = "0.2.10.dev1"
4
4
  description = "AI-powered research, planning, and task management CLI tool"
5
5
  readme = "README_PYPI.md"
6
6
  license = { text = "MIT" }
@@ -32,6 +32,7 @@ dependencies = [
32
32
  "posthog>=3.0.0",
33
33
  "textual>=6.1.0",
34
34
  "textual-dev>=1.7.0",
35
+ "textual-serve>=0.1.0",
35
36
  "kuzu>=0.7.0",
36
37
  "tree-sitter>=0.21.0",
37
38
  "tree-sitter-python>=0.23.0",
@@ -125,6 +125,41 @@ def main(
125
125
  help="Continue previous TUI conversation",
126
126
  ),
127
127
  ] = False,
128
+ web: Annotated[
129
+ bool,
130
+ typer.Option(
131
+ "--web",
132
+ help="Serve TUI as web application",
133
+ ),
134
+ ] = False,
135
+ port: Annotated[
136
+ int,
137
+ typer.Option(
138
+ "--port",
139
+ help="Port for web server (only used with --web)",
140
+ ),
141
+ ] = 8000,
142
+ host: Annotated[
143
+ str,
144
+ typer.Option(
145
+ "--host",
146
+ help="Host address for web server (only used with --web)",
147
+ ),
148
+ ] = "localhost",
149
+ public_url: Annotated[
150
+ str | None,
151
+ typer.Option(
152
+ "--public-url",
153
+ help="Public URL if behind proxy (only used with --web)",
154
+ ),
155
+ ] = None,
156
+ force_reindex: Annotated[
157
+ bool,
158
+ typer.Option(
159
+ "--force-reindex",
160
+ help="Force re-indexing of codebase (ignores existing index)",
161
+ ),
162
+ ] = False,
128
163
  ) -> None:
129
164
  """Shotgun - AI-powered CLI tool."""
130
165
  logger.debug("Starting shotgun CLI application")
@@ -134,16 +169,35 @@ def main(
134
169
  perform_auto_update_async(no_update_check=no_update_check)
135
170
 
136
171
  if ctx.invoked_subcommand is None and not ctx.resilient_parsing:
137
- logger.debug("Launching shotgun TUI application")
138
- try:
139
- tui_app.run(
140
- no_update_check=no_update_check, continue_session=continue_session
141
- )
142
- finally:
143
- # Ensure PostHog is shut down cleanly even if TUI exits unexpectedly
144
- from shotgun.posthog_telemetry import shutdown
145
-
146
- shutdown()
172
+ if web:
173
+ logger.debug("Launching shotgun TUI as web application")
174
+ try:
175
+ tui_app.serve(
176
+ host=host,
177
+ port=port,
178
+ public_url=public_url,
179
+ no_update_check=no_update_check,
180
+ continue_session=continue_session,
181
+ force_reindex=force_reindex,
182
+ )
183
+ finally:
184
+ # Ensure PostHog is shut down cleanly even if server exits unexpectedly
185
+ from shotgun.posthog_telemetry import shutdown
186
+
187
+ shutdown()
188
+ else:
189
+ logger.debug("Launching shotgun TUI application")
190
+ try:
191
+ tui_app.run(
192
+ no_update_check=no_update_check,
193
+ continue_session=continue_session,
194
+ force_reindex=force_reindex,
195
+ )
196
+ finally:
197
+ # Ensure PostHog is shut down cleanly even if TUI exits unexpectedly
198
+ from shotgun.posthog_telemetry import shutdown
199
+
200
+ shutdown()
147
201
  raise typer.Exit()
148
202
 
149
203
  # For CLI commands, register PostHog shutdown handler
@@ -36,12 +36,16 @@ class ShotgunApp(App[None]):
36
36
  CSS_PATH = "styles.tcss"
37
37
 
38
38
  def __init__(
39
- self, no_update_check: bool = False, continue_session: bool = False
39
+ self,
40
+ no_update_check: bool = False,
41
+ continue_session: bool = False,
42
+ force_reindex: bool = False,
40
43
  ) -> None:
41
44
  super().__init__()
42
45
  self.config_manager: ConfigManager = get_config_manager()
43
46
  self.no_update_check = no_update_check
44
47
  self.continue_session = continue_session
48
+ self.force_reindex = force_reindex
45
49
 
46
50
  # Start async update check and install
47
51
  if not no_update_check:
@@ -87,8 +91,12 @@ class ShotgunApp(App[None]):
87
91
 
88
92
  if isinstance(self.screen, ChatScreen):
89
93
  return
90
- # Pass continue_session flag to ChatScreen
91
- self.push_screen(ChatScreen(continue_session=self.continue_session))
94
+ # Pass continue_session and force_reindex flags to ChatScreen
95
+ self.push_screen(
96
+ ChatScreen(
97
+ continue_session=self.continue_session, force_reindex=self.force_reindex
98
+ )
99
+ )
92
100
 
93
101
  def check_local_shotgun_directory_exists(self) -> bool:
94
102
  shotgun_dir = get_shotgun_base_path()
@@ -121,12 +129,17 @@ class ShotgunApp(App[None]):
121
129
  self.push_screen(FeedbackScreen(), callback=handle_feedback)
122
130
 
123
131
 
124
- def run(no_update_check: bool = False, continue_session: bool = False) -> None:
132
+ def run(
133
+ no_update_check: bool = False,
134
+ continue_session: bool = False,
135
+ force_reindex: bool = False,
136
+ ) -> None:
125
137
  """Run the TUI application.
126
138
 
127
139
  Args:
128
140
  no_update_check: If True, disable automatic update checks.
129
141
  continue_session: If True, continue from previous conversation.
142
+ force_reindex: If True, force re-indexing of codebase (ignores existing index).
130
143
  """
131
144
  # Clean up any corrupted databases BEFORE starting the TUI
132
145
  # This prevents crashes from corrupted databases during initialization
@@ -148,9 +161,133 @@ def run(no_update_check: bool = False, continue_session: bool = False) -> None:
148
161
  logger.error(f"Failed to cleanup corrupted databases: {e}")
149
162
  # Continue anyway - the TUI can still function
150
163
 
151
- app = ShotgunApp(no_update_check=no_update_check, continue_session=continue_session)
164
+ app = ShotgunApp(
165
+ no_update_check=no_update_check,
166
+ continue_session=continue_session,
167
+ force_reindex=force_reindex,
168
+ )
152
169
  app.run(inline_no_clear=True)
153
170
 
154
171
 
172
+ def serve(
173
+ host: str = "localhost",
174
+ port: int = 8000,
175
+ public_url: str | None = None,
176
+ no_update_check: bool = False,
177
+ continue_session: bool = False,
178
+ force_reindex: bool = False,
179
+ ) -> None:
180
+ """Serve the TUI application as a web application.
181
+
182
+ Args:
183
+ host: Host address for the web server.
184
+ port: Port number for the web server.
185
+ public_url: Public URL if behind a proxy.
186
+ no_update_check: If True, disable automatic update checks.
187
+ continue_session: If True, continue from previous conversation.
188
+ force_reindex: If True, force re-indexing of codebase (ignores existing index).
189
+ """
190
+ # Clean up any corrupted databases BEFORE starting the TUI
191
+ # This prevents crashes from corrupted databases during initialization
192
+ import asyncio
193
+
194
+ from textual_serve.server import Server
195
+
196
+ from shotgun.codebase.core.manager import CodebaseGraphManager
197
+ from shotgun.utils import get_shotgun_home
198
+
199
+ storage_dir = get_shotgun_home() / "codebases"
200
+ manager = CodebaseGraphManager(storage_dir)
201
+
202
+ try:
203
+ removed = asyncio.run(manager.cleanup_corrupted_databases())
204
+ if removed:
205
+ logger.info(
206
+ f"Cleaned up {len(removed)} corrupted database(s) before TUI startup"
207
+ )
208
+ except Exception as e:
209
+ logger.error(f"Failed to cleanup corrupted databases: {e}")
210
+ # Continue anyway - the TUI can still function
211
+
212
+ # Create a new event loop after asyncio.run() closes the previous one
213
+ # This is needed for the Server.serve() method
214
+ loop = asyncio.new_event_loop()
215
+ asyncio.set_event_loop(loop)
216
+
217
+ # Build the command string based on flags
218
+ command = "shotgun"
219
+ if no_update_check:
220
+ command += " --no-update-check"
221
+ if continue_session:
222
+ command += " --continue"
223
+ if force_reindex:
224
+ command += " --force-reindex"
225
+
226
+ # Create and start the server with hardcoded title and debug=False
227
+ server = Server(
228
+ command=command,
229
+ host=host,
230
+ port=port,
231
+ title="The Shotgun",
232
+ public_url=public_url,
233
+ )
234
+
235
+ # Set up graceful shutdown on SIGTERM/SIGINT
236
+ import signal
237
+ import sys
238
+
239
+ def signal_handler(_signum: int, _frame: Any) -> None:
240
+ """Handle shutdown signals gracefully."""
241
+ from shotgun.posthog_telemetry import shutdown
242
+
243
+ logger.info("Received shutdown signal, cleaning up...")
244
+ # Restore stdout/stderr before shutting down
245
+ sys.stdout = original_stdout
246
+ sys.stderr = original_stderr
247
+ shutdown()
248
+ sys.exit(0)
249
+
250
+ signal.signal(signal.SIGTERM, signal_handler)
251
+ signal.signal(signal.SIGINT, signal_handler)
252
+
253
+ # Suppress the textual-serve banner by redirecting stdout/stderr
254
+ import io
255
+
256
+ # Capture and suppress the banner, but show the actual serving URL
257
+ original_stdout = sys.stdout
258
+ original_stderr = sys.stderr
259
+
260
+ captured_output = io.StringIO()
261
+ sys.stdout = captured_output
262
+ sys.stderr = captured_output
263
+
264
+ try:
265
+ # This will print the banner to our captured output
266
+ import logging
267
+
268
+ # Temporarily set logging to ERROR level to suppress INFO messages
269
+ textual_serve_logger = logging.getLogger("textual_serve")
270
+ original_level = textual_serve_logger.level
271
+ textual_serve_logger.setLevel(logging.ERROR)
272
+
273
+ # Print our own message to the original stdout
274
+ sys.stdout = original_stdout
275
+ sys.stderr = original_stderr
276
+ print(f"Serving Shotgun TUI at http://{host}:{port}")
277
+ print("Press Ctrl+C to quit")
278
+
279
+ # Now suppress output again for the serve call
280
+ sys.stdout = captured_output
281
+ sys.stderr = captured_output
282
+
283
+ server.serve(debug=False)
284
+ finally:
285
+ # Restore original stdout/stderr
286
+ sys.stdout = original_stdout
287
+ sys.stderr = original_stderr
288
+ if "textual_serve_logger" in locals():
289
+ textual_serve_logger.setLevel(original_level)
290
+
291
+
155
292
  if __name__ == "__main__":
156
293
  run()
@@ -291,7 +291,9 @@ class ChatScreen(Screen[None]):
291
291
  qa_current_index = reactive(0)
292
292
  qa_answers: list[str] = []
293
293
 
294
- def __init__(self, continue_session: bool = False) -> None:
294
+ def __init__(
295
+ self, continue_session: bool = False, force_reindex: bool = False
296
+ ) -> None:
295
297
  super().__init__()
296
298
  # Get the model configuration and services
297
299
  model_config = get_provider_model()
@@ -319,6 +321,7 @@ class ChatScreen(Screen[None]):
319
321
  self.placeholder_hints = PlaceholderHints()
320
322
  self.conversation_manager = ConversationManager()
321
323
  self.continue_session = continue_session
324
+ self.force_reindex = force_reindex
322
325
 
323
326
  def on_mount(self) -> None:
324
327
  self.query_one(PromptInput).focus(scroll_visible=True)
@@ -378,6 +381,22 @@ class ChatScreen(Screen[None]):
378
381
  if is_empty or self.continue_session:
379
382
  return
380
383
 
384
+ # If force_reindex is True, delete any existing graphs for this directory
385
+ if self.force_reindex:
386
+ accessible_graphs = (
387
+ await self.codebase_sdk.list_codebases_for_directory()
388
+ ).graphs
389
+ for graph in accessible_graphs:
390
+ try:
391
+ await self.codebase_sdk.delete_codebase(graph.graph_id)
392
+ logger.info(
393
+ f"Deleted existing graph {graph.graph_id} due to --force-reindex"
394
+ )
395
+ except Exception as e:
396
+ logger.warning(
397
+ f"Failed to delete graph {graph.graph_id} during force reindex: {e}"
398
+ )
399
+
381
400
  # Check if the current directory has any accessible codebases
382
401
  accessible_graphs = (
383
402
  await self.codebase_sdk.list_codebases_for_directory()