shotgun-sh 0.2.8.dev2__py3-none-any.whl → 0.2.17__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.
Files changed (117) hide show
  1. shotgun/agents/agent_manager.py +354 -46
  2. shotgun/agents/common.py +14 -8
  3. shotgun/agents/config/constants.py +0 -6
  4. shotgun/agents/config/manager.py +66 -35
  5. shotgun/agents/config/models.py +41 -1
  6. shotgun/agents/config/provider.py +33 -5
  7. shotgun/agents/context_analyzer/__init__.py +28 -0
  8. shotgun/agents/context_analyzer/analyzer.py +471 -0
  9. shotgun/agents/context_analyzer/constants.py +9 -0
  10. shotgun/agents/context_analyzer/formatter.py +115 -0
  11. shotgun/agents/context_analyzer/models.py +212 -0
  12. shotgun/agents/conversation_history.py +2 -0
  13. shotgun/agents/conversation_manager.py +35 -19
  14. shotgun/agents/export.py +2 -2
  15. shotgun/agents/history/compaction.py +9 -4
  16. shotgun/agents/history/history_processors.py +113 -5
  17. shotgun/agents/history/token_counting/anthropic.py +17 -1
  18. shotgun/agents/history/token_counting/base.py +14 -3
  19. shotgun/agents/history/token_counting/openai.py +11 -1
  20. shotgun/agents/history/token_counting/sentencepiece_counter.py +8 -0
  21. shotgun/agents/history/token_counting/tokenizer_cache.py +3 -1
  22. shotgun/agents/history/token_counting/utils.py +0 -3
  23. shotgun/agents/plan.py +2 -2
  24. shotgun/agents/research.py +3 -3
  25. shotgun/agents/specify.py +2 -2
  26. shotgun/agents/tasks.py +2 -2
  27. shotgun/agents/tools/codebase/codebase_shell.py +6 -0
  28. shotgun/agents/tools/codebase/directory_lister.py +6 -0
  29. shotgun/agents/tools/codebase/file_read.py +11 -2
  30. shotgun/agents/tools/codebase/query_graph.py +6 -0
  31. shotgun/agents/tools/codebase/retrieve_code.py +6 -0
  32. shotgun/agents/tools/file_management.py +27 -7
  33. shotgun/agents/tools/registry.py +217 -0
  34. shotgun/agents/tools/web_search/__init__.py +8 -8
  35. shotgun/agents/tools/web_search/anthropic.py +8 -2
  36. shotgun/agents/tools/web_search/gemini.py +7 -1
  37. shotgun/agents/tools/web_search/openai.py +7 -1
  38. shotgun/agents/tools/web_search/utils.py +2 -2
  39. shotgun/agents/usage_manager.py +16 -11
  40. shotgun/api_endpoints.py +7 -3
  41. shotgun/build_constants.py +3 -3
  42. shotgun/cli/clear.py +53 -0
  43. shotgun/cli/compact.py +186 -0
  44. shotgun/cli/config.py +8 -5
  45. shotgun/cli/context.py +111 -0
  46. shotgun/cli/export.py +1 -1
  47. shotgun/cli/feedback.py +4 -2
  48. shotgun/cli/models.py +1 -0
  49. shotgun/cli/plan.py +1 -1
  50. shotgun/cli/research.py +1 -1
  51. shotgun/cli/specify.py +1 -1
  52. shotgun/cli/tasks.py +1 -1
  53. shotgun/cli/update.py +16 -2
  54. shotgun/codebase/core/change_detector.py +5 -3
  55. shotgun/codebase/core/code_retrieval.py +4 -2
  56. shotgun/codebase/core/ingestor.py +10 -8
  57. shotgun/codebase/core/manager.py +13 -4
  58. shotgun/codebase/core/nl_query.py +1 -1
  59. shotgun/exceptions.py +32 -0
  60. shotgun/logging_config.py +18 -27
  61. shotgun/main.py +73 -11
  62. shotgun/posthog_telemetry.py +37 -28
  63. shotgun/prompts/agents/partials/common_agent_system_prompt.j2 +3 -2
  64. shotgun/sentry_telemetry.py +163 -16
  65. shotgun/settings.py +238 -0
  66. shotgun/telemetry.py +10 -33
  67. shotgun/tui/app.py +243 -43
  68. shotgun/tui/commands/__init__.py +1 -1
  69. shotgun/tui/components/context_indicator.py +179 -0
  70. shotgun/tui/components/mode_indicator.py +70 -0
  71. shotgun/tui/components/status_bar.py +48 -0
  72. shotgun/tui/containers.py +91 -0
  73. shotgun/tui/dependencies.py +39 -0
  74. shotgun/tui/protocols.py +45 -0
  75. shotgun/tui/screens/chat/__init__.py +5 -0
  76. shotgun/tui/screens/chat/chat.tcss +54 -0
  77. shotgun/tui/screens/chat/chat_screen.py +1254 -0
  78. shotgun/tui/screens/chat/codebase_index_prompt_screen.py +64 -0
  79. shotgun/tui/screens/chat/codebase_index_selection.py +12 -0
  80. shotgun/tui/screens/chat/help_text.py +40 -0
  81. shotgun/tui/screens/chat/prompt_history.py +48 -0
  82. shotgun/tui/screens/chat.tcss +11 -0
  83. shotgun/tui/screens/chat_screen/command_providers.py +78 -2
  84. shotgun/tui/screens/chat_screen/history/__init__.py +22 -0
  85. shotgun/tui/screens/chat_screen/history/agent_response.py +66 -0
  86. shotgun/tui/screens/chat_screen/history/chat_history.py +115 -0
  87. shotgun/tui/screens/chat_screen/history/formatters.py +115 -0
  88. shotgun/tui/screens/chat_screen/history/partial_response.py +43 -0
  89. shotgun/tui/screens/chat_screen/history/user_question.py +42 -0
  90. shotgun/tui/screens/confirmation_dialog.py +151 -0
  91. shotgun/tui/screens/feedback.py +4 -4
  92. shotgun/tui/screens/github_issue.py +102 -0
  93. shotgun/tui/screens/model_picker.py +49 -24
  94. shotgun/tui/screens/onboarding.py +431 -0
  95. shotgun/tui/screens/pipx_migration.py +153 -0
  96. shotgun/tui/screens/provider_config.py +50 -27
  97. shotgun/tui/screens/shotgun_auth.py +2 -2
  98. shotgun/tui/screens/welcome.py +14 -11
  99. shotgun/tui/services/__init__.py +5 -0
  100. shotgun/tui/services/conversation_service.py +184 -0
  101. shotgun/tui/state/__init__.py +7 -0
  102. shotgun/tui/state/processing_state.py +185 -0
  103. shotgun/tui/utils/mode_progress.py +14 -7
  104. shotgun/tui/widgets/__init__.py +5 -0
  105. shotgun/tui/widgets/widget_coordinator.py +263 -0
  106. shotgun/utils/file_system_utils.py +22 -2
  107. shotgun/utils/marketing.py +110 -0
  108. shotgun/utils/update_checker.py +69 -14
  109. shotgun_sh-0.2.17.dist-info/METADATA +465 -0
  110. shotgun_sh-0.2.17.dist-info/RECORD +194 -0
  111. {shotgun_sh-0.2.8.dev2.dist-info → shotgun_sh-0.2.17.dist-info}/entry_points.txt +1 -0
  112. {shotgun_sh-0.2.8.dev2.dist-info → shotgun_sh-0.2.17.dist-info}/licenses/LICENSE +1 -1
  113. shotgun/tui/screens/chat.py +0 -996
  114. shotgun/tui/screens/chat_screen/history.py +0 -335
  115. shotgun_sh-0.2.8.dev2.dist-info/METADATA +0 -126
  116. shotgun_sh-0.2.8.dev2.dist-info/RECORD +0 -155
  117. {shotgun_sh-0.2.8.dev2.dist-info → shotgun_sh-0.2.17.dist-info}/WHEEL +0 -0
