steerdev 0.4.27__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 (57) hide show
  1. steerdev-0.4.27.dist-info/METADATA +224 -0
  2. steerdev-0.4.27.dist-info/RECORD +57 -0
  3. steerdev-0.4.27.dist-info/WHEEL +4 -0
  4. steerdev-0.4.27.dist-info/entry_points.txt +2 -0
  5. steerdev_agent/__init__.py +10 -0
  6. steerdev_agent/api/__init__.py +32 -0
  7. steerdev_agent/api/activity.py +278 -0
  8. steerdev_agent/api/agents.py +145 -0
  9. steerdev_agent/api/client.py +158 -0
  10. steerdev_agent/api/commands.py +399 -0
  11. steerdev_agent/api/configs.py +238 -0
  12. steerdev_agent/api/context.py +306 -0
  13. steerdev_agent/api/events.py +294 -0
  14. steerdev_agent/api/hooks.py +178 -0
  15. steerdev_agent/api/implementation_plan.py +408 -0
  16. steerdev_agent/api/messages.py +231 -0
  17. steerdev_agent/api/prd.py +281 -0
  18. steerdev_agent/api/runs.py +526 -0
  19. steerdev_agent/api/sessions.py +403 -0
  20. steerdev_agent/api/specs.py +321 -0
  21. steerdev_agent/api/tasks.py +659 -0
  22. steerdev_agent/api/workflow_runs.py +351 -0
  23. steerdev_agent/api/workflows.py +191 -0
  24. steerdev_agent/cli.py +2254 -0
  25. steerdev_agent/config/__init__.py +19 -0
  26. steerdev_agent/config/models.py +236 -0
  27. steerdev_agent/config/platform.py +272 -0
  28. steerdev_agent/config/settings.py +62 -0
  29. steerdev_agent/daemon.py +675 -0
  30. steerdev_agent/executor/__init__.py +64 -0
  31. steerdev_agent/executor/base.py +121 -0
  32. steerdev_agent/executor/claude.py +328 -0
  33. steerdev_agent/executor/stream.py +163 -0
  34. steerdev_agent/git/__init__.py +1 -0
  35. steerdev_agent/handlers/__init__.py +5 -0
  36. steerdev_agent/handlers/prd.py +533 -0
  37. steerdev_agent/integration.py +334 -0
  38. steerdev_agent/prompt/__init__.py +10 -0
  39. steerdev_agent/prompt/builder.py +263 -0
  40. steerdev_agent/prompt/templates.py +422 -0
  41. steerdev_agent/py.typed +0 -0
  42. steerdev_agent/runner.py +829 -0
  43. steerdev_agent/setup/__init__.py +5 -0
  44. steerdev_agent/setup/claude_setup.py +560 -0
  45. steerdev_agent/setup/templates/claude_md_section.md +140 -0
  46. steerdev_agent/setup/templates/settings.json +69 -0
  47. steerdev_agent/setup/templates/skills/activity/SKILL.md +160 -0
  48. steerdev_agent/setup/templates/skills/context/SKILL.md +122 -0
  49. steerdev_agent/setup/templates/skills/git-workflow/SKILL.md +218 -0
  50. steerdev_agent/setup/templates/skills/progress-logging/SKILL.md +211 -0
  51. steerdev_agent/setup/templates/skills/specs-management/SKILL.md +161 -0
  52. steerdev_agent/setup/templates/skills/task-management/SKILL.md +343 -0
  53. steerdev_agent/setup/templates/steerdev.yaml +51 -0
  54. steerdev_agent/version.py +149 -0
  55. steerdev_agent/workflow/__init__.py +10 -0
  56. steerdev_agent/workflow/executor.py +494 -0
  57. steerdev_agent/workflow/memory.py +185 -0
