shotgun-sh 0.1.0.dev20__py3-none-any.whl → 0.1.0.dev23__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 (60) hide show
  1. shotgun/agents/agent_manager.py +100 -16
  2. shotgun/agents/common.py +142 -28
  3. shotgun/agents/conversation_history.py +56 -0
  4. shotgun/agents/conversation_manager.py +105 -0
  5. shotgun/agents/export.py +5 -2
  6. shotgun/agents/models.py +21 -7
  7. shotgun/agents/plan.py +2 -1
  8. shotgun/agents/research.py +2 -1
  9. shotgun/agents/specify.py +2 -1
  10. shotgun/agents/tasks.py +5 -2
  11. shotgun/agents/tools/codebase/codebase_shell.py +2 -2
  12. shotgun/agents/tools/codebase/directory_lister.py +1 -1
  13. shotgun/agents/tools/codebase/file_read.py +1 -1
  14. shotgun/agents/tools/codebase/query_graph.py +1 -1
  15. shotgun/agents/tools/codebase/retrieve_code.py +1 -1
  16. shotgun/agents/tools/file_management.py +67 -2
  17. shotgun/main.py +9 -1
  18. shotgun/prompts/agents/export.j2 +14 -11
  19. shotgun/prompts/agents/partials/codebase_understanding.j2 +9 -0
  20. shotgun/prompts/agents/partials/common_agent_system_prompt.j2 +6 -9
  21. shotgun/prompts/agents/plan.j2 +9 -13
  22. shotgun/prompts/agents/research.j2 +11 -14
  23. shotgun/prompts/agents/specify.j2 +9 -12
  24. shotgun/prompts/agents/state/codebase/codebase_graphs_available.j2 +5 -1
  25. shotgun/prompts/agents/state/system_state.j2 +27 -5
  26. shotgun/prompts/agents/tasks.j2 +12 -12
  27. shotgun/sdk/models.py +1 -1
  28. shotgun/sdk/services.py +0 -14
  29. shotgun/tui/app.py +9 -4
  30. shotgun/tui/screens/chat.py +92 -30
  31. shotgun/tui/screens/chat_screen/command_providers.py +1 -1
  32. shotgun/tui/screens/chat_screen/history.py +6 -0
  33. shotgun/tui/utils/__init__.py +5 -0
  34. shotgun/tui/utils/mode_progress.py +257 -0
  35. {shotgun_sh-0.1.0.dev20.dist-info → shotgun_sh-0.1.0.dev23.dist-info}/METADATA +8 -9
  36. {shotgun_sh-0.1.0.dev20.dist-info → shotgun_sh-0.1.0.dev23.dist-info}/RECORD +39 -56
  37. shotgun/agents/artifact_state.py +0 -58
  38. shotgun/agents/tools/artifact_management.py +0 -481
  39. shotgun/artifacts/__init__.py +0 -17
  40. shotgun/artifacts/exceptions.py +0 -89
  41. shotgun/artifacts/manager.py +0 -530
  42. shotgun/artifacts/models.py +0 -334
  43. shotgun/artifacts/service.py +0 -463
  44. shotgun/artifacts/templates/__init__.py +0 -10
  45. shotgun/artifacts/templates/loader.py +0 -252
  46. shotgun/artifacts/templates/models.py +0 -136
  47. shotgun/artifacts/templates/plan/delivery_and_release_plan.yaml +0 -66
  48. shotgun/artifacts/templates/research/market_research.yaml +0 -585
  49. shotgun/artifacts/templates/research/sdk_comparison.yaml +0 -257
  50. shotgun/artifacts/templates/specify/prd.yaml +0 -331
  51. shotgun/artifacts/templates/specify/product_spec.yaml +0 -301
  52. shotgun/artifacts/utils.py +0 -76
  53. shotgun/prompts/agents/partials/artifact_system.j2 +0 -32
  54. shotgun/prompts/agents/state/artifact_templates_available.j2 +0 -20
  55. shotgun/prompts/agents/state/existing_artifacts_available.j2 +0 -25
  56. shotgun/sdk/artifact_models.py +0 -186
  57. shotgun/sdk/artifacts.py +0 -448
  58. {shotgun_sh-0.1.0.dev20.dist-info → shotgun_sh-0.1.0.dev23.dist-info}/WHEEL +0 -0
  59. {shotgun_sh-0.1.0.dev20.dist-info → shotgun_sh-0.1.0.dev23.dist-info}/entry_points.txt +0 -0
  60. {shotgun_sh-0.1.0.dev20.dist-info → shotgun_sh-0.1.0.dev23.dist-info}/licenses/LICENSE +0 -0
