shotgun-sh 0.4.0.dev1__py3-none-any.whl → 0.6.2__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 (135) hide show
  1. shotgun/agents/agent_manager.py +307 -8
  2. shotgun/agents/cancellation.py +103 -0
  3. shotgun/agents/common.py +12 -0
  4. shotgun/agents/config/README.md +0 -1
  5. shotgun/agents/config/manager.py +10 -7
  6. shotgun/agents/config/models.py +5 -27
  7. shotgun/agents/config/provider.py +44 -27
  8. shotgun/agents/conversation/history/token_counting/base.py +51 -9
  9. shotgun/agents/file_read.py +176 -0
  10. shotgun/agents/messages.py +15 -3
  11. shotgun/agents/models.py +24 -1
  12. shotgun/agents/router/models.py +8 -0
  13. shotgun/agents/router/tools/delegation_tools.py +55 -1
  14. shotgun/agents/router/tools/plan_tools.py +88 -7
  15. shotgun/agents/runner.py +17 -2
  16. shotgun/agents/tools/__init__.py +8 -0
  17. shotgun/agents/tools/codebase/directory_lister.py +27 -39
  18. shotgun/agents/tools/codebase/file_read.py +26 -35
  19. shotgun/agents/tools/codebase/query_graph.py +9 -0
  20. shotgun/agents/tools/codebase/retrieve_code.py +9 -0
  21. shotgun/agents/tools/file_management.py +32 -2
  22. shotgun/agents/tools/file_read_tools/__init__.py +7 -0
  23. shotgun/agents/tools/file_read_tools/multimodal_file_read.py +167 -0
  24. shotgun/agents/tools/markdown_tools/__init__.py +62 -0
  25. shotgun/agents/tools/markdown_tools/insert_section.py +148 -0
  26. shotgun/agents/tools/markdown_tools/models.py +86 -0
  27. shotgun/agents/tools/markdown_tools/remove_section.py +114 -0
  28. shotgun/agents/tools/markdown_tools/replace_section.py +119 -0
  29. shotgun/agents/tools/markdown_tools/utils.py +453 -0
  30. shotgun/agents/tools/registry.py +44 -6
  31. shotgun/agents/tools/web_search/openai.py +42 -23
  32. shotgun/attachments/__init__.py +41 -0
  33. shotgun/attachments/errors.py +60 -0
  34. shotgun/attachments/models.py +107 -0
  35. shotgun/attachments/parser.py +257 -0
  36. shotgun/attachments/processor.py +193 -0
  37. shotgun/build_constants.py +4 -7
  38. shotgun/cli/clear.py +2 -2
  39. shotgun/cli/codebase/commands.py +181 -65
  40. shotgun/cli/compact.py +2 -2
  41. shotgun/cli/context.py +2 -2
  42. shotgun/cli/error_handler.py +2 -2
  43. shotgun/cli/run.py +90 -0
  44. shotgun/cli/spec/backup.py +2 -1
  45. shotgun/codebase/__init__.py +2 -0
  46. shotgun/codebase/benchmarks/__init__.py +35 -0
  47. shotgun/codebase/benchmarks/benchmark_runner.py +309 -0
  48. shotgun/codebase/benchmarks/exporters.py +119 -0
  49. shotgun/codebase/benchmarks/formatters/__init__.py +49 -0
  50. shotgun/codebase/benchmarks/formatters/base.py +34 -0
  51. shotgun/codebase/benchmarks/formatters/json_formatter.py +106 -0
  52. shotgun/codebase/benchmarks/formatters/markdown.py +136 -0
  53. shotgun/codebase/benchmarks/models.py +129 -0
  54. shotgun/codebase/core/__init__.py +4 -0
  55. shotgun/codebase/core/call_resolution.py +91 -0
  56. shotgun/codebase/core/change_detector.py +11 -6
  57. shotgun/codebase/core/errors.py +159 -0
  58. shotgun/codebase/core/extractors/__init__.py +23 -0
  59. shotgun/codebase/core/extractors/base.py +138 -0
  60. shotgun/codebase/core/extractors/factory.py +63 -0
  61. shotgun/codebase/core/extractors/go/__init__.py +7 -0
  62. shotgun/codebase/core/extractors/go/extractor.py +122 -0
  63. shotgun/codebase/core/extractors/javascript/__init__.py +7 -0
  64. shotgun/codebase/core/extractors/javascript/extractor.py +132 -0
  65. shotgun/codebase/core/extractors/protocol.py +109 -0
  66. shotgun/codebase/core/extractors/python/__init__.py +7 -0
  67. shotgun/codebase/core/extractors/python/extractor.py +141 -0
  68. shotgun/codebase/core/extractors/rust/__init__.py +7 -0
  69. shotgun/codebase/core/extractors/rust/extractor.py +139 -0
  70. shotgun/codebase/core/extractors/types.py +15 -0
  71. shotgun/codebase/core/extractors/typescript/__init__.py +7 -0
  72. shotgun/codebase/core/extractors/typescript/extractor.py +92 -0
  73. shotgun/codebase/core/gitignore.py +252 -0
  74. shotgun/codebase/core/ingestor.py +644 -354
  75. shotgun/codebase/core/kuzu_compat.py +119 -0
  76. shotgun/codebase/core/language_config.py +239 -0
  77. shotgun/codebase/core/manager.py +256 -46
  78. shotgun/codebase/core/metrics_collector.py +310 -0
  79. shotgun/codebase/core/metrics_types.py +347 -0
  80. shotgun/codebase/core/parallel_executor.py +424 -0
  81. shotgun/codebase/core/work_distributor.py +254 -0
  82. shotgun/codebase/core/worker.py +768 -0
  83. shotgun/codebase/indexing_state.py +86 -0
  84. shotgun/codebase/models.py +94 -0
  85. shotgun/codebase/service.py +13 -0
  86. shotgun/exceptions.py +9 -9
  87. shotgun/main.py +3 -16
  88. shotgun/posthog_telemetry.py +165 -24
  89. shotgun/prompts/agents/file_read.j2 +48 -0
  90. shotgun/prompts/agents/partials/common_agent_system_prompt.j2 +19 -47
  91. shotgun/prompts/agents/partials/content_formatting.j2 +12 -33
  92. shotgun/prompts/agents/partials/interactive_mode.j2 +9 -32
  93. shotgun/prompts/agents/partials/router_delegation_mode.j2 +21 -22
  94. shotgun/prompts/agents/plan.j2 +14 -0
  95. shotgun/prompts/agents/router.j2 +531 -258
  96. shotgun/prompts/agents/specify.j2 +14 -0
  97. shotgun/prompts/agents/state/codebase/codebase_graphs_available.j2 +14 -1
  98. shotgun/prompts/agents/state/system_state.j2 +13 -11
  99. shotgun/prompts/agents/tasks.j2 +14 -0
  100. shotgun/settings.py +49 -10
  101. shotgun/tui/app.py +149 -18
  102. shotgun/tui/commands/__init__.py +9 -1
  103. shotgun/tui/components/attachment_bar.py +87 -0
  104. shotgun/tui/components/prompt_input.py +25 -28
  105. shotgun/tui/components/status_bar.py +14 -7
  106. shotgun/tui/dependencies.py +3 -8
  107. shotgun/tui/protocols.py +18 -0
  108. shotgun/tui/screens/chat/chat.tcss +15 -0
  109. shotgun/tui/screens/chat/chat_screen.py +766 -235
  110. shotgun/tui/screens/chat/codebase_index_prompt_screen.py +8 -4
  111. shotgun/tui/screens/chat_screen/attachment_hint.py +40 -0
  112. shotgun/tui/screens/chat_screen/command_providers.py +0 -10
  113. shotgun/tui/screens/chat_screen/history/chat_history.py +54 -14
  114. shotgun/tui/screens/chat_screen/history/formatters.py +22 -0
  115. shotgun/tui/screens/chat_screen/history/user_question.py +25 -3
  116. shotgun/tui/screens/database_locked_dialog.py +219 -0
  117. shotgun/tui/screens/database_timeout_dialog.py +158 -0
  118. shotgun/tui/screens/kuzu_error_dialog.py +135 -0
  119. shotgun/tui/screens/model_picker.py +1 -3
  120. shotgun/tui/screens/models.py +11 -0
  121. shotgun/tui/state/processing_state.py +19 -0
  122. shotgun/tui/widgets/widget_coordinator.py +18 -0
  123. shotgun/utils/file_system_utils.py +4 -1
  124. {shotgun_sh-0.4.0.dev1.dist-info → shotgun_sh-0.6.2.dist-info}/METADATA +87 -34
  125. {shotgun_sh-0.4.0.dev1.dist-info → shotgun_sh-0.6.2.dist-info}/RECORD +128 -79
  126. shotgun/cli/export.py +0 -81
  127. shotgun/cli/plan.py +0 -73
  128. shotgun/cli/research.py +0 -93
  129. shotgun/cli/specify.py +0 -70
  130. shotgun/cli/tasks.py +0 -78
  131. shotgun/sentry_telemetry.py +0 -232
  132. shotgun/tui/screens/onboarding.py +0 -584
  133. {shotgun_sh-0.4.0.dev1.dist-info → shotgun_sh-0.6.2.dist-info}/WHEEL +0 -0
  134. {shotgun_sh-0.4.0.dev1.dist-info → shotgun_sh-0.6.2.dist-info}/entry_points.txt +0 -0
  135. {shotgun_sh-0.4.0.dev1.dist-info → shotgun_sh-0.6.2.dist-info}/licenses/LICENSE +0 -0
