shotgun-sh 0.1.0.dev12__py3-none-any.whl → 0.1.0.dev14__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of shotgun-sh might be problematic. Click here for more details.

Files changed (73) hide show
  1. shotgun/agents/agent_manager.py +16 -3
  2. shotgun/agents/artifact_state.py +58 -0
  3. shotgun/agents/common.py +137 -88
  4. shotgun/agents/config/constants.py +18 -0
  5. shotgun/agents/config/manager.py +68 -16
  6. shotgun/agents/config/models.py +61 -0
  7. shotgun/agents/config/provider.py +11 -6
  8. shotgun/agents/history/compaction.py +85 -0
  9. shotgun/agents/history/constants.py +19 -0
  10. shotgun/agents/history/context_extraction.py +108 -0
  11. shotgun/agents/history/history_building.py +104 -0
  12. shotgun/agents/history/history_processors.py +354 -157
  13. shotgun/agents/history/message_utils.py +46 -0
  14. shotgun/agents/history/token_counting.py +429 -0
  15. shotgun/agents/history/token_estimation.py +138 -0
  16. shotgun/agents/models.py +131 -1
  17. shotgun/agents/plan.py +15 -37
  18. shotgun/agents/research.py +10 -45
  19. shotgun/agents/specify.py +97 -0
  20. shotgun/agents/tasks.py +7 -36
  21. shotgun/agents/tools/artifact_management.py +482 -0
  22. shotgun/agents/tools/file_management.py +31 -12
  23. shotgun/agents/tools/web_search/anthropic.py +78 -17
  24. shotgun/agents/tools/web_search/gemini.py +1 -1
  25. shotgun/agents/tools/web_search/openai.py +16 -2
  26. shotgun/artifacts/__init__.py +17 -0
  27. shotgun/artifacts/exceptions.py +89 -0
  28. shotgun/artifacts/manager.py +530 -0
  29. shotgun/artifacts/models.py +334 -0
  30. shotgun/artifacts/service.py +463 -0
  31. shotgun/artifacts/templates/__init__.py +10 -0
  32. shotgun/artifacts/templates/loader.py +252 -0
  33. shotgun/artifacts/templates/models.py +136 -0
  34. shotgun/artifacts/templates/plan/delivery_and_release_plan.yaml +66 -0
  35. shotgun/artifacts/templates/research/market_research.yaml +585 -0
  36. shotgun/artifacts/templates/research/sdk_comparison.yaml +257 -0
  37. shotgun/artifacts/templates/specify/prd.yaml +331 -0
  38. shotgun/artifacts/templates/specify/product_spec.yaml +301 -0
  39. shotgun/artifacts/utils.py +76 -0
  40. shotgun/cli/plan.py +1 -4
  41. shotgun/cli/specify.py +69 -0
  42. shotgun/cli/tasks.py +0 -4
  43. shotgun/codebase/core/nl_query.py +4 -4
  44. shotgun/logging_config.py +23 -7
  45. shotgun/main.py +7 -6
  46. shotgun/prompts/agents/partials/artifact_system.j2 +35 -0
  47. shotgun/prompts/agents/partials/codebase_understanding.j2 +1 -2
  48. shotgun/prompts/agents/partials/common_agent_system_prompt.j2 +28 -2
  49. shotgun/prompts/agents/partials/content_formatting.j2 +65 -0
  50. shotgun/prompts/agents/partials/interactive_mode.j2 +10 -2
  51. shotgun/prompts/agents/plan.j2 +33 -32
  52. shotgun/prompts/agents/research.j2 +39 -29
  53. shotgun/prompts/agents/specify.j2 +32 -0
  54. shotgun/prompts/agents/state/artifact_templates_available.j2 +18 -0
  55. shotgun/prompts/agents/state/codebase/codebase_graphs_available.j2 +3 -1
  56. shotgun/prompts/agents/state/existing_artifacts_available.j2 +23 -0
  57. shotgun/prompts/agents/state/system_state.j2 +9 -1
  58. shotgun/prompts/agents/tasks.j2 +27 -12
  59. shotgun/prompts/history/incremental_summarization.j2 +53 -0
  60. shotgun/sdk/artifact_models.py +186 -0
  61. shotgun/sdk/artifacts.py +448 -0
  62. shotgun/sdk/services.py +14 -0
  63. shotgun/tui/app.py +26 -7
  64. shotgun/tui/screens/chat.py +32 -5
  65. shotgun/tui/screens/directory_setup.py +113 -0
  66. shotgun/utils/file_system_utils.py +6 -1
  67. {shotgun_sh-0.1.0.dev12.dist-info → shotgun_sh-0.1.0.dev14.dist-info}/METADATA +3 -2
  68. shotgun_sh-0.1.0.dev14.dist-info/RECORD +138 -0
  69. shotgun/prompts/user/research.j2 +0 -5
  70. shotgun_sh-0.1.0.dev12.dist-info/RECORD +0 -104
  71. {shotgun_sh-0.1.0.dev12.dist-info → shotgun_sh-0.1.0.dev14.dist-info}/WHEEL +0 -0
  72. {shotgun_sh-0.1.0.dev12.dist-info → shotgun_sh-0.1.0.dev14.dist-info}/entry_points.txt +0 -0
  73. {shotgun_sh-0.1.0.dev12.dist-info → shotgun_sh-0.1.0.dev14.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,301 @@
1
+ name: Product Specification Template
2
+ purpose: Use this to template to build a product specification for the user's product.
3
+ prompt: |
4
+ First, suggest creating a product.overview section. Then, once the user reviews, move on to the next sections.
5
+ Include a technology architecture blueprint that defines boundaries, responsibilities, and quality goals for the product. The system enables end users to perform core workflows reliably and securely while supporting iterative evolution.
6
+ Prioritize features by user value × business value to maximize the ROI.
7
+ Facilitate ideation & discovery: Divergent thinking before convergence
8
+ Fill blanks creatively if the user lacks detail: Momentum over paralysis
9
+ Your focus needs to be on creating clear, actionable product artifacts that development teams can use.
10
+ If user provides detailed description with problem, solution, target users, acknowledge and get to work OR ask for more details if critical details are truly missing.
11
+ Try to suggest next steps for the user in their product definition journey.
12
+ sections:
13
+ product.overview:
14
+ instructions: |
15
+ # A good product.overview:
16
+ • Inspires action
17
+ • Focuses on a real pain for real users
18
+ • Aligns the team on desired outcomes
19
+ * Is complete and comprehensive
20
+
21
+ # Questions to ask yourself:
22
+ • What would success headlines say 12 months after launch?
23
+ • What user behavior or workflow do we want to eliminate or unlock?
24
+ * Is there anything else, specific to the product, that we should include?
25
+
26
+ # Includes:
27
+ Product Vision: [One punchy sentence that inspires; problem + aspirational outcome]
28
+ Problem Statement:
29
+ Who hurts? [Persona or segment]
30
+ Pain intensity? [Metric / qualitative quote]
31
+ Existing workaround? [Current solution]
32
+ [additional relevant information]
33
+
34
+ # Goals & Success Metrics:
35
+
36
+ | Goal | KPI | Target |
37
+ |------|-----|--------|
38
+ | Reduce payroll processing time | Avg. run time | < 5 min |
39
+ | Increase retention | NPS | > 60 |
40
+ [more like that]
41
+ product.user_personas:
42
+ instructions: |
43
+ # How to write a good product.user_personas section
44
+
45
+ Capture the motivations, frustrations, and context of your target users.
46
+
47
+ • Makes the user feel real to the team
48
+ • Communicates job context and emotional stakes
49
+ • Informs tradeoffs during prioritization
50
+
51
+ # Questions to ask yourself:
52
+ • What would frustrate this person about our current plan?
53
+ • What would success feel like in their words?
54
+
55
+ Each persona should have their own Emoji you'll use throughout the product specification.
56
+
57
+ # Includes:
58
+ Name / Archetype: [Short, memorable]
59
+ Role & Demographics: [Job, age, environment]
60
+ Goals:
61
+ - [Primary job‑to‑be‑done]
62
+ - [Secondary]
63
+ Frustrations / Pain Points:
64
+ - [Top pain]
65
+ - [Tech constraints]
66
+ Success Definition: “[Quote in their words]”
67
+ depends_on:
68
+ - "product.overview"
69
+ product.user_stories:
70
+ instructions: |
71
+ Create a concise set of INVEST-compliant user stories, each with clear acceptance criteria using the **Given / When / Then** pattern.
72
+
73
+ # Voice & Style
74
+ Professional, direct, and unambiguous. Avoid marketing fluff and technical implementation details.
75
+
76
+ # How to write a good product.user_stories section
77
+
78
+ • Is short, clear, and framed around user benefit
79
+ • Has testable, concrete acceptance criteria
80
+ • Maps to a real persona and real-world situation
81
+ * Comprehensively cover the whole system
82
+ * They cover all personas already defined in the product.personas section (do not create new personas here)
83
+
84
+ # Questions to ask yourself:
85
+ • Could the team design/build this without ambiguity?
86
+ • Is this too big? Can it be split?
87
+
88
+ # Key Principles to Apply
89
+ - **User story format:** "As a \<role>, I want \<goal> so that \<benefit>."
90
+ - **INVEST:** Independent, Negotiable, Valuable, Estimable, Small, Testable.
91
+ - **3 Cs:**
92
+ - **Card:** Concise statement
93
+ - **Conversation:** Brief elaboration if needed
94
+ - **Confirmation:** Acceptance criteria clearly defined
95
+ - **Do’s:** User-centric, outcome-oriented, sprint-sized, measurable value.
96
+ - **Don’ts:** No UI specifics, vague benefits, or bundled epics.
97
+ - ALWAYS include at least one acceptance criteria for each user story.
98
+ - ALWAYS assign the story a JIRA-like ID that we can later refer to easily. Format prefix should come from the product name or EPIC.
99
+
100
+ Write key parts of user stories in **bold**.
101
+
102
+ # Context Sensitivity
103
+ - **Startup Context:** Allow lighter processes and faster iteration.
104
+ - **Enterprise Context:** Include 1–2 "Enabler" stories for compliance, performance, and note dependencies explicitly.
105
+
106
+
107
+ # (Optional) Enabler / Technical Stories
108
+
109
+ - As a developer…, I want… so that…
110
+ depends_on:
111
+ - "product.user_personas"
112
+
113
+ product.user_journeys:
114
+ instructions: |
115
+ # How to write a good product.user_journeys section
116
+
117
+ Visually maps the end-to-end experience from the user's perspective, highlighting actions, thoughts, and feelings.
118
+ • Tells a Story: It should have a clear beginning, middle, and end, following a specific user and scenario. • Reveals Pain & Opportunity: Clearly identifies moments of frustration (pain points) and moments of delight. • Holistic View: Captures touchpoints both inside and outside the product (e.g., receiving an email notification). • Uses Mermaid: Creates a clean, easy-to-read visual diagram of the journey.
119
+ Questions to ask yourself:
120
+ • What happens before the user opens our app and after they close it? • Where is the emotional low point of this journey? How can we fix it? • What is the "happy path," and what are the most common deviations?
121
+
122
+ # Includes:
123
+ * A Mermaid diagram for each key persona or critical task.
124
+ * Title: A clear, descriptive title for the journey (e.g., "Journey of a New User Onboarding").
125
+ * Sections: Logical phases of the journey (e.g., Awareness, Consideration, Purchase, Onboarding, Regular Use).
126
+ * Tasks: Specific actions the user takes, assigned to a persona.
127
+ * Sentiment Score: A rating (e.g., 1-5) to show the user's emotional state at each step.
128
+ * Include a description of the journey in the section content. Make important things in **bold**.
129
+
130
+ # Diagram example
131
+
132
+ IMPORTANT: DO NOT use semicolons in the content.
133
+
134
+ ```mermaid
135
+ journey
136
+ title My working day
137
+ section Go to work
138
+ Make tea: 5: Me
139
+ Go upstairs: 3: Me
140
+ Do work: 1: Me, Cat
141
+ section Go home
142
+ Go downstairs: 5: Me
143
+ Sit down: 5: Me
144
+ ```
145
+
146
+ depends_on:
147
+ - "product.user_stories"
148
+
149
+ product.features:
150
+ instructions: |
151
+ # How to write a good product.features section
152
+
153
+ Detailed specification of product capabilities. Tied directly to user needs and business outcomes.
154
+
155
+ • Explains why the feature matters (not just what it does)
156
+ • Specifies functional and non-functional behavior
157
+ • Clarifies edge cases and constraints
158
+
159
+ # Questions to ask yourself:
160
+ • What would make a developer or designer fail to implement this right?
161
+ • What are the failure modes or critical risks?
162
+
163
+ # Includes:
164
+ Feature: **[Name]**
165
+ Objective: **[Problem it solves]**
166
+ User Benefit: **[Why user cares]**
167
+ Detailed Requirements:
168
+ - **[Functional spec]**
169
+ - **[Performance spec]**
170
+ Non‑Functional:
171
+ - Security: **[e.g., SOC 2 compliance]**
172
+ - Localization: **[e.g., EN/ES at launch]**
173
+ depends_on:
174
+ - "product.user_stories"
175
+
176
+ product.roadmap:
177
+ instructions: |
178
+ # How to write a good product.roadmap section?
179
+
180
+ Defines the sequence of what gets built when — and why.
181
+
182
+ • Shows clear strategic themes
183
+ • Communicates tradeoffs and intent
184
+ • Helps stakeholders set expectations
185
+
186
+ # Questions to ask yourself:
187
+ • What themes are we prioritizing this quarter and why?
188
+ • What’s realistic to deliver given team velocity?
189
+
190
+ # Includes:
191
+ Quarter
192
+ Theme
193
+ Initiatives
194
+ Mermaid Gantt diagram
195
+
196
+ # Diagram example (syntax)
197
+
198
+ ```mermaid
199
+ gantt
200
+ dateFormat YYYY-MM-DD
201
+ title Adding GANTT diagram functionality to mermaid
202
+ excludes weekends
203
+ %% (`excludes` accepts specific dates in YYYY-MM-DD format, days of the week ("sunday") or "weekends", but not the word "weekdays".)
204
+
205
+ section A section
206
+ Completed task :done, des1, 2014-01-06,2014-01-08
207
+ Active task :active, des2, 2014-01-09, 3d
208
+ Future task : des3, after des2, 5d
209
+ Future task2 : des4, after des3, 5d
210
+
211
+ section Critical tasks
212
+ Completed task in the critical line :crit, done, 2014-01-06,24h
213
+ Implement parser and jison :crit, done, after des1, 2d
214
+ Create tests for parser :crit, active, 3d
215
+ Future task in critical line :crit, 5d
216
+ Create tests for renderer :2d
217
+ Add to mermaid :until isadded
218
+ Functionality added :milestone, isadded, 2014-01-25, 0d
219
+
220
+ section Documentation
221
+ Describe gantt syntax :active, a1, after des1, 3d
222
+ Add gantt diagram to demo page :after a1 , 20h
223
+ Add another diagram to demo page :doc1, after a1 , 48h
224
+
225
+ section Last section
226
+ Describe gantt syntax :after doc1, 3d
227
+ Add gantt diagram to demo page :20h
228
+ Add another diagram to demo page :48h
229
+ ```
230
+
231
+ architecture.overview:
232
+ instructions: |
233
+ # A good architecture_overview:
234
+ • Establishes scope, purpose, high‑level constraints
235
+ • Gives a north‑star vision for future evolution
236
+
237
+ # Ask yourself:
238
+ • What external systems/actors touch us?
239
+ • Which constraints shape every other decision (regulations, runtime, budget)?
240
+
241
+ # Includes:
242
+ • System Purpose – 1‑sentence mission
243
+ • Context Diagram – Mermaid
244
+ • Key Constraints – Regs, legacy ties, SLAs
245
+
246
+ depends_on:
247
+ - "product.features"
248
+
249
+ architecture.key_components:
250
+ instructions: |
251
+ This section should include all key components and their relationships.
252
+
253
+ Include diagrams on how they interact and dependencies.
254
+
255
+ depends_on:
256
+ - "architecture.overview"
257
+
258
+ architecture.quality_attributes:
259
+ instructions: |
260
+ # Example of a good architecture_quality_attributes section
261
+
262
+ Attribute Metric Target Design Strategies
263
+ Performance P99 latency < 200 ms Async queue, in‑memory cache
264
+ Scalability Sustained RPS 5 k Stateless services + HPA
265
+ Security OWASP Top 10 0 critical vulns CSP, parameterized SQL
266
+
267
+ Use measurable targets and map to architectural mechanisms.
268
+
269
+ depends_on:
270
+ - "architecture.key_components"
271
+
272
+ architecture.cross_cutting_concerns:
273
+ instructions: |
274
+ Capture reusable patterns/services (e.g., centralized logging stack, OAuth provider, feature flags).
275
+ State ownership and SLOs so ops knows who to page.
276
+
277
+ depends_on:
278
+ - "architecture.key_components"
279
+ - "architecture.quality_attributes"
280
+
281
+ architecture.tech_stack_requirements:
282
+ instructions: |
283
+ Next up, we will engage tech research agent to find the best tech stack for the project.
284
+ Outline key elements of the stack so they can focus on finding the best option for each element in terms of programming language, frameworks, libraries, databases, etc.
285
+ depends_on:
286
+ - "architecture.cross_cutting_concerns"
287
+ - "architecture.quality_attributes"
288
+ - "architecture.key_components"
289
+
290
+ architecture.tech_stack_decisions:
291
+ instructions: |
292
+ # Example of a good architecture_tech_stack_decisions section
293
+
294
+ Include a summary of the tech stack decisions and why they were made.
295
+
296
+ depends_on:
297
+ - "architecture.tech_stack_requirements"
298
+ - "architecture.cross_cutting_concerns"
299
+ - "architecture.quality_attributes"
300
+ - "architecture.key_components"
301
+ - "architecture.overview"
@@ -0,0 +1,76 @@
1
+ """Utilities for artifact system."""
2
+
3
+ from .models import AgentMode
4
+
5
+ # Error message templates
6
+ INVALID_AGENT_MODE_MSG = (
7
+ "Invalid agent mode '{mode}'. Valid modes: research, plan, tasks, specify"
8
+ )
9
+ VALIDATION_ERROR_MSG = "Validation error: {error}"
10
+
11
+ # Valid modes list for error messages
12
+ VALID_AGENT_MODES = ["research", "plan", "tasks", "specify"]
13
+
14
+
15
+ def parse_agent_mode_string(mode_str: str) -> AgentMode:
16
+ """Parse agent mode string to AgentMode enum.
17
+
18
+ Args:
19
+ mode_str: String representation of agent mode
20
+
21
+ Returns:
22
+ AgentMode enum value
23
+
24
+ Raises:
25
+ ValueError: If mode_str is not a valid agent mode
26
+ """
27
+ try:
28
+ return AgentMode(mode_str.lower())
29
+ except ValueError as e:
30
+ if "not a valid enumeration member" in str(e):
31
+ raise ValueError(INVALID_AGENT_MODE_MSG.format(mode=mode_str)) from e
32
+ raise ValueError(VALIDATION_ERROR_MSG.format(error=str(e))) from e
33
+
34
+
35
+ def generate_artifact_name(artifact_id: str) -> str:
36
+ """Generate human-readable name from artifact ID.
37
+
38
+ Args:
39
+ artifact_id: Artifact identifier (slug format)
40
+
41
+ Returns:
42
+ Human-readable name
43
+ """
44
+ return artifact_id.replace("-", " ").title()
45
+
46
+
47
+ def format_agent_error_message(agent_mode: str, error: Exception) -> str:
48
+ """Format error message for agent tools.
49
+
50
+ Args:
51
+ agent_mode: Agent mode string that caused the error
52
+ error: The exception that occurred
53
+
54
+ Returns:
55
+ Formatted error message
56
+ """
57
+ if "not a valid enumeration member" in str(error):
58
+ return INVALID_AGENT_MODE_MSG.format(mode=agent_mode)
59
+ else:
60
+ return VALIDATION_ERROR_MSG.format(error=str(error))
61
+
62
+
63
+ def handle_agent_mode_parsing(agent_mode: str) -> tuple[AgentMode | None, str | None]:
64
+ """Handle agent mode parsing with error handling.
65
+
66
+ Args:
67
+ agent_mode: Agent mode string to parse
68
+
69
+ Returns:
70
+ Tuple of (parsed_mode, error_message). If parsing succeeds,
71
+ error_message is None. If parsing fails, parsed_mode is None.
72
+ """
73
+ try:
74
+ return parse_agent_mode_string(agent_mode), None
75
+ except ValueError as e:
76
+ return None, str(e)
shotgun/cli/plan.py CHANGED
@@ -7,7 +7,7 @@ import typer
7
7
 
8
8
  from shotgun.agents.config import ProviderType
9
9
  from shotgun.agents.models import AgentRuntimeOptions
10
- from shotgun.agents.plan import create_plan_agent, get_plan_history, run_plan_agent
10
+ from shotgun.agents.plan import create_plan_agent, run_plan_agent
11
11
  from shotgun.logging_config import get_logger
12
12
 
13
13
  app = typer.Typer(name="plan", help="Generate structured plans", no_args_is_help=True)
@@ -65,9 +65,6 @@ def plan(
65
65
  logger.info("✅ Planning Complete!")
66
66
  logger.info("📋 Results:")
67
67
  logger.info("%s", result.output)
68
- logger.info("📄 Plan saved to: .shotgun/plan.md")
69
- logger.debug("📚 Current plan:")
70
- logger.debug("%s", get_plan_history())
71
68
 
72
69
  except Exception as e:
73
70
  logger.error("❌ Error during planning: %s", str(e))
shotgun/cli/specify.py ADDED
@@ -0,0 +1,69 @@
1
+ """Specify command for shotgun CLI."""
2
+
3
+ import asyncio
4
+ from typing import Annotated
5
+
6
+ import typer
7
+
8
+ from shotgun.agents.config import ProviderType
9
+ from shotgun.agents.models import AgentRuntimeOptions
10
+ from shotgun.agents.specify import (
11
+ create_specify_agent,
12
+ run_specify_agent,
13
+ )
14
+ from shotgun.logging_config import get_logger
15
+
16
+ app = typer.Typer(
17
+ name="specify", help="Generate comprehensive specifications", no_args_is_help=True
18
+ )
19
+ logger = get_logger(__name__)
20
+
21
+
22
+ @app.callback(invoke_without_command=True)
23
+ def specify(
24
+ requirement: Annotated[
25
+ str, typer.Argument(help="Requirement or feature to specify")
26
+ ],
27
+ non_interactive: Annotated[
28
+ bool,
29
+ typer.Option(
30
+ "--non-interactive", "-n", help="Disable user interaction (for CI/CD)"
31
+ ),
32
+ ] = False,
33
+ provider: Annotated[
34
+ ProviderType | None,
35
+ typer.Option("--provider", "-p", help="AI provider to use (overrides default)"),
36
+ ] = None,
37
+ ) -> None:
38
+ """Generate comprehensive specifications for software features and systems.
39
+
40
+ This command creates detailed technical specifications including requirements,
41
+ architecture, implementation details, and acceptance criteria based on your
42
+ provided requirement or feature description.
43
+ """
44
+
45
+ logger.info("📝 Specification Requirement: %s", requirement)
46
+
47
+ try:
48
+ # Create agent dependencies
49
+ agent_runtime_options = AgentRuntimeOptions(
50
+ interactive_mode=not non_interactive
51
+ )
52
+
53
+ # Create the specify agent with deps and provider
54
+ agent, deps = create_specify_agent(agent_runtime_options, provider)
55
+
56
+ # Start specification process
57
+ logger.info("📋 Starting specification generation...")
58
+ result = asyncio.run(run_specify_agent(agent, requirement, deps))
59
+
60
+ # Display results
61
+ logger.info("✅ Specification Complete!")
62
+ logger.info("📋 Results:")
63
+ logger.info("%s", result.output)
64
+
65
+ except Exception as e:
66
+ logger.error("❌ Error during specification: %s", str(e))
67
+ import traceback
68
+
69
+ logger.debug("Full traceback:\n%s", traceback.format_exc())
shotgun/cli/tasks.py CHANGED
@@ -9,7 +9,6 @@ from shotgun.agents.config import ProviderType
9
9
  from shotgun.agents.models import AgentRuntimeOptions
10
10
  from shotgun.agents.tasks import (
11
11
  create_tasks_agent,
12
- get_tasks_history,
13
12
  run_tasks_agent,
14
13
  )
15
14
  from shotgun.logging_config import get_logger
@@ -71,9 +70,6 @@ def tasks(
71
70
  logger.info("✅ Task Creation Complete!")
72
71
  logger.info("📋 Results:")
73
72
  logger.info("%s", result.output)
74
- logger.info("📄 Tasks saved to: .shotgun/tasks.md")
75
- logger.debug("📚 Current tasks:")
76
- logger.debug("%s", get_tasks_history())
77
73
 
78
74
  except Exception as e:
79
75
  logger.error("❌ Error during task creation: %s", str(e))
@@ -4,7 +4,6 @@ import time
4
4
  from datetime import datetime
5
5
  from typing import TYPE_CHECKING
6
6
 
7
- from pydantic_ai.direct import model_request
8
7
  from pydantic_ai.messages import (
9
8
  ModelRequest,
10
9
  SystemPromptPart,
@@ -13,6 +12,7 @@ from pydantic_ai.messages import (
13
12
  )
14
13
 
15
14
  from shotgun.agents.config import get_provider_model
15
+ from shotgun.agents.config.models import shotgun_model_request
16
16
  from shotgun.logging_config import get_logger
17
17
  from shotgun.prompts import PromptLoader
18
18
 
@@ -35,9 +35,9 @@ async def llm_cypher_prompt(system_prompt: str, user_prompt: str) -> str:
35
35
  The generated Cypher query as a string
36
36
  """
37
37
  model_config = get_provider_model()
38
- # Use the Model instance directly (has API key baked in)
39
- query_cypher_response = await model_request(
40
- model=model_config.model_instance,
38
+ # Use shotgun wrapper to maximize response quality for codebase queries
39
+ query_cypher_response = await shotgun_model_request(
40
+ model_config=model_config,
41
41
  messages=[
42
42
  ModelRequest(
43
43
  parts=[
shotgun/logging_config.py CHANGED
@@ -65,14 +65,20 @@ def setup_logger(
65
65
  """
66
66
  logger = logging.getLogger(name)
67
67
 
68
- # Avoid adding duplicate handlers
69
- if logger.handlers:
68
+ # Check if we already have a file handler
69
+ has_file_handler = any(
70
+ isinstance(h, logging.handlers.TimedRotatingFileHandler)
71
+ for h in logger.handlers
72
+ )
73
+
74
+ # If we already have a file handler, just return the logger
75
+ if has_file_handler:
70
76
  return logger
71
77
 
72
- # Get log level from environment variable, default to ERROR
73
- env_level = os.getenv("SHOTGUN_LOG_LEVEL", "ERROR").upper()
78
+ # Get log level from environment variable, default to INFO
79
+ env_level = os.getenv("SHOTGUN_LOG_LEVEL", "INFO").upper()
74
80
  if env_level not in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]:
75
- env_level = "ERROR"
81
+ env_level = "INFO"
76
82
 
77
83
  logger.setLevel(getattr(logging, env_level))
78
84
 
@@ -163,8 +169,14 @@ def get_logger(name: str) -> logging.Logger:
163
169
  """
164
170
  logger = logging.getLogger(name)
165
171
 
166
- # If logger doesn't have handlers, set it up
167
- if not logger.handlers:
172
+ # Check if we have a file handler already
173
+ has_file_handler = any(
174
+ isinstance(h, logging.handlers.TimedRotatingFileHandler)
175
+ for h in logger.handlers
176
+ )
177
+
178
+ # If no file handler, set up the logger (will add file handler)
179
+ if not has_file_handler:
168
180
  return setup_logger(name)
169
181
 
170
182
  return logger
@@ -187,4 +199,8 @@ def set_global_log_level(level: str) -> None:
187
199
 
188
200
  def configure_root_logger() -> None:
189
201
  """Configure the root shotgun logger."""
202
+ # Always set up the root logger to ensure file handler is added
190
203
  setup_logger("shotgun")
204
+
205
+ # Also ensure main module gets configured
206
+ setup_logger("__main__")
shotgun/main.py CHANGED
@@ -7,7 +7,7 @@ from dotenv import load_dotenv
7
7
 
8
8
  from shotgun import __version__
9
9
  from shotgun.agents.config import get_config_manager
10
- from shotgun.cli import codebase, config, plan, research, tasks, update
10
+ from shotgun.cli import codebase, config, plan, research, specify, tasks, update
11
11
  from shotgun.logging_config import configure_root_logger, get_logger
12
12
  from shotgun.posthog_telemetry import setup_posthog_observability
13
13
  from shotgun.sentry_telemetry import setup_sentry_observability
@@ -18,9 +18,13 @@ from shotgun.utils.update_checker import check_for_updates_async
18
18
  # Load environment variables from .env file
19
19
  load_dotenv()
20
20
 
21
- # Initialize logging
21
+ # Initialize telemetry FIRST (before logging setup to prevent handler conflicts)
22
+ _logfire_enabled = setup_logfire_observability()
23
+
24
+ # Initialize logging AFTER telemetry
22
25
  configure_root_logger()
23
26
  logger = get_logger(__name__)
27
+ logger.debug("Logfire observability enabled: %s", _logfire_enabled)
24
28
 
25
29
  # Initialize configuration
26
30
  try:
@@ -29,10 +33,6 @@ try:
29
33
  except Exception as e:
30
34
  logger.debug("Configuration initialization warning: %s", e)
31
35
 
32
- # Initialize telemetry
33
- _logfire_enabled = setup_logfire_observability()
34
- logger.debug("Logfire observability enabled: %s", _logfire_enabled)
35
-
36
36
  # Initialize Sentry telemetry
37
37
  _sentry_enabled = setup_sentry_observability()
38
38
  logger.debug("Sentry observability enabled: %s", _sentry_enabled)
@@ -64,6 +64,7 @@ app.add_typer(
64
64
  )
65
65
  app.add_typer(research.app, name="research", help="Perform research with agentic loops")
66
66
  app.add_typer(plan.app, name="plan", help="Generate structured plans")
67
+ app.add_typer(specify.app, name="specify", help="Generate comprehensive specifications")
67
68
  app.add_typer(tasks.app, name="tasks", help="Generate task lists with agentic approach")
68
69
  app.add_typer(update.app, name="update", help="Check for and install updates")
69
70
 
@@ -0,0 +1,35 @@
1
+ ## ARTIFACT SYSTEM
2
+
3
+ You have access to a structured artifact system for organizing your work. Use artifacts instead of flat files for better organization.
4
+
5
+ ### Available Artifact Tools:
6
+ - `list_artifacts(agent_mode)`: List existing artifacts for an agent mode ("research", "plan", "tasks", "specify")
7
+ - `read_artifact(artifact_id, agent_mode)`: Read all sections of an artifact
8
+ - `read_artifact_section(artifact_id, agent_mode, section_number)`: Read specific section
9
+ - `write_artifact_section(artifact_id, agent_mode, section_number, section_slug, section_title, content)`: Create/update section
10
+
11
+ ### Artifact Structure:
12
+ - **Artifact ID**: Meaningful slug (e.g., "api-design-patterns", "mvp-roadmap")
13
+ - **Sections**: Numbered sections with descriptive slugs and titles
14
+ - **Organization**: `.shotgun/{agent_mode}/{artifact_id}/{section_number}-{section_slug}.md`
15
+
16
+ ### Best Practices:
17
+ - Always start by checking existing artifacts with `list_artifacts()`
18
+ - Use meaningful artifact IDs that describe the work
19
+ - Organize content into logical sections (overview, analysis, recommendations, etc.)
20
+ - Use descriptive section titles and slugs
21
+ - Build upon existing work rather than starting from scratch
22
+
23
+
24
+ ## ARTIFACT TEMPLATES
25
+
26
+ Use artifact templates to help you create new artifacts.
27
+
28
+ MOST IMPORTANT: WHEN YOU CREATE AN ARTIFACT FROM A TEMPLATE, ALWAYS RESPECT AND FOLLOW THE "INSTRUCTIONS" AND "PROMPT" CONTAINED IN THE TEMPLATE TO THE LETTER.
29
+
30
+ Use `list_artifact_templates(agent_mode)` to see what templates are available.
31
+
32
+ Use `create_artifact(artifact_id, agent_mode, name, template_id)` to create a new artifact with a template.
33
+
34
+ Template ID example: "research/market_research"
35
+
@@ -1,4 +1,3 @@
1
- {% if codebase_understanding_graphs -%}
2
1
  **Graph Tools Available**:
3
2
  - `query_graph` - Query this graph using natural language
4
3
  - `retrieve_code` - Get source code by qualified name (e.g., "module.Class.method")
@@ -76,4 +75,4 @@ If the task you received is about codebase management, follow the codebase manag
76
75
  - If "entity not found", try alternative names or explore the file system
77
76
  - If "graph not found", verify the exact graph name with `list_graphs()`
78
77
  - Report errors clearly and try alternative approaches
79
- {% endif %}
78
+