@@ -1,301 +0,0 @@
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"
@@ -1,76 +0,0 @@
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)
@@ -1,32 +0,0 @@
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
- - Use meaningful artifact IDs that describe the work
18
- - Organize content into logical sections (overview, analysis, recommendations, etc.)
19
- - Use descriptive section titles and slugs
20
- - Build upon existing work rather than starting from scratch
21
-
22
-
23
- ## ARTIFACT TEMPLATES
24
-
25
- Use artifact templates to help you create new artifacts.
26
-
27
- 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.
28
-
29
- Use `create_artifact(artifact_id, agent_mode, name, template_id)` to create a new artifact with a template.
30
-
31
- Template ID example: "research/market_research"
32
-
@@ -1,20 +0,0 @@
1
- {% if available_templates %}
2
-
3
- ## Available Artifact Templates (up to date, no need to check again)
4
-
5
- ### Below if the current output of list_artifact_templates()
6
-
7
- You have access to these pre-built templates for creating structured artifacts:
8
-
9
- {% for mode, templates in available_templates.items() %}
10
- ### {{ mode.title() }} Templates
11
- {% for template in templates %}
12
- - **{{ template.name }}** (`{{ template.template_id }}`)
13
- Purpose: {{ template.purpose[:150] }}{% if template.purpose|length > 150 %}...{% endif %}
14
- {% endfor %}
15
-
16
- {% endfor %}
17
- Use `list_artifact_templates("mode")` to get detailed template information for a specific mode, or `list_artifact_templates()` for all templates.
18
- Use `create_artifact(artifact_id, agent_mode, name, template_id)` to create a new artifact with any of these templates.
19
-
20
- {% endif %}
@@ -1,25 +0,0 @@
1
- {% if existing_artifacts %}
2
-
3
- ## Existing Artifacts (All Modes)
4
-
5
- ### Below if the current output of list_artifacts()
6
-
7
- Work already completed across all agent modes:
8
-
9
- {% for mode, artifacts in existing_artifacts.items() %}
10
- ### {{ mode.title() }} Artifacts
11
- {% for artifact in artifacts %}
12
- - **{{ artifact.artifact_id }}** ({{ artifact.section_count }} sections)
13
- Updated: {{ artifact.updated_at.strftime('%B %d, %Y') }}
14
- {% endfor %}
15
-
16
- {% endfor %}
17
- Use `read_artifact(artifact_id)` to access full content, `list_artifacts()` for detailed view, or `list_artifacts("mode")` for specific mode.
18
-
19
- {% else %}
20
-
21
- ## Existing Artifacts
22
-
23
- No artifacts have been created yet. Use `create_artifact()` with available templates to start new work.
24
-
25
- {% endif %}
@@ -1,186 +0,0 @@
1
- """Result models for SDK artifact operations."""
2
-
3
- from pydantic import BaseModel
4
-
5
- from shotgun.artifacts.models import AgentMode, Artifact, ArtifactSummary
6
-
7
-
8
- class ArtifactListResult(BaseModel):
9
- """Result for artifact list command."""
10
-
11
- artifacts: list[ArtifactSummary]
12
- agent_mode: AgentMode | None = None
13
-
14
- def __str__(self) -> str:
15
- """Format list result as plain text table."""
16
- if not self.artifacts:
17
- mode_text = f" for {self.agent_mode.value}" if self.agent_mode else ""
18
- return f"No artifacts found{mode_text}."
19
-
20
- lines = [
21
- f"{'Agent':<10} {'ID':<25} {'Name':<30} {'Sections':<8} {'Updated'}",
22
- "-" * 85,
23
- ]
24
-
25
- for artifact in self.artifacts:
26
- lines.append(
27
- f"{artifact.agent_mode.value:<10} "
28
- f"{artifact.artifact_id[:25]:<25} "
29
- f"{artifact.name[:30]:<30} "
30
- f"{artifact.section_count:<8} "
31
- f"{artifact.updated_at.strftime('%Y-%m-%d')}"
32
- )
33
-
34
- return "\n".join(lines)
35
-
36
-
37
- class ArtifactCreateResult(BaseModel):
38
- """Result for artifact create command."""
39
-
40
- artifact_id: str
41
- agent_mode: AgentMode
42
- name: str
43
- created: bool = True
44
-
45
- def __str__(self) -> str:
46
- """Format create result as success message."""
47
- return f"Created artifact '{self.artifact_id}' in {self.agent_mode.value} mode"
48
-
49
-
50
- class ArtifactDeleteResult(BaseModel):
51
- """Result for artifact delete command."""
52
-
53
- artifact_id: str
54
- agent_mode: AgentMode
55
- deleted: bool = True
56
- cancelled: bool = False
57
-
58
- def __str__(self) -> str:
59
- """Format delete result message."""
60
- if self.cancelled:
61
- return "Deletion cancelled."
62
- elif self.deleted:
63
- return f"Deleted artifact '{self.artifact_id}' from {self.agent_mode.value} mode"
64
- else:
65
- return f"Failed to delete artifact '{self.artifact_id}'"
66
-
67
-
68
- class ArtifactInfoResult(BaseModel):
69
- """Result for artifact info command."""
70
-
71
- artifact: Artifact
72
-
73
- def __str__(self) -> str:
74
- """Format detailed artifact information."""
75
- artifact = self.artifact
76
- lines = [
77
- f"Artifact ID: {artifact.artifact_id}",
78
- f"Name: {artifact.name}",
79
- f"Agent Mode: {artifact.agent_mode.value}",
80
- f"Created: {artifact.get_created_at()}",
81
- f"Updated: {artifact.get_updated_at()}",
82
- f"Sections: {artifact.get_section_count()}",
83
- f"Total Content Length: {artifact.get_total_content_length()} characters",
84
- ]
85
-
86
- if artifact.sections:
87
- lines.append("\nSections:")
88
- for section in artifact.get_ordered_sections():
89
- content_preview = (
90
- section.content[:50] + "..."
91
- if len(section.content) > 50
92
- else section.content
93
- ).replace("\n", " ")
94
- lines.append(f" {section.number:03d}. {section.title}")
95
- if content_preview:
96
- lines.append(f" {content_preview}")
97
-
98
- return "\n".join(lines)
99
-
100
-
101
- class SectionCreateResult(BaseModel):
102
- """Result for section create command."""
103
-
104
- artifact_id: str
105
- agent_mode: AgentMode
106
- section_number: int
107
- section_title: str
108
- created: bool = True
109
-
110
- def __str__(self) -> str:
111
- """Format section create result."""
112
- return (
113
- f"Created section {self.section_number} '{self.section_title}' "
114
- f"in artifact '{self.artifact_id}'"
115
- )
116
-
117
-
118
- class SectionUpdateResult(BaseModel):
119
- """Result for section update command."""
120
-
121
- artifact_id: str
122
- agent_mode: AgentMode
123
- section_number: int
124
- updated_fields: list[str]
125
-
126
- def __str__(self) -> str:
127
- """Format section update result."""
128
- fields_text = ", ".join(self.updated_fields)
129
- return (
130
- f"Updated section {self.section_number} in artifact '{self.artifact_id}' "
131
- f"(fields: {fields_text})"
132
- )
133
-
134
-
135
- class SectionDeleteResult(BaseModel):
136
- """Result for section delete command."""
137
-
138
- artifact_id: str
139
- agent_mode: AgentMode
140
- section_number: int
141
- deleted: bool = True
142
-
143
- def __str__(self) -> str:
144
- """Format section delete result."""
145
- if self.deleted:
146
- return f"Deleted section {self.section_number} from artifact '{self.artifact_id}'"
147
- else:
148
- return f"Failed to delete section {self.section_number}"
149
-
150
-
151
- class SectionContentResult(BaseModel):
152
- """Result for section content read command."""
153
-
154
- artifact_id: str
155
- agent_mode: AgentMode
156
- section_number: int
157
- content: str
158
-
159
- def __str__(self) -> str:
160
- """Format section content."""
161
- return self.content
162
-
163
-
164
- class ArtifactErrorResult(BaseModel):
165
- """Result for error cases in artifact operations."""
166
-
167
- error_message: str
168
- artifact_id: str | None = None
169
- agent_mode: AgentMode | None = None
170
- section_number: int | None = None
171
- details: str | None = None
172
-
173
- def __str__(self) -> str:
174
- """Format error message."""
175
- parts = [f"Error: {self.error_message}"]
176
-
177
- if self.artifact_id:
178
- parts.append(f"Artifact: {self.artifact_id}")
179
- if self.agent_mode:
180
- parts.append(f"Mode: {self.agent_mode.value}")
181
- if self.section_number:
182
- parts.append(f"Section: {self.section_number}")
183
- if self.details:
184
- parts.append(f"Details: {self.details}")
185
-
186
- return " | ".join(parts)