@@ -0,0 +1,281 @@
1
+ """PRD API client for SteerDev Agent.
2
+
3
+ Provides methods for interacting with PRD documents and comments
4
+ during agent-driven PRD analysis and task generation.
5
+ """
6
+
7
+ from __future__ import annotations
8
+
9
+ from typing import Any
10
+
11
+ from loguru import logger
12
+ from pydantic import BaseModel
13
+
14
+ from steerdev_agent.api.client import SteerDevClient
15
+
16
+
17
+ class PRDComment(BaseModel):
18
+ """PRD comment model."""
19
+
20
+ id: str
21
+ prd_id: str
22
+ parent_id: str | None = None
23
+ content: str
24
+ comment_type: str # question, answer, note
25
+ context: str | None = None
26
+ category: str | None = None
27
+ author_type: str # agent, user
28
+ author_id: str
29
+ author_name: str | None = None
30
+ is_resolved: bool = False
31
+ created_at: str
32
+ updated_at: str
33
+
34
+
35
+ class PRDDocument(BaseModel):
36
+ """PRD document model."""
37
+
38
+ id: str
39
+ project_id: str
40
+ title: str
41
+ content: str
42
+ source: str
43
+ source_file_name: str | None = None
44
+ status: str # draft, analyzing, clarifying, planning, ready, completed
45
+ implementation_plan: dict[str, Any] | None = None
46
+ run_id: str | None = None
47
+ created_by: str
48
+ created_at: str
49
+ updated_at: str
50
+
51
+
52
+ class PRDClient(SteerDevClient):
53
+ """API client for PRD operations.
54
+
55
+ Used by the agent to:
56
+ - Get PRD document content
57
+ - Post analysis questions as comments
58
+ - Update PRD status
59
+ - Save implementation plans
60
+ """
61
+
62
+ def get_prd(self, prd_id: str) -> PRDDocument | None:
63
+ """Get a PRD document by ID.
64
+
65
+ Args:
66
+ prd_id: PRD document ID.
67
+
68
+ Returns:
69
+ PRD document or None if not found.
70
+ """
71
+ try:
72
+ response = self.get(f"/prd/{prd_id}")
73
+
74
+ if response.status_code == 200:
75
+ data = response.json()
76
+ return PRDDocument(**data)
77
+ if response.status_code == 404:
78
+ return None
79
+
80
+ logger.error(f"Failed to get PRD: {response.status_code} - {response.text}")
81
+ return None
82
+
83
+ except Exception as e:
84
+ logger.error(f"Error getting PRD: {e}")
85
+ return None
86
+
87
+ def update_prd_status(self, prd_id: str, status: str) -> PRDDocument | None:
88
+ """Update PRD status.
89
+
90
+ Args:
91
+ prd_id: PRD document ID.
92
+ status: New status value.
93
+
94
+ Returns:
95
+ Updated PRD document or None on failure.
96
+ """
97
+ try:
98
+ response = self.patch(f"/prd/{prd_id}", json={"status": status})
99
+
100
+ if response.status_code == 200:
101
+ data = response.json()
102
+ return PRDDocument(**data)
103
+
104
+ logger.error(f"Failed to update PRD status: {response.status_code} - {response.text}")
105
+ return None
106
+
107
+ except Exception as e:
108
+ logger.error(f"Error updating PRD status: {e}")
109
+ return None
110
+
111
+ def save_implementation_plan(
112
+ self,
113
+ prd_id: str,
114
+ plan: dict[str, Any],
115
+ ) -> PRDDocument | None:
116
+ """Save implementation plan to PRD document.
117
+
118
+ Args:
119
+ prd_id: PRD document ID.
120
+ plan: Implementation plan dictionary.
121
+
122
+ Returns:
123
+ Updated PRD document or None on failure.
124
+ """
125
+ try:
126
+ response = self.patch(
127
+ f"/prd/{prd_id}",
128
+ json={
129
+ "implementation_plan": plan,
130
+ "status": "ready",
131
+ },
132
+ )
133
+
134
+ if response.status_code == 200:
135
+ data = response.json()
136
+ return PRDDocument(**data)
137
+
138
+ logger.error(
139
+ f"Failed to save implementation plan: {response.status_code} - {response.text}"
140
+ )
141
+ return None
142
+
143
+ except Exception as e:
144
+ logger.error(f"Error saving implementation plan: {e}")
145
+ return None
146
+
147
+ def post_questions(
148
+ self,
149
+ prd_id: str,
150
+ questions: list[dict[str, str]],
151
+ agent_id: str,
152
+ agent_name: str = "SteerDev Agent",
153
+ ) -> list[PRDComment]:
154
+ """Post analysis questions as comments.
155
+
156
+ Args:
157
+ prd_id: PRD document ID.
158
+ questions: List of question dicts with keys: question, context, category.
159
+ agent_id: Agent ID posting the questions.
160
+ agent_name: Display name for the agent.
161
+
162
+ Returns:
163
+ List of created comments.
164
+ """
165
+ try:
166
+ comments_data = [
167
+ {
168
+ "content": q.get("question", ""),
169
+ "comment_type": "question",
170
+ "context": q.get("context"),
171
+ "category": q.get("category"),
172
+ "author_type": "agent",
173
+ "author_id": agent_id,
174
+ "author_name": agent_name,
175
+ }
176
+ for q in questions
177
+ ]
178
+
179
+ response = self.post(
180
+ f"/prd/{prd_id}/comments",
181
+ json={"comments": comments_data},
182
+ )
183
+
184
+ if response.status_code == 201:
185
+ data = response.json()
186
+ return [PRDComment(**c) for c in data.get("comments", [])]
187
+
188
+ logger.error(f"Failed to post questions: {response.status_code} - {response.text}")
189
+ return []
190
+
191
+ except Exception as e:
192
+ logger.error(f"Error posting questions: {e}")
193
+ return []
194
+
195
+ def get_comments(self, prd_id: str) -> list[PRDComment]:
196
+ """Get all comments for a PRD.
197
+
198
+ Args:
199
+ prd_id: PRD document ID.
200
+
201
+ Returns:
202
+ List of comments.
203
+ """
204
+ try:
205
+ response = self.get(f"/prd/{prd_id}/comments")
206
+
207
+ if response.status_code == 200:
208
+ data = response.json()
209
+ return [PRDComment(**c) for c in data.get("comments", [])]
210
+
211
+ logger.error(f"Failed to get comments: {response.status_code} - {response.text}")
212
+ return []
213
+
214
+ except Exception as e:
215
+ logger.error(f"Error getting comments: {e}")
216
+ return []
217
+
218
+ def resolve_comment(self, prd_id: str, comment_id: str) -> PRDComment | None:
219
+ """Mark a question as resolved.
220
+
221
+ Args:
222
+ prd_id: PRD document ID.
223
+ comment_id: Comment ID to resolve.
224
+
225
+ Returns:
226
+ Updated comment or None on failure.
227
+ """
228
+ try:
229
+ response = self.post(f"/prd/{prd_id}/comments/{comment_id}/resolve")
230
+
231
+ if response.status_code == 200:
232
+ data = response.json()
233
+ return PRDComment(**data)
234
+
235
+ logger.error(f"Failed to resolve comment: {response.status_code} - {response.text}")
236
+ return None
237
+
238
+ except Exception as e:
239
+ logger.error(f"Error resolving comment: {e}")
240
+ return None
241
+
242
+ def post_note(
243
+ self,
244
+ prd_id: str,
245
+ content: str,
246
+ agent_id: str,
247
+ agent_name: str = "SteerDev Agent",
248
+ ) -> PRDComment | None:
249
+ """Post a general note as a comment.
250
+
251
+ Args:
252
+ prd_id: PRD document ID.
253
+ content: Note content.
254
+ agent_id: Agent ID posting the note.
255
+ agent_name: Display name for the agent.
256
+
257
+ Returns:
258
+ Created comment or None on failure.
259
+ """
260
+ try:
261
+ response = self.post(
262
+ f"/prd/{prd_id}/comments",
263
+ json={
264
+ "content": content,
265
+ "comment_type": "note",
266
+ "author_type": "agent",
267
+ "author_id": agent_id,
268
+ "author_name": agent_name,
269
+ },
270
+ )
271
+
272
+ if response.status_code == 201:
273
+ data = response.json()
274
+ return PRDComment(**data)
275
+
276
+ logger.error(f"Failed to post note: {response.status_code} - {response.text}")
277
+ return None
278
+
279
+ except Exception as e:
280
+ logger.error(f"Error posting note: {e}")
281
+ return None