@@ -1,335 +0,0 @@
1
- import json
2
- from collections.abc import Generator, Sequence
3
-
4
- from pydantic_ai.messages import (
5
- BuiltinToolCallPart,
6
- BuiltinToolReturnPart,
7
- ModelMessage,
8
- ModelRequest,
9
- ModelRequestPart,
10
- ModelResponse,
11
- TextPart,
12
- ThinkingPart,
13
- ToolCallPart,
14
- ToolReturnPart,
15
- UserPromptPart,
16
- )
17
- from textual.app import ComposeResult
18
- from textual.reactive import reactive
19
- from textual.widget import Widget
20
- from textual.widgets import Markdown
21
-
22
- from shotgun.tui.components.vertical_tail import VerticalTail
23
- from shotgun.tui.screens.chat_screen.hint_message import HintMessage, HintMessageWidget
24
-
25
-
26
- class PartialResponseWidget(Widget): # TODO: doesn't work lol
27
- DEFAULT_CSS = """
28
- PartialResponseWidget {
29
- height: auto;
30
- }
31
- Markdown, AgentResponseWidget, UserQuestionWidget {
32
- height: auto;
33
- }
34
- """
35
-
36
- item: reactive[ModelMessage | None] = reactive(None, recompose=True)
37
-
38
- def __init__(self, item: ModelMessage | None) -> None:
39
- super().__init__()
40
- self.item = item
41
-
42
- def compose(self) -> ComposeResult:
43
- if self.item is None:
44
- pass
45
- elif self.item.kind == "response":
46
- yield AgentResponseWidget(self.item)
47
- elif self.item.kind == "request":
48
- yield UserQuestionWidget(self.item)
49
-
50
- def watch_item(self, item: ModelMessage | None) -> None:
51
- if item is None:
52
- self.display = False
53
- else:
54
- self.display = True
55
-
56
-
57
- class ChatHistory(Widget):
58
- DEFAULT_CSS = """
59
- VerticalTail {
60
- align: left bottom;
61
-
62
- }
63
- VerticalTail > * {
64
- height: auto;
65
- }
66
-
67
- Horizontal {
68
- height: auto;
69
- background: $secondary-muted;
70
- }
71
-
72
- Markdown {
73
- height: auto;
74
- }
75
- """
76
- partial_response: reactive[ModelMessage | None] = reactive(None)
77
-
78
- def __init__(self) -> None:
79
- super().__init__()
80
- self.items: Sequence[ModelMessage | HintMessage] = []
81
- self.vertical_tail: VerticalTail | None = None
82
- self.partial_response = None
83
- self._rendered_count = 0 # Track how many messages have been mounted
84
-
85
- def compose(self) -> ComposeResult:
86
- self.vertical_tail = VerticalTail()
87
-
88
- filtered = list(self.filtered_items())
89
- with self.vertical_tail:
90
- for item in filtered:
91
- if isinstance(item, ModelRequest):
92
- yield UserQuestionWidget(item)
93
- elif isinstance(item, HintMessage):
94
- yield HintMessageWidget(item)
95
- elif isinstance(item, ModelResponse):
96
- yield AgentResponseWidget(item)
97
- yield PartialResponseWidget(self.partial_response).data_bind(
98
- item=ChatHistory.partial_response
99
- )
100
-
101
- # Track how many messages were rendered during initial compose
102
- self._rendered_count = len(filtered)
103
-
104
- def filtered_items(self) -> Generator[ModelMessage | HintMessage, None, None]:
105
- # Simply yield all items - no filtering needed now that ask_user/ask_questions are gone
106
- yield from self.items
107
-
108
- def update_messages(self, messages: list[ModelMessage | HintMessage]) -> None:
109
- """Update the displayed messages using incremental mounting."""
110
- if not self.vertical_tail:
111
- return
112
-
113
- self.items = messages
114
- filtered = list(self.filtered_items())
115
-
116
- # Only mount new messages that haven't been rendered yet
117
- if len(filtered) > self._rendered_count:
118
- new_messages = filtered[self._rendered_count :]
119
- for item in new_messages:
120
- widget: Widget
121
- if isinstance(item, ModelRequest):
122
- widget = UserQuestionWidget(item)
123
- elif isinstance(item, HintMessage):
124
- widget = HintMessageWidget(item)
125
- elif isinstance(item, ModelResponse):
126
- widget = AgentResponseWidget(item)
127
- else:
128
- continue
129
-
130
- # Mount before the PartialResponseWidget
131
- self.vertical_tail.mount(widget, before=self.vertical_tail.children[-1])
132
-
133
- self._rendered_count = len(filtered)
134
-
135
- # Scroll to bottom to show newly added messages
136
- self.vertical_tail.scroll_end(animate=False)
137
-
138
-
139
- class UserQuestionWidget(Widget):
140
- def __init__(self, item: ModelRequest | None) -> None:
141
- super().__init__()
142
- self.item = item
143
-
144
- def compose(self) -> ComposeResult:
145
- self.display = self.item is not None
146
- if self.item is None:
147
- yield Markdown(markdown="")
148
- else:
149
- prompt = self.format_prompt_parts(self.item.parts)
150
- yield Markdown(markdown=prompt)
151
-
152
- def format_prompt_parts(self, parts: Sequence[ModelRequestPart]) -> str:
153
- acc = ""
154
- for part in parts:
155
- if isinstance(part, UserPromptPart):
156
- acc += (
157
- f"**>** {part.content if isinstance(part.content, str) else ''}\n\n"
158
- )
159
- elif isinstance(part, ToolReturnPart):
160
- # Don't show tool return parts in the UI
161
- pass
162
- return acc
163
-
164
-
165
- class AgentResponseWidget(Widget):
166
- def __init__(self, item: ModelResponse | None) -> None:
167
- super().__init__()
168
- self.item = item
169
-
170
- def compose(self) -> ComposeResult:
171
- self.display = self.item is not None
172
- if self.item is None:
173
- yield Markdown(markdown="")
174
- else:
175
- yield Markdown(markdown=self.compute_output())
176
-
177
- def compute_output(self) -> str:
178
- acc = ""
179
- if self.item is None:
180
- return ""
181
-
182
- for idx, part in enumerate(self.item.parts):
183
- if isinstance(part, TextPart):
184
- # Only show the circle prefix if there's actual content
185
- if part.content and part.content.strip():
186
- acc += f"**⏺** {part.content}\n\n"
187
- elif isinstance(part, ToolCallPart):
188
- parts_str = self._format_tool_call_part(part)
189
- if parts_str: # Only add if there's actual content
190
- acc += parts_str + "\n\n"
191
- elif isinstance(part, BuiltinToolCallPart):
192
- # Format builtin tool calls better
193
- if part.tool_name and "search" in part.tool_name.lower():
194
- args = self._parse_args(part.args)
195
- if isinstance(args, dict) and "query" in args:
196
- query = self._truncate(str(args.get("query", "")))
197
- acc += f'Searching: "{query}"\n\n'
198
- else:
199
- acc += f"{part.tool_name}()\n\n"
200
- else:
201
- # For other builtin tools, show name only or with truncated args
202
- if part.args:
203
- args_str = (
204
- str(part.args)[:50] + "..."
205
- if len(str(part.args)) > 50
206
- else str(part.args)
207
- )
208
- acc += f"{part.tool_name}({args_str})\n\n"
209
- else:
210
- acc += f"{part.tool_name}()\n\n"
211
- elif isinstance(part, BuiltinToolReturnPart):
212
- acc += f"builtin tool ({part.tool_name}) return: {part.content}\n\n"
213
- elif isinstance(part, ThinkingPart):
214
- if (
215
- idx == len(self.item.parts) - 1
216
- ): # show the thinking part only if it's the last part
217
- acc += (
218
- f"thinking: {part.content}\n\n"
219
- if part.content
220
- else "Thinking..."
221
- )
222
- else:
223
- continue
224
- return acc.strip()
225
-
226
- def _truncate(self, text: str, max_length: int = 100) -> str:
227
- """Truncate text to max_length characters, adding ellipsis if needed."""
228
- if len(text) <= max_length:
229
- return text
230
- return text[: max_length - 3] + "..."
231
-
232
- def _parse_args(self, args: dict[str, object] | str | None) -> dict[str, object]:
233
- """Parse tool call arguments, handling both dict and JSON string formats."""
234
- if args is None:
235
- return {}
236
- if isinstance(args, str):
237
- try:
238
- return json.loads(args) if args.strip() else {}
239
- except json.JSONDecodeError:
240
- return {}
241
- return args if isinstance(args, dict) else {}
242
-
243
- def _format_tool_call_part(self, part: ToolCallPart) -> str:
244
- # Parse args once (handles both JSON string and dict)
245
- args = self._parse_args(part.args)
246
-
247
- # Codebase tools - show friendly names
248
- if part.tool_name == "query_graph":
249
- if "query" in args:
250
- query = self._truncate(str(args["query"]))
251
- return f'Querying code: "{query}"'
252
- return "Querying code"
253
-
254
- if part.tool_name == "retrieve_code":
255
- if "qualified_name" in args:
256
- return f'Retrieving code: "{args["qualified_name"]}"'
257
- return "Retrieving code"
258
-
259
- if part.tool_name == "file_read":
260
- if "file_path" in args:
261
- return f'Reading file: "{args["file_path"]}"'
262
- return "Reading file"
263
-
264
- if part.tool_name == "directory_lister":
265
- if "directory" in args:
266
- return f'Listing directory: "{args["directory"]}"'
267
- return "Listing directory"
268
-
269
- if part.tool_name == "codebase_shell":
270
- command = args.get("command", "")
271
- cmd_args = args.get("args", [])
272
- # Handle cmd_args as list of strings
273
- if isinstance(cmd_args, list):
274
- args_str = " ".join(str(arg) for arg in cmd_args)
275
- else:
276
- args_str = ""
277
- full_cmd = f"{command} {args_str}".strip()
278
- if full_cmd:
279
- return f'Running shell: "{self._truncate(full_cmd)}"'
280
- return "Running shell"
281
-
282
- # File management tools
283
- if part.tool_name == "read_file":
284
- if "filename" in args:
285
- return f'Reading file: "{args["filename"]}"'
286
- return "Reading file"
287
-
288
- # Web search tools - handle variations
289
- if (
290
- part.tool_name
291
- in [
292
- "openai_web_search_tool",
293
- "anthropic_web_search_tool",
294
- "gemini_web_search_tool",
295
- ]
296
- or "search" in part.tool_name.lower()
297
- ): # Catch other search variations
298
- if "query" in args:
299
- query = self._truncate(str(args["query"]))
300
- return f'Searching web: "{query}"'
301
- return "Searching web"
302
-
303
- # write_file
304
- if part.tool_name == "write_file" or part.tool_name == "append_file":
305
- if "filename" in args:
306
- return f"{part.tool_name}({args['filename']})"
307
- return f"{part.tool_name}()"
308
-
309
- if part.tool_name == "write_artifact_section":
310
- if "section_title" in args:
311
- return f"{part.tool_name}({args['section_title']})"
312
- return f"{part.tool_name}()"
313
-
314
- if part.tool_name == "final_result":
315
- # Hide final_result tool calls completely - they're internal Pydantic AI mechanics
316
- return ""
317
-
318
- # Default case for unrecognized tools - format args properly
319
- args = self._parse_args(part.args)
320
- if args and isinstance(args, dict):
321
- # Try to extract common fields
322
- if "query" in args:
323
- return f'{part.tool_name}: "{self._truncate(str(args["query"]))}"'
324
- elif "question" in args:
325
- return f'{part.tool_name}: "{self._truncate(str(args["question"]))}"'
326
- else:
327
- # Show tool name with truncated args
328
- args_str = (
329
- str(part.args)[:50] + "..."
330
- if len(str(part.args)) > 50
331
- else str(part.args)
332
- )
333
- return f"{part.tool_name}({args_str})"
334
- else:
335
- return f"{part.tool_name}()"
@@ -1,126 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: shotgun-sh
3
- Version: 0.2.8.dev2
4
- Summary: AI-powered research, planning, and task management CLI tool
5
- Project-URL: Homepage, https://shotgun.sh/
6
- Project-URL: Repository, https://github.com/shotgun-sh/shotgun
7
- Project-URL: Issues, https://github.com/shotgun-sh/shotgun-alpha/issues
8
- Project-URL: Discord, https://discord.gg/5RmY6J2N7s
9
- Author-email: "Proofs.io" <hello@proofs.io>
10
- License: MIT
11
- License-File: LICENSE
12
- Keywords: agent,ai,cli,llm,planning,productivity,pydantic-ai,research,task-management
13
- Classifier: Development Status :: 3 - Alpha
14
- Classifier: Environment :: Console
15
- Classifier: Intended Audience :: Developers
16
- Classifier: License :: OSI Approved :: MIT License
17
- Classifier: Operating System :: OS Independent
18
- Classifier: Programming Language :: Python :: 3
19
- Classifier: Programming Language :: Python :: 3.11
20
- Classifier: Programming Language :: Python :: 3.12
21
- Classifier: Topic :: Software Development :: Libraries :: Python Modules
22
- Classifier: Topic :: Utilities
23
- Requires-Python: >=3.11
24
- Requires-Dist: anthropic>=0.39.0
25
- Requires-Dist: genai-prices>=0.0.27
26
- Requires-Dist: httpx>=0.27.0
27
- Requires-Dist: jinja2>=3.1.0
28
- Requires-Dist: kuzu>=0.7.0
29
- Requires-Dist: logfire[pydantic-ai]>=2.0.0
30
- Requires-Dist: openai>=1.0.0
31
- Requires-Dist: packaging>=23.0
32
- Requires-Dist: posthog>=3.0.0
33
- Requires-Dist: pydantic-ai>=0.0.14
34
- Requires-Dist: rich>=13.0.0
35
- Requires-Dist: sentencepiece>=0.2.0
36
- Requires-Dist: sentry-sdk[pure-eval]>=2.0.0
37
- Requires-Dist: tenacity>=8.0.0
38
- Requires-Dist: textual-dev>=1.7.0
39
- Requires-Dist: textual>=6.1.0
40
- Requires-Dist: tiktoken>=0.7.0
41
- Requires-Dist: tree-sitter-go>=0.23.0
42
- Requires-Dist: tree-sitter-javascript>=0.23.0
43
- Requires-Dist: tree-sitter-python>=0.23.0
44
- Requires-Dist: tree-sitter-rust>=0.23.0
45
- Requires-Dist: tree-sitter-typescript>=0.23.0
46
- Requires-Dist: tree-sitter>=0.21.0
47
- Requires-Dist: typer>=0.12.0
48
- Requires-Dist: watchdog>=4.0.0
49
- Provides-Extra: dev
50
- Requires-Dist: commitizen>=3.13.0; extra == 'dev'
51
- Requires-Dist: lefthook>=1.12.0; extra == 'dev'
52
- Requires-Dist: mypy>=1.11.0; extra == 'dev'
53
- Requires-Dist: ruff>=0.6.0; extra == 'dev'
54
- Description-Content-Type: text/markdown
55
-
56
- # Shotgun
57
-
58
- **Spec-Driven Development for AI Code Generation**
59
-
60
- Shotgun is a CLI tool that turns work with AI code-gen tools from "I want to build X" into: **research → specs → plans → tasks → implementation**. It reads your entire codebase, coordinates AI agents to do the heavy lifting, and exports clean artifacts in the agents.md format so your code-gen tools actually know what they're building.
61
-
62
- 🌐 **Learn more at [shotgun.sh](https://shotgun.sh/)**
63
-
64
- ## Features
65
-
66
- ### 📊 Complete Codebase Understanding
67
-
68
- Before writing a single line, Shotgun reads all of it. Your patterns. Your dependencies. Your technical debt. Whether you're adding features, onboarding devs, planning migrations, or refactoring - Shotgun knows what you're working with.
69
-
70
- ### 🔄 Five Modes. One Journey. Zero Gaps.
71
-
72
- **Research** (what exists) → **Specify** (what to build) → **Plan** (how to build) → **Tasks** (break it down) → **Export** (to any tool)
73
-
74
- Not another chatbot. A complete workflow where each mode feeds the next.
75
-
76
- ### ➡️ Export to agents.md
77
-
78
- Outputs plug into many code-generation tools including Codex, Cursor, Warp, Devin, opencode, Jules, and more.
79
-
80
- ### 📝 Specs That Don't Die in Slack
81
-
82
- Every research finding, every architectural decision, every "here's why we didn't use that library" - captured as markdown in your repo. Version controlled. Searchable.
83
-
84
- ## Installation
85
-
86
- ### Using pipx (Recommended)
87
-
88
- ```bash
89
- pipx install shotgun-sh
90
- ```
91
-
92
- **Why pipx?** It installs Shotgun in an isolated environment, preventing dependency conflicts with your other Python projects.
93
-
94
- ### Using pip
95
-
96
- ```bash
97
- pip install shotgun-sh
98
- ```
99
-
100
- ## Quick Start
101
-
102
- ```bash
103
- # Research your codebase or a topic
104
- shotgun research "What is our authentication flow?"
105
-
106
- # Generate specifications
107
- shotgun spec "Add OAuth2 authentication"
108
-
109
- # Create an implementation plan
110
- shotgun plan "Build user dashboard"
111
-
112
- # Break down into tasks
113
- shotgun tasks "Implement payment system"
114
-
115
- # Export to agents.md format for your code-gen tools
116
- shotgun export
117
- ```
118
-
119
- ## Support
120
-
121
- Have questions? Join our community on **[Discord](https://discord.gg/5RmY6J2N7s)**
122
-
123
- ---
124
-
125
- **License:** MIT
126
- **Python:** 3.11+
@@ -1,155 +0,0 @@
1
- shotgun/__init__.py,sha256=P40K0fnIsb7SKcQrFnXZ4aREjpWchVDhvM1HxI4cyIQ,104
2
- shotgun/api_endpoints.py,sha256=TvxuJyMrZLy6KZTrR6lrdkG8OBtb3TJ48qaw3pWitO0,526
3
- shotgun/build_constants.py,sha256=RXNxMz46HaB5jucgMVpw8a2yCJqjbhTOh0PddyEVMN8,713
4
- shotgun/logging_config.py,sha256=UKenihvgH8OA3W0b8ZFcItYaFJVe9MlsMYlcevyW1HY,7440
5
- shotgun/main.py,sha256=RA3q1xPfqxCu43UmgI2ryZpA-IxPhJb_MJrbLqp9c_g,5140
6
- shotgun/posthog_telemetry.py,sha256=TOiyBtLg21SttHGWKc4-e-PQgpbq6Uz_4OzlvlxMcZ0,6099
7
- shotgun/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
- shotgun/sentry_telemetry.py,sha256=VD8es-tREfgtRKhDsEVvqpo0_kM_ab6iVm2lkOEmTlI,2950
9
- shotgun/telemetry.py,sha256=C8dM7Feo1OxJMwDvgAMaA2RyRDO2rYPvC_8kLBuRUS8,3683
10
- shotgun/agents/__init__.py,sha256=8Jzv1YsDuLyNPFJyckSr_qI4ehTVeDyIMDW4omsfPGc,25
11
- shotgun/agents/agent_manager.py,sha256=cdrw96weXEkqaLGgmIPgnA48iMR1fYBLu_05p1eMHtQ,39851
12
- shotgun/agents/common.py,sha256=0F_dwEc72APvbY1b-lqM9VgPYuY1GpfhjSWv5-1pCB0,19032
13
- shotgun/agents/conversation_history.py,sha256=c-1PBaG9FXPfSmekWtrD6s6YVT0sd98DdDhzS4a1Hyo,7859
14
- shotgun/agents/conversation_manager.py,sha256=X3DWZZIqrv0hS1SUasyoxexnLPBUrZMBg4ZmRAipkBE,4429
15
- shotgun/agents/export.py,sha256=7ZNw7781WJ4peLSeoUc7zxKeaZVxFpow2y4nU4dCfbo,2919
16
- shotgun/agents/llm.py,sha256=hs8j1wwTczGtehzahL1Z_5D4qus5QUx4-h9-m5ZPzm4,2209
17
- shotgun/agents/messages.py,sha256=wNn0qC5AqASM8LMaSGFOerZEJPn5FsIOmaJs1bdosuU,1036
18
- shotgun/agents/models.py,sha256=anNz8_U95B1__VPXgxFqfzk2BRIHrIO4clJlnfedVS8,9862
19
- shotgun/agents/plan.py,sha256=lVhIoRUMCX2TsFbwbgKjS2HHhNreX35j_aZRqGxFAso,2980
20
- shotgun/agents/research.py,sha256=EYqUda_wtrxmUNy6Mme3NFnO_uOXBCs94m2tZzheNOE,3224
21
- shotgun/agents/specify.py,sha256=38z0n_7pAgWN3oJFuOxfiEHWtEqzMha-SyPhhZ9pWag,3087
22
- shotgun/agents/tasks.py,sha256=AuriwtDn6uZz2G0eKfqBHYQrxYfJlbiAd-fcsw9lU3I,2949
23
- shotgun/agents/usage_manager.py,sha256=5d9JC4_cthXwhTSytMfMExMDAUYp8_nkPepTJZXk13w,5017
24
- shotgun/agents/config/__init__.py,sha256=Fl8K_81zBpm-OfOW27M_WWLSFdaHHek6lWz95iDREjQ,318
25
- shotgun/agents/config/constants.py,sha256=JNuLpeBUKikEsxGSjwX3RVWUQpbCKnDKstF2NczuDqk,932
26
- shotgun/agents/config/manager.py,sha256=WO3TOwXCSOa7e3s_rmvH74jGw7xTqA_OaGhNaUsZ0a4,18922
27
- shotgun/agents/config/models.py,sha256=ohLXt9niCy4uFfFP1E6WSBZtxh7aZ16gTA2S3pHYkmc,5431
28
- shotgun/agents/config/provider.py,sha256=K2uW7DkdAhZfoDJcWV7NxOrSoEq1rQzArtZnxIgEe3E,12496
29
- shotgun/agents/history/__init__.py,sha256=XFQj2a6fxDqVg0Q3juvN9RjV_RJbgvFZtQOCOjVJyp4,147
30
- shotgun/agents/history/compaction.py,sha256=9RMpG0aY_7L4TecbgwHSOkGtbd9W5XZTg-MbzZmNl00,3515
31
- shotgun/agents/history/constants.py,sha256=yWY8rrTZarLA3flCCMB_hS2NMvUDRDTwP4D4j7MIh1w,446
32
- shotgun/agents/history/context_extraction.py,sha256=yPF3oYpv5GFsFQT5y53ORKdADtrkGH4u8LwPdO0YVzU,7157
33
- shotgun/agents/history/history_building.py,sha256=6LFDZ60MTPDoGAcmu_mjlnjVYu8YYWdIi-cGbF3jm7A,3532
34
- shotgun/agents/history/history_processors.py,sha256=D3z-hzrXHxE7OAZaVX4_YAKN_nyxSF5iYMIYO24V_CI,17943
35
- shotgun/agents/history/message_utils.py,sha256=aPusAl2RYKbjc7lBxPaNprRHmZEG6fe97q7DQUlhlzU,2918
36
- shotgun/agents/history/token_estimation.py,sha256=iRyKq-YDivEpJrULIbQgNpjhOuSC4nHVJYfsWEFV8sQ,4770
37
- shotgun/agents/history/token_counting/__init__.py,sha256=YZt5Lus--fkF6l1hdkIlp1e_oAIpACNwHOI0FRP4q8s,924
38
- shotgun/agents/history/token_counting/anthropic.py,sha256=0Nf4mR7yjDbGyy8WguHse-sOENyU4X4CkthPjzbBaog,4031
39
- shotgun/agents/history/token_counting/base.py,sha256=TN4mzwSyWNQyTuOuCFaU-8AgLdAyquoX3af4qrmkxCs,1904
40
- shotgun/agents/history/token_counting/openai.py,sha256=XJ2z2HaUG6f3Cw9tCK_yaOsaMJGHpSFF1I30-d3soSI,2350
41
- shotgun/agents/history/token_counting/sentencepiece_counter.py,sha256=qj1bT7J5nCd5y6Mr42O9K1KTaele0rjdd09FeyyEA70,3987
42
- shotgun/agents/history/token_counting/tokenizer_cache.py,sha256=Y0V6KMtEwn42M5-zJGAc7YudM8X6m5-j2ekA6YGL5Xk,2868
43
- shotgun/agents/history/token_counting/utils.py,sha256=d124IDjtd0IYBYrr3gDJGWxSbdP10Vrc7ZistbUosMg,5002
44
- shotgun/agents/tools/__init__.py,sha256=kYppd4f4MoJcfTEPzkY2rqtxL1suXRGa9IRUm1G82GY,717
45
- shotgun/agents/tools/file_management.py,sha256=7qj2yxzOC_40_swuBIcRcFv6MSZM78mNfsV3SCL_sH4,9205
46
- shotgun/agents/tools/codebase/__init__.py,sha256=ceAGkK006NeOYaIJBLQsw7Q46sAyCRK9PYDs8feMQVw,661
47
- shotgun/agents/tools/codebase/codebase_shell.py,sha256=9b7ZStAVFprdGqp1O23ZgwkToMytlUdp_R4MhvmENhc,8584
48
- shotgun/agents/tools/codebase/directory_lister.py,sha256=eX5GKDSmbKggKDvjPpYMa2WPSGPYQAtUEZ4eN01T0t8,4703
49
- shotgun/agents/tools/codebase/file_read.py,sha256=EGK5yNqiS4cbIEQfDtdKVoJSJYk20NbZv1AQKNBUKVc,5051
50
- shotgun/agents/tools/codebase/models.py,sha256=8eR3_8DQiBNgB2twu0aC_evIJbugN9KW3gtxMZdGYCE,10087
51
- shotgun/agents/tools/codebase/query_graph.py,sha256=vOeyN4-OZj-vpTSk3Z9W5TjraZAepJ-Qjk_zzvum3fU,2115
52
- shotgun/agents/tools/codebase/retrieve_code.py,sha256=2VjiqVKJMd9rPV-mGrL4C-N8fqGjYLW6ZInFGbcTxOM,2878
53
- shotgun/agents/tools/web_search/__init__.py,sha256=166SzGDspEqRoHvAoguoy02WAT5EQfozoc5Ha5VubdY,3699
54
- shotgun/agents/tools/web_search/anthropic.py,sha256=_xtSUImIi8XNOVY4w2tJjHGEpAnEUkaCqWpjn7hwikY,5505
55
- shotgun/agents/tools/web_search/gemini.py,sha256=RESEVKAJHK_IkQf6npo6EObOJDQtBqhRVnQ4GsD3rSk,3670
56
- shotgun/agents/tools/web_search/openai.py,sha256=V_hs1bPoNNLK_SqR5ObM_wId9hc-NIOSSfGWAR16HIU,3550
57
- shotgun/agents/tools/web_search/utils.py,sha256=GLJ5QV9bT2ubFMuFN7caMN7tK9OTJ0R3GD57B-tCMF0,532
58
- shotgun/cli/__init__.py,sha256=_F1uW2g87y4bGFxz8Gp8u7mq2voHp8vQIUtCmm8Tojo,40
59
- shotgun/cli/config.py,sha256=lT_zXwui-Wv3hewjebQeu9eLwK3tYn1wla5vKit6eqs,7931
60
- shotgun/cli/export.py,sha256=3hIwK2_OM1MFYSTfzBxsGuuBGm5fo0XdxASfQ5Uqb3Y,2471
61
- shotgun/cli/feedback.py,sha256=K8iFDl5051_g95jwDEm9gdKUjDWO8HBVZjlRN8uD7Mk,1300
62
- shotgun/cli/models.py,sha256=kwZEldQWUheNsqF_ezgDzRBc6h0Y0JxFw1VMQjZlvPE,182
63
- shotgun/cli/plan.py,sha256=T-eu-I9z-dSoKqJ-KI8X5i5Mm0VL1BfornxRiUjTgnk,2324
64
- shotgun/cli/research.py,sha256=qvBBtX3Wyn6pDZlJpcEvbeK-0iTOXegi71tm8HKVYaE,2490
65
- shotgun/cli/specify.py,sha256=ErRQ72Zc75fmxopZbKy0vvnLPuYBLsGynpjj1X6-BwI,2166
66
- shotgun/cli/tasks.py,sha256=17qWoGCVYpNIxa2vaoIH1P-xz2RcGLaK8SF4JlPsOWI,2420
67
- shotgun/cli/update.py,sha256=Dn_No7jPmdZ-7qYlhzI0BtmlufetVdw1BN-xRi_UE5A,4718
68
- shotgun/cli/utils.py,sha256=umVWXDx8pelovMk-nT8B7m0c39AKY9hHsuAMnbw_Hcg,732
69
- shotgun/cli/codebase/__init__.py,sha256=rKdvx33p0i_BYbNkz5_4DCFgEMwzOOqLi9f5p7XTLKM,73
70
- shotgun/cli/codebase/commands.py,sha256=1N2yOGmok0ZarqXPIpWGcsQrwm_ZJcyWiMxy6tm0j70,8711
71
- shotgun/cli/codebase/models.py,sha256=B9vs-d-Bq0aS6FZKebhHT-9tw90Y5f6k_t71VlZpL8k,374
72
- shotgun/codebase/__init__.py,sha256=QBgFE2Abd5Vl7_NdYOglF9S6d-vIjkb3C0cpIYoHZEU,309
73
- shotgun/codebase/models.py,sha256=5e_7zaPL032n_ghcvs01Uug3BH4jyKiQ3S3U5w21BSM,5296
74
- shotgun/codebase/service.py,sha256=nyggapfHKdwkKXyuT9oA0tJ9qf4RNVsOxfY8lC5pHro,8006
75
- shotgun/codebase/core/__init__.py,sha256=GWWhJEqChiDXAF4omYCgzgoZmJjwsAf6P1aZ5Bl8OE0,1170
76
- shotgun/codebase/core/change_detector.py,sha256=kWCYLWzRzb3IGGOj71KBn7UOCOKMpINJbOBDf98aMxE,12409
77
- shotgun/codebase/core/code_retrieval.py,sha256=_JVyyQKHDFm3dxOOua1mw9eIIOHIVz3-I8aZtEsEj1E,7927
78
- shotgun/codebase/core/cypher_models.py,sha256=Yfysfa9lLguILftkmtuJCN3kLBFIo7WW7NigM-Zr-W4,1735
79
- shotgun/codebase/core/ingestor.py,sha256=CNYbdoJycnbA2psYCD9uKcUwIe3Ao7I7T6NrPhTQE9k,64613
80
- shotgun/codebase/core/language_config.py,sha256=vsqHyuFnumRPRBV1lMOxWKNOIiClO6FyfKQR0fGrtl4,8934
81
- shotgun/codebase/core/manager.py,sha256=kjxQ9eCs5vVCVDproCN1eYSKuGiqtcxF01reQ18JfOw,66184
82
- shotgun/codebase/core/nl_query.py,sha256=kPoSJXBlm5rLhzOofZhqPVMJ_Lj3rV2H6sld6BwtMdg,16115
83
- shotgun/codebase/core/parser_loader.py,sha256=LZRrDS8Sp518jIu3tQW-BxdwJ86lnsTteI478ER9Td8,4278
84
- shotgun/llm_proxy/__init__.py,sha256=3ST3ygtf2sXXSOjIFHxVZ5xqRbT3TF7jpNHwuZAtIwA,452
85
- shotgun/llm_proxy/clients.py,sha256=Y19W8Gb2e-37w8rUKPmxJOqoTk6GlcPhZhoeAbbURU0,1341
86
- shotgun/llm_proxy/constants.py,sha256=_4piKdyvM7pAIRdAGrzYexwWoDlueUZiEMfwWrOa4T0,381
87
- shotgun/prompts/__init__.py,sha256=RswUm0HMdfm2m2YKUwUsEdRIwoczdbI7zlucoEvHYRo,132
88
- shotgun/prompts/loader.py,sha256=_7CdUYrAo6ZwvTBUlXugKyLU0IDBg5CVzUIAHFPw418,4433
89
- shotgun/prompts/agents/__init__.py,sha256=YRIJMbzpArojNX1BP5gfxxois334z_GQga8T-xyWMbY,39
90
- shotgun/prompts/agents/export.j2,sha256=DGqVijH1PkpkY0rDauU52u_fMv15frEvOdXAPFZNMM4,17057
91
- shotgun/prompts/agents/plan.j2,sha256=mbt505NdqmzmPxXzQYJS_gH5vkiVa2a3Dgz2K-15JZk,6093
92
- shotgun/prompts/agents/research.j2,sha256=QFoSSiF_5v7c78RHaiucZEb9mOC_wF54BVKnJEH_DnI,3964
93
- shotgun/prompts/agents/specify.j2,sha256=XdB2WehbVmszw9crl6PEHLyLgwvU08MV--ClV3hI4mA,12014
94
- shotgun/prompts/agents/tasks.j2,sha256=SMvTQPzRR6eHlW3fcj-7Bl-Lh9HWaiF3uAKv77nMdZw,5956
95
- shotgun/prompts/agents/partials/codebase_understanding.j2,sha256=7WH-PVd-TRBFQUdOdKkwwn9hAUaJznFZMAGHhO7IGGU,5633
96
- shotgun/prompts/agents/partials/common_agent_system_prompt.j2,sha256=wfjsQGcMTWWGBk9l0pKDnPehG8NrwTHm5FFEqba__LI,2161
97
- shotgun/prompts/agents/partials/content_formatting.j2,sha256=MG0JB7SSp8YV5akDWpbs2f9DcdREIYqLp38NnoWLeQ0,1854
98
- shotgun/prompts/agents/partials/interactive_mode.j2,sha256=nyNTURRszG_Pl7M3TS_luUshekDn9yVHfBDMkHSZ1kw,1448
99
- shotgun/prompts/agents/state/system_state.j2,sha256=RPweqBYmgWMiDuOjdEDl6NLgYU7HMaUGW1jBSnD5UzQ,1270
100
- shotgun/prompts/agents/state/codebase/codebase_graphs_available.j2,sha256=U-hy-H9bPwV0sYIHTZ5TESxc5EOCtntI8GUZOmJipJw,601
101
- shotgun/prompts/codebase/__init__.py,sha256=NYuPMtmYM2ptuwf3YxVuotNlJOUq0hnjmwlzKcJkGK4,42
102
- shotgun/prompts/codebase/cypher_query_patterns.j2,sha256=ufTx_xT3VoS76KcVUbIgGQx-bJoJHx3bBE3dagAXv18,8913
103
- shotgun/prompts/codebase/cypher_system.j2,sha256=jo8d_AIoyAd0zKCvPXSmYGBxvtulMsCfeaOTdOfeC5g,2620
104
- shotgun/prompts/codebase/enhanced_query_context.j2,sha256=WzGnFaBLZO-mOdkZ_u_PewSu9niKy87DKNL4uzQq1Jg,724
105
- shotgun/prompts/codebase/partials/cypher_rules.j2,sha256=yhptyyZNzFNJWFGmOkxpF5PzZtUAXWDF4xl9ADu7yDw,3200
106
- shotgun/prompts/codebase/partials/graph_schema.j2,sha256=fUsD1ZgU1pIWUzrs97jHq3TatKeGSvZgG8XP5gCQUJc,1939
107
- shotgun/prompts/codebase/partials/temporal_context.j2,sha256=yYHQHBQ4EeSs6TtKPm9fflGW3y6H0-yAANcTdsApkk4,1388
108
- shotgun/prompts/history/__init__.py,sha256=wbMLQ8yWmYz1sfXXigEAUlNkFcM50KdQv0kp4VU_P58,43
109
- shotgun/prompts/history/incremental_summarization.j2,sha256=GmnNh0pWTjaEaI1sPwKNsGCys5fK8xrzWqalAs_LhJw,2447
110
- shotgun/prompts/history/summarization.j2,sha256=OYNVHg65zbuWB6_pXzTOs2T2k5qFD2gyfbmr6NP01rs,2268
111
- shotgun/prompts/tools/web_search.j2,sha256=_F1m5UYiZENPQCqTUiO2du9Lkzs1SWujjAiauDD_5-Y,568
112
- shotgun/sdk/__init__.py,sha256=ESV0WM9MigjXG30g9qVjcCMI40GQv-P-MSMGVuOisK4,380
113
- shotgun/sdk/codebase.py,sha256=7doUvwwl27RDJZIbP56LQsAx26GANtAKEBptTUhLT6w,8842
114
- shotgun/sdk/exceptions.py,sha256=qBcQv0v7ZTwP7CMcxZST4GqCsfOWtOUjSzGBo0-heqo,412
115
- shotgun/sdk/models.py,sha256=X9nOTUHH0cdkQW1NfnMEDu-QgK9oUsEISh1Jtwr5Am4,5496
116
- shotgun/sdk/services.py,sha256=J4PJFSxCQ6--u7rb3Ta-9eYtlYcxcbnzrMP6ThyCnw4,705
117
- shotgun/shotgun_web/__init__.py,sha256=IB-TvK3WvLNrdKH0j9MwMGtIjqi81ASFIVwaZa0ifNg,461
118
- shotgun/shotgun_web/client.py,sha256=n5DDuVfSa6VPZjhSsfSxQlSFOnhgDHyidRnB8Hv9XF4,4134
119
- shotgun/shotgun_web/constants.py,sha256=eNvtjlu81bAVQaCwZXOVjSpDopUm9pf34XuZEvuMiko,661
120
- shotgun/shotgun_web/models.py,sha256=Ie9VfqKZM2tIJhIjentU9qLoNaMZvnUJaIu-xg9kQsA,1391
121
- shotgun/tui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
122
- shotgun/tui/app.py,sha256=B2tKbXeGhWBIVec1jJHGAuBcP1SMbO_6xol2OaBpw2Y,5374
123
- shotgun/tui/filtered_codebase_service.py,sha256=lJ8gTMhIveTatmvmGLP299msWWTkVYKwvY_2FhuL2s4,1687
124
- shotgun/tui/styles.tcss,sha256=ETyyw1bpMBOqTi5RLcAJUScdPWTvAWEqE9YcT0kVs_E,121
125
- shotgun/tui/commands/__init__.py,sha256=8D5lvtpqMW5-fF7Bg3oJtUzU75cKOv6aUaHYYszydU8,2518
126
- shotgun/tui/components/prompt_input.py,sha256=Ss-htqraHZAPaehGE4x86ij0veMjc4UgadMXpbdXr40,2229
127
- shotgun/tui/components/spinner.py,sha256=ovTDeaJ6FD6chZx_Aepia6R3UkPOVJ77EKHfRmn39MY,2427
128
- shotgun/tui/components/splash.py,sha256=vppy9vEIEvywuUKRXn2y11HwXSRkQZHLYoVjhDVdJeU,1267
129
- shotgun/tui/components/vertical_tail.py,sha256=kROwTaRjUwVB7H35dtmNcUVPQqNYvvfq7K2tXBKEb6c,638
130
- shotgun/tui/screens/chat.py,sha256=VAsgX7YiXTXAH7pAwcWaWr2hGu_Ft0i8VpoUETTPsTM,37424
131
- shotgun/tui/screens/chat.tcss,sha256=2Yq3E23jxsySYsgZf4G1AYrYVcpX0UDW6kNNI0tDmtM,437
132
- shotgun/tui/screens/directory_setup.py,sha256=lIZ1J4A6g5Q2ZBX8epW7BhR96Dmdcg22CyiM5S-I5WU,3237
133
- shotgun/tui/screens/feedback.py,sha256=VxpW0PVxMp22ZvSfQkTtgixNrpEOlfWtekjqlVfYEjA,5708
134
- shotgun/tui/screens/model_picker.py,sha256=G-EvalpxgHKk0W3FgHMcxIr817VwZyEgh_ZadSQiRwo,11831
135
- shotgun/tui/screens/provider_config.py,sha256=UCnAzjXPoP7Y73gsXxZF2PNA4LdSgpgoGYwiOd6fERA,10902
136
- shotgun/tui/screens/shotgun_auth.py,sha256=Y--7LZewV6gfDkucxymfAO7BCd7eI2C3H1ClDMztVio,10663
137
- shotgun/tui/screens/splash.py,sha256=E2MsJihi3c9NY1L28o_MstDxGwrCnnV7zdq00MrGAsw,706
138
- shotgun/tui/screens/welcome.py,sha256=XOKhd3hjhEUBjs9ZlUIZDdmrlIAvQ7qdO1_KKruGcqo,6134
139
- shotgun/tui/screens/chat_screen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
140
- shotgun/tui/screens/chat_screen/command_providers.py,sha256=7Xnxd4k30bpLOMZSX32bcugU4IgpqU4Y8f6eHWKXd4o,12694
141
- shotgun/tui/screens/chat_screen/hint_message.py,sha256=WOpbk8q7qt7eOHTyyHvh_IQIaublVDeJGaLpsxEk9FA,933
142
- shotgun/tui/screens/chat_screen/history.py,sha256=Bv7t1bcCf66X2qNEgwGMpPzNcxy4QZC4USshbctmJzA,12274
143
- shotgun/tui/utils/__init__.py,sha256=cFjDfoXTRBq29wgP7TGRWUu1eFfiIG-LLOzjIGfadgI,150
144
- shotgun/tui/utils/mode_progress.py,sha256=lseRRo7kMWLkBzI3cU5vqJmS2ZcCjyRYf9Zwtvc-v58,10931
145
- shotgun/utils/__init__.py,sha256=WinIEp9oL2iMrWaDkXz2QX4nYVPAm8C9aBSKTeEwLtE,198
146
- shotgun/utils/datetime_utils.py,sha256=x_uYmG1n9rkhSO2oR2uV9ttiuPL0nKa9os8YYaPfdWY,2592
147
- shotgun/utils/env_utils.py,sha256=ulM3BRi9ZhS7uC-zorGeDQm4SHvsyFuuU9BtVPqdrHY,1418
148
- shotgun/utils/file_system_utils.py,sha256=l-0p1bEHF34OU19MahnRFdClHufThfGAjQ431teAIp0,1004
149
- shotgun/utils/source_detection.py,sha256=Co6Q03R3fT771TF3RzB-70stfjNP2S4F_ArZKibwzm8,454
150
- shotgun/utils/update_checker.py,sha256=IgzPHRhS1ETH7PnJR_dIx6lxgr1qHpCkMTgzUxvGjhI,7586
151
- shotgun_sh-0.2.8.dev2.dist-info/METADATA,sha256=8nSxwROnGNuQxNUY8bovpYeFSCwHhnLLx4geGZZVaKo,4299
152
- shotgun_sh-0.2.8.dev2.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
153
- shotgun_sh-0.2.8.dev2.dist-info/entry_points.txt,sha256=asZxLU4QILneq0MWW10saVCZc4VWhZfb0wFZvERnzfA,45
154
- shotgun_sh-0.2.8.dev2.dist-info/licenses/LICENSE,sha256=YebsZl590zCHrF_acCU5pmNt0pnAfD2DmAnevJPB1tY,1065
155
- shotgun_sh-0.2.8.dev2.dist-info/RECORD,,