@@ -1,584 +0,0 @@
1
- """Onboarding popup modal for first-time users."""
2
-
3
- import webbrowser
4
-
5
- from textual import on
6
- from textual.app import ComposeResult
7
- from textual.containers import Container, Horizontal, VerticalScroll
8
- from textual.events import Resize
9
- from textual.screen import ModalScreen
10
- from textual.widgets import Button, Markdown, Static
11
-
12
- from shotgun.tui.layout import COMPACT_HEIGHT_THRESHOLD, TINY_HEIGHT_THRESHOLD
13
-
14
-
15
- class OnboardingModal(ModalScreen[None]):
16
- """Multi-page onboarding modal for new users.
17
-
18
- This modal presents helpful resources and tips for using Shotgun across
19
- multiple pages. Users can navigate between pages using Next/Back buttons.
20
- """
21
-
22
- CSS = """
23
- OnboardingModal {
24
- align: center middle;
25
- }
26
-
27
- #onboarding-container {
28
- width: 95;
29
- max-width: 100;
30
- height: auto;
31
- max-height: 90%;
32
- border: thick $primary;
33
- background: $surface;
34
- padding: 2;
35
- }
36
-
37
- #progress-sidebar {
38
- width: 26;
39
- dock: left;
40
- border-right: solid $primary;
41
- padding: 1;
42
- height: 100%;
43
- }
44
-
45
- #main-content {
46
- width: 1fr;
47
- height: auto;
48
- }
49
-
50
- #progress-header {
51
- text-style: bold;
52
- padding-bottom: 1;
53
- color: $text-accent;
54
- }
55
-
56
- .progress-item {
57
- padding: 1 0;
58
- }
59
-
60
- .progress-item-current {
61
- color: $accent;
62
- text-style: bold;
63
- }
64
-
65
- .progress-item-visited {
66
- color: $success;
67
- }
68
-
69
- .progress-item-unvisited {
70
- color: $text-muted;
71
- }
72
-
73
- #onboarding-header {
74
- text-style: bold;
75
- color: $text-accent;
76
- padding-bottom: 1;
77
- text-align: center;
78
- }
79
-
80
- #onboarding-content {
81
- height: 1fr;
82
- padding: 1 0;
83
- }
84
-
85
- #page-indicator {
86
- text-align: center;
87
- color: $text-muted;
88
- padding: 1 0;
89
- }
90
-
91
- #buttons-container {
92
- height: auto;
93
- padding: 1 0 0 0;
94
- }
95
-
96
- #navigation-buttons {
97
- width: 100%;
98
- height: auto;
99
- align: center middle;
100
- }
101
-
102
- .nav-button {
103
- margin: 0 1;
104
- min-width: 12;
105
- }
106
-
107
- #resource-sections {
108
- padding: 1 0;
109
- height: auto;
110
- }
111
-
112
- #resource-sections Button {
113
- width: 100%;
114
- margin: 0 0 2 0;
115
- }
116
-
117
- #video-section {
118
- padding: 0;
119
- margin: 0 0 1 0;
120
- }
121
-
122
- #docs-section {
123
- padding: 0;
124
- margin: 2 0 1 0;
125
- }
126
-
127
- /* Tiny screen fallback */
128
- #tiny-screen-container {
129
- display: none;
130
- width: auto;
131
- height: auto;
132
- padding: 1 2;
133
- background: $surface;
134
- text-align: center;
135
- }
136
-
137
- #tiny-screen-message {
138
- padding: 1 0;
139
- }
140
-
141
- #tiny-screen-link {
142
- padding: 1 0;
143
- color: $accent;
144
- }
145
-
146
- /* Compact styles for short terminals */
147
- #onboarding-container.compact {
148
- padding: 1;
149
- max-height: 98%;
150
- }
151
-
152
- #progress-sidebar.compact {
153
- padding: 0;
154
- }
155
-
156
- .progress-item.compact {
157
- padding: 0;
158
- }
159
-
160
- #onboarding-header.compact {
161
- padding-bottom: 0;
162
- }
163
-
164
- #onboarding-content.compact {
165
- padding: 0;
166
- }
167
-
168
- #page-indicator.compact {
169
- padding: 0;
170
- }
171
-
172
- #buttons-container.compact {
173
- padding: 0;
174
- }
175
-
176
- #resource-sections.compact {
177
- padding: 0;
178
- }
179
-
180
- #resource-sections.compact Button {
181
- margin: 0 0 1 0;
182
- }
183
-
184
- #video-section.compact {
185
- margin: 0;
186
- }
187
-
188
- #docs-section.compact {
189
- margin: 1 0 0 0;
190
- }
191
-
192
- /* Tiny mode - hide full onboarding, show minimal message */
193
- OnboardingModal.tiny #onboarding-container {
194
- display: none;
195
- }
196
-
197
- OnboardingModal.tiny #tiny-screen-container {
198
- display: block;
199
- }
200
- """
201
-
202
- BINDINGS = [
203
- ("escape", "dismiss", "Close"),
204
- ("ctrl+c", "app.quit", "Quit"),
205
- ]
206
-
207
- def __init__(self) -> None:
208
- """Initialize the onboarding modal."""
209
- super().__init__()
210
- self.current_page = 0
211
- self.total_pages = 4
212
- self.page_titles = [
213
- "Getting Started",
214
- "Discovering the 5 Modes",
215
- "Prompting Better",
216
- "Context Management!",
217
- ]
218
- # Track which pages have been visited (in memory only)
219
- self.visited_pages: set[int] = {0} # Start on page 0, so it's visited
220
-
221
- def compose(self) -> ComposeResult:
222
- """Compose the onboarding modal."""
223
- # Tiny screen fallback - shown when terminal is too small
224
- with Container(id="tiny-screen-container"):
225
- yield Static(
226
- "Your screen is too small for the onboarding wizard.",
227
- id="tiny-screen-message",
228
- )
229
- yield Static(
230
- "[@click=screen.open_usage_guide]View usage instructions[/]",
231
- id="tiny-screen-link",
232
- markup=True,
233
- )
234
- yield Button("Start Shotgunning", id="tiny-close-button")
235
-
236
- # Full onboarding container
237
- with Container(id="onboarding-container"):
238
- # Left sidebar for progress tracking
239
- with Container(id="progress-sidebar"):
240
- yield Static("Progress", id="progress-header")
241
- for i in range(self.total_pages):
242
- yield Static(
243
- f"{i + 1}. {self.page_titles[i]}",
244
- id=f"progress-item-{i}",
245
- classes="progress-item",
246
- )
247
-
248
- # Main content area
249
- with Container(id="main-content"):
250
- yield Static("Welcome to Shotgun!", id="onboarding-header")
251
- with VerticalScroll(id="onboarding-content"):
252
- yield Markdown(id="page-content")
253
- # Resource sections (only shown on page 1)
254
- with Container(id="resource-sections"):
255
- yield Markdown(
256
- "### 🎥 Video Demo\nWatch our demo video to see Shotgun in action",
257
- id="video-section",
258
- )
259
- yield Button(
260
- "▶️ Watch Demo Video",
261
- id="youtube-button",
262
- variant="success",
263
- )
264
- yield Markdown(
265
- "### 📖 Documentation\nRead the comprehensive usage guide for detailed instructions",
266
- id="docs-section",
267
- )
268
- yield Button(
269
- "📚 Read Usage Guide", id="usage-button", variant="primary"
270
- )
271
- yield Static(id="page-indicator")
272
- with Container(id="buttons-container"):
273
- with Horizontal(id="navigation-buttons"):
274
- yield Button("Back", id="back-button", classes="nav-button")
275
- yield Button(
276
- "Next",
277
- id="next-button",
278
- classes="nav-button",
279
- variant="primary",
280
- )
281
- yield Button("Close", id="close-button", classes="nav-button")
282
-
283
- def on_mount(self) -> None:
284
- """Set up the modal after mounting."""
285
- self.update_page()
286
- # Apply layout based on terminal height
287
- self._apply_layout_for_height(self.app.size.height)
288
-
289
- @on(Resize)
290
- def handle_resize(self, event: Resize) -> None:
291
- """Adjust layout based on terminal height."""
292
- self._apply_layout_for_height(event.size.height)
293
-
294
- def _apply_layout_for_height(self, height: int) -> None:
295
- """Apply appropriate layout based on terminal height."""
296
- if height < TINY_HEIGHT_THRESHOLD:
297
- self.add_class("tiny")
298
- self.remove_class("compact")
299
- elif height < COMPACT_HEIGHT_THRESHOLD:
300
- self.remove_class("tiny")
301
- self._apply_compact_classes(True)
302
- else:
303
- self.remove_class("tiny")
304
- self._apply_compact_classes(False)
305
-
306
- def _apply_compact_classes(self, compact: bool) -> None:
307
- """Apply or remove compact layout classes."""
308
- container = self.query_one("#onboarding-container")
309
- sidebar = self.query_one("#progress-sidebar")
310
- header = self.query_one("#onboarding-header")
311
- content = self.query_one("#onboarding-content")
312
- page_indicator = self.query_one("#page-indicator")
313
- buttons_container = self.query_one("#buttons-container")
314
- resource_sections = self.query_one("#resource-sections")
315
- progress_items = self.query(".progress-item")
316
-
317
- if compact:
318
- container.add_class("compact")
319
- sidebar.add_class("compact")
320
- header.add_class("compact")
321
- content.add_class("compact")
322
- page_indicator.add_class("compact")
323
- buttons_container.add_class("compact")
324
- resource_sections.add_class("compact")
325
- for item in progress_items:
326
- item.add_class("compact")
327
- else:
328
- container.remove_class("compact")
329
- sidebar.remove_class("compact")
330
- header.remove_class("compact")
331
- content.remove_class("compact")
332
- page_indicator.remove_class("compact")
333
- buttons_container.remove_class("compact")
334
- resource_sections.remove_class("compact")
335
- for item in progress_items:
336
- item.remove_class("compact")
337
-
338
- def action_open_usage_guide(self) -> None:
339
- """Open the usage guide in browser."""
340
- webbrowser.open(
341
- "https://github.com/shotgun-sh/shotgun?tab=readme-ov-file#-usage"
342
- )
343
-
344
- def update_page(self) -> None:
345
- """Update the displayed page content and navigation buttons."""
346
- # Mark current page as visited
347
- self.visited_pages.add(self.current_page)
348
-
349
- # Update page content
350
- content_widget = self.query_one("#page-content", Markdown)
351
- content_widget.update(self.get_page_content())
352
-
353
- # Update page indicator
354
- page_indicator = self.query_one("#page-indicator", Static)
355
- page_indicator.update(f"Page {self.current_page + 1} of {self.total_pages}")
356
-
357
- # Update progress sidebar
358
- for i in range(self.total_pages):
359
- progress_item = self.query_one(f"#progress-item-{i}", Static)
360
- # Remove all progress classes first
361
- progress_item.remove_class(
362
- "progress-item-current",
363
- "progress-item-visited",
364
- "progress-item-unvisited",
365
- )
366
- # Add appropriate class
367
- if i == self.current_page:
368
- progress_item.add_class("progress-item-current")
369
- progress_item.update(f"▶ {i + 1}. {self.page_titles[i]}")
370
- elif i in self.visited_pages:
371
- progress_item.add_class("progress-item-visited")
372
- progress_item.update(f"✓ {i + 1}. {self.page_titles[i]}")
373
- else:
374
- progress_item.add_class("progress-item-unvisited")
375
- progress_item.update(f" {i + 1}. {self.page_titles[i]}")
376
-
377
- # Show/hide resource sections (only on page 1)
378
- resource_sections = self.query_one("#resource-sections", Container)
379
- resource_sections.display = self.current_page == 0
380
-
381
- # Update button visibility and states
382
- back_button = self.query_one("#back-button", Button)
383
- next_button = self.query_one("#next-button", Button)
384
-
385
- # Update back button label and state
386
- if self.current_page == 0:
387
- back_button.disabled = True
388
- back_button.label = "Back"
389
- else:
390
- back_button.disabled = False
391
- prev_title = self.page_titles[self.current_page - 1]
392
- back_button.label = f"← {prev_title}"
393
-
394
- # Update next button label
395
- if self.current_page == self.total_pages - 1:
396
- next_button.label = "Finish"
397
- else:
398
- next_title = self.page_titles[self.current_page + 1]
399
- next_button.label = f"{next_title} (Next →)"
400
-
401
- # Focus the appropriate button
402
- if self.current_page == 0:
403
- next_button.focus()
404
- else:
405
- next_button.focus()
406
-
407
- # Scroll content to top
408
- self.query_one("#onboarding-content", VerticalScroll).scroll_home(animate=False)
409
-
410
- def get_page_content(self) -> str:
411
- """Get the content for the current page."""
412
- if self.current_page == 0:
413
- return self._page_1_resources()
414
- elif self.current_page == 1:
415
- return self._page_2_modes()
416
- elif self.current_page == 2:
417
- return self._page_3_prompts()
418
- else:
419
- return self._page_4_context_management()
420
-
421
- def _page_1_resources(self) -> str:
422
- """Page 1: Helpful resources."""
423
- return """
424
- ## Getting Started Resources
425
-
426
- Here are some helpful resources to get you up to speed with Shotgun:
427
- """
428
-
429
- def _page_2_modes(self) -> str:
430
- """Page 2: Explanation of the Router and its modes."""
431
- return """
432
- ## Understanding Shotgun's Router
433
-
434
- Shotgun uses an intelligent **Router** that orchestrates your workflow automatically. Just describe what you need, and the Router will coordinate research, specifications, planning, and tasks for you.
435
-
436
- ### Two Operating Modes
437
-
438
- The Router operates in two modes, which you can toggle with `Shift+Tab`:
439
-
440
- ### 📋 Planning Mode (Default)
441
- - **Incremental execution**: Does one step at a time
442
- - **Asks clarifying questions** before complex tasks
443
- - **Shows plan for approval** before executing multi-step work
444
- - **Confirms before cascading** changes to dependent files
445
-
446
- Best for: Complex tasks, learning the workflow, staying in control
447
-
448
- ### ✍️ Drafting Mode
449
- - **Auto-executes** plans without stopping for approval
450
- - **Makes reasonable assumptions** instead of asking questions
451
- - **Updates all dependent files** automatically
452
-
453
- Best for: Routine tasks, experienced users, speed-focused work
454
-
455
- ---
456
-
457
- ### Files Created
458
-
459
- The Router manages these files in `.shotgun/`:
460
- - `research.md` - Research findings
461
- - `specification.md` - Detailed specifications
462
- - `plan.md` - Implementation plans
463
- - `tasks.md` - Actionable task lists
464
- - `exports/` - Documentation exports
465
-
466
- ---
467
-
468
- **Tip:** Press `Shift+Tab` to toggle between Planning and Drafting modes!
469
- """
470
-
471
- def _page_3_prompts(self) -> str:
472
- """Page 3: Tips for better prompts."""
473
- return """
474
- ## Writing Better Prompts
475
-
476
- Here are some tips to get the best results from Shotgun:
477
-
478
- ### 1. Ask for Research First
479
- Before jumping into a task, ask Shotgun to research the codebase or topic:
480
-
481
- > "Can you research how authentication works in this codebase?"
482
-
483
- ### 2. Request Clarifying Questions
484
- Let Shotgun ask you questions to better understand your needs:
485
-
486
- > "I want to add user profiles. Please ask me clarifying questions before starting."
487
-
488
- ### 3. Be Specific About Context
489
- Provide relevant context about what you're trying to accomplish:
490
-
491
- > "I'm working on the payment flow. I need to add support for refunds."
492
-
493
- ### 4. Let the Router Guide You
494
- The Router will automatically coordinate the right workflow:
495
- - Describe what you want to accomplish
496
- - In Planning mode, it will ask clarifying questions first
497
- - In Drafting mode, it will execute immediately
498
-
499
- ---
500
-
501
- **Remember:** Shotgun works best when you give it context and let it ask questions!
502
- """
503
-
504
- def _page_4_context_management(self) -> str:
505
- """Page 4: Context management and conversation controls."""
506
- return """
507
- ## Managing Conversation Context
508
-
509
- As conversations grow, you may need to manage the context sent to the AI model.
510
-
511
- ### Clear Conversation
512
- Completely start over with a fresh conversation.
513
-
514
- **How to use:**
515
- - Open Command Palette: `Ctrl+P`
516
- - Type: "Clear Conversation"
517
- - Confirm the action
518
-
519
- **When to use:**
520
- - Starting a completely new task or project
521
- - When you want a clean slate
522
- - Context has become too cluttered
523
-
524
- ---
525
-
526
- ### Compact Conversation
527
- Intelligently compress the conversation history while preserving important context.
528
-
529
- **How to use:**
530
- - Open Command Palette: `Ctrl+P`
531
- - Type: "Compact Conversation"
532
- - Shotgun will compress older messages automatically
533
-
534
- **When to use:**
535
- - Conversation is getting long but you want to keep context
536
- - Running into token limits
537
- - Want to reduce costs while maintaining continuity
538
-
539
- **What it does:**
540
- - Summarizes older messages
541
- - Keeps recent messages intact
542
- - Preserves key information and decisions
543
-
544
- ---
545
-
546
- **Tip:** Use `Ctrl+U` to view your current usage and see how much context you're using!
547
- """
548
-
549
- @on(Button.Pressed, "#back-button")
550
- def handle_back(self) -> None:
551
- """Handle back button press."""
552
- if self.current_page > 0:
553
- self.current_page -= 1
554
- self.update_page()
555
-
556
- @on(Button.Pressed, "#next-button")
557
- def handle_next(self) -> None:
558
- """Handle next/finish button press."""
559
- if self.current_page < self.total_pages - 1:
560
- self.current_page += 1
561
- self.update_page()
562
- else:
563
- # On last page, finish closes the modal
564
- self.dismiss()
565
-
566
- @on(Button.Pressed, "#close-button")
567
- @on(Button.Pressed, "#tiny-close-button")
568
- def handle_close(self) -> None:
569
- """Handle close button press."""
570
- self.dismiss()
571
-
572
- @on(Button.Pressed, "#youtube-button")
573
- def handle_youtube(self) -> None:
574
- """Open demo section in README."""
575
- webbrowser.open(
576
- "https://github.com/shotgun-sh/shotgun?tab=readme-ov-file#-demo"
577
- )
578
-
579
- @on(Button.Pressed, "#usage-button")
580
- def handle_usage_guide(self) -> None:
581
- """Open usage guide in browser."""
582
- webbrowser.open(
583
- "https://github.com/shotgun-sh/shotgun?tab=readme-ov-file#-usage"
584
- )