steerdev 1.0.58__tar.gz → 1.0.59__tar.gz

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 (114) hide show
  1. {steerdev-1.0.58 → steerdev-1.0.59}/PKG-INFO +1 -1
  2. {steerdev-1.0.58 → steerdev-1.0.59}/pyproject.toml +1 -1
  3. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/agent_loop.py +55 -0
  4. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/commands.py +1 -1
  5. steerdev-1.0.59/src/steerdev_agent/api/merger.py +71 -0
  6. {steerdev-1.0.58 → steerdev-1.0.59}/.github/workflows/pre-commit.yml +0 -0
  7. {steerdev-1.0.58 → steerdev-1.0.59}/.github/workflows/publish.yml +0 -0
  8. {steerdev-1.0.58 → steerdev-1.0.59}/.gitignore +0 -0
  9. {steerdev-1.0.58 → steerdev-1.0.59}/.pre-commit-config.yaml +0 -0
  10. {steerdev-1.0.58 → steerdev-1.0.59}/AGENTS.md +0 -0
  11. {steerdev-1.0.58 → steerdev-1.0.59}/CLAUDE.md +0 -0
  12. {steerdev-1.0.58 → steerdev-1.0.59}/README.md +0 -0
  13. {steerdev-1.0.58 → steerdev-1.0.59}/scripts/pre-commit-version-bump.sh +0 -0
  14. {steerdev-1.0.58 → steerdev-1.0.59}/snapshots/steerdev-agent-v1/Dockerfile +0 -0
  15. {steerdev-1.0.58 → steerdev-1.0.59}/snapshots/steerdev-agent-v1/start-agent.sh +0 -0
  16. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/__init__.py +0 -0
  17. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/__init__.py +0 -0
  18. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/activity.py +0 -0
  19. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/agents.py +0 -0
  20. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/canals.py +0 -0
  21. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/client.py +0 -0
  22. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/configs.py +0 -0
  23. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/context.py +0 -0
  24. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/events.py +0 -0
  25. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/hooks.py +0 -0
  26. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/implementation_plan.py +0 -0
  27. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/messages.py +0 -0
  28. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/prd.py +0 -0
  29. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/reports.py +0 -0
  30. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/runs.py +0 -0
  31. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/sessions.py +0 -0
  32. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/specs.py +0 -0
  33. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/tasks.py +0 -0
  34. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/workflow_runs.py +0 -0
  35. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/api/workflows.py +0 -0
  36. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/cli.py +0 -0
  37. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/config/__init__.py +0 -0
  38. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/config/models.py +0 -0
  39. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/config/platform.py +0 -0
  40. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/config/settings.py +0 -0
  41. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/evidence.py +0 -0
  42. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/evidence_assets.py +0 -0
  43. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/executor/__init__.py +0 -0
  44. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/executor/base.py +0 -0
  45. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/executor/claude.py +0 -0
  46. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/executor/stream.py +0 -0
  47. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/handlers/__init__.py +0 -0
  48. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/handlers/prd.py +0 -0
  49. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/integration.py +0 -0
  50. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/prompt/__init__.py +0 -0
  51. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/prompt/builder.py +0 -0
  52. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/prompt/templates.py +0 -0
  53. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/prompt/workflow_template.py +0 -0
  54. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/py.typed +0 -0
  55. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/retry.py +0 -0
  56. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/runner.py +0 -0
  57. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/__init__.py +0 -0
  58. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/claude_setup.py +0 -0
  59. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/repo_setup.py +0 -0
  60. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/ci/canal-integration.yml +0 -0
  61. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/claude_md_section.md +0 -0
  62. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/settings.json +0 -0
  63. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/skills/steerdev-activity-skill/SKILL.md +0 -0
  64. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/skills/steerdev-canal-workflow-skill/SKILL.md +0 -0
  65. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/skills/steerdev-context-skill/SKILL.md +0 -0
  66. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/skills/steerdev-git-workflow-skill/SKILL.md +0 -0
  67. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/skills/steerdev-merge-into-canal-skill/SKILL.md +0 -0
  68. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/skills/steerdev-progress-logging-skill/SKILL.md +0 -0
  69. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/skills/steerdev-single-task-merge-skill/SKILL.md +0 -0
  70. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/skills/steerdev-specs-management-skill/SKILL.md +0 -0
  71. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/skills/steerdev-task-management-skill/SKILL.md +0 -0
  72. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/skills/steerdev-wave-tasks-merge-skill/SKILL.md +0 -0
  73. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/steerdev.yaml +0 -0
  74. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/setup/templates/worktrunk.config.toml +0 -0
  75. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/update_check.py +0 -0
  76. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/version.py +0 -0
  77. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/workflow/__init__.py +0 -0
  78. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/workflow/context.py +0 -0
  79. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/workflow/executor.py +0 -0
  80. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/workflow/memory.py +0 -0
  81. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/workspace/__init__.py +0 -0
  82. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/workspace/project_manager.py +0 -0
  83. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/workspace/tool_detection.py +0 -0
  84. {steerdev-1.0.58 → steerdev-1.0.59}/src/steerdev_agent/worktree.py +0 -0
  85. {steerdev-1.0.58 → steerdev-1.0.59}/tests/__init__.py +0 -0
  86. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_agent_loop.py +0 -0
  87. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_agent_loop_extended.py +0 -0
  88. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_agents_api.py +0 -0
  89. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_api_client.py +0 -0
  90. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_claude_executor.py +0 -0
  91. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_claude_setup.py +0 -0
  92. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_client_methods.py +0 -0
  93. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_commands_api.py +0 -0
  94. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_config.py +0 -0
  95. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_config_extended.py +0 -0
  96. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_conflict_mitigation.py +0 -0
  97. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_context_search.py +0 -0
  98. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_executor.py +0 -0
  99. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_platform_config.py +0 -0
  100. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_prompt.py +0 -0
  101. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_reports_client.py +0 -0
  102. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_retry.py +0 -0
  103. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_runner_merge_modes.py +0 -0
  104. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_runner_worktrees.py +0 -0
  105. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_stream_parser.py +0 -0
  106. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_tasks.py +0 -0
  107. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_version.py +0 -0
  108. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_workflow_context.py +0 -0
  109. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_workflow_memory.py +0 -0
  110. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_workflow_prompt_template.py +0 -0
  111. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_workflow_runs_api.py +0 -0
  112. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_workspace.py +0 -0
  113. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_workspace_extended.py +0 -0
  114. {steerdev-1.0.58 → steerdev-1.0.59}/tests/test_worktree.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: steerdev
3
- Version: 1.0.58
3
+ Version: 1.0.59
4
4
  Summary: Backend task runner for steerdev.com - orchestrates CLI coding agents with activity reporting
5
5
  Project-URL: Homepage, https://github.com/pentoai/steerdev-agent
6
6
  Project-URL: Repository, https://github.com/pentoai/steerdev-agent
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "steerdev"
3
- version = "1.0.58"
3
+ version = "1.0.59"
4
4
  description = "Backend task runner for steerdev.com - orchestrates CLI coding agents with activity reporting"
5
5
  readme = "README.md"
6
6
  authors = [
@@ -126,6 +126,8 @@ class CommandExecutor:
126
126
  await self._execute_task_command(command, project_id, working_directory)
127
127
  elif command.command_type == "prompt":
128
128
  await self._execute_prompt_command(command, project_id, working_directory)
129
+ elif command.command_type == "merger":
130
+ await self._execute_merger_command(command, project_id, working_directory)
129
131
  else:
130
132
  await self._commands_client.mark_failed(
131
133
  command.id, error=f"Unknown command type: {command.command_type}"
@@ -403,6 +405,59 @@ class CommandExecutor:
403
405
  finally:
404
406
  await events_client.close()
405
407
 
408
+ async def _execute_merger_command(
409
+ self,
410
+ command: CommandResponse,
411
+ project_id: str,
412
+ working_directory: Path,
413
+ ) -> None:
414
+ """Execute a merger command - triggers merger run and polls for completion."""
415
+ from steerdev_agent.api.merger import MergerClient
416
+
417
+ assert self._commands_client is not None
418
+
419
+ merger_run_id = command.metadata.get("mergerRunId")
420
+ if not merger_run_id:
421
+ raise ValueError("merger command missing mergerRunId in metadata")
422
+
423
+ merger_client = MergerClient(api_key=self._api_key)
424
+
425
+ logger.info(f"Starting merger run: {merger_run_id}")
426
+
427
+ # Mark command as executing
428
+ await self._commands_client.mark_executing(command.id)
429
+
430
+ # Trigger execution
431
+ result = merger_client.execute_merger_run(merger_run_id)
432
+ if not result:
433
+ raise RuntimeError(f"Failed to trigger merger run {merger_run_id}")
434
+
435
+ # Poll for completion
436
+ max_polls = 60 # 30 minutes at 30s intervals
437
+ for _ in range(max_polls):
438
+ run = merger_client.get_merger_run(merger_run_id)
439
+ if not run:
440
+ raise RuntimeError("Failed to get merger run status")
441
+
442
+ if run.status in ("completed", "failed", "partial"):
443
+ logger.info(f"Merger run {merger_run_id} finished: {run.status}")
444
+ if run.status == "failed":
445
+ raise RuntimeError(f"Merger run failed: {run.error_message}")
446
+ await self._commands_client.mark_completed(
447
+ command.id,
448
+ result=f"Merger run {merger_run_id} {run.status}",
449
+ )
450
+ self._commands_succeeded += 1
451
+ return
452
+
453
+ if self._shutdown_event.is_set():
454
+ logger.info("Shutdown during merger polling, aborting")
455
+ raise RuntimeError("Shutdown requested during merger run")
456
+
457
+ await asyncio.sleep(30)
458
+
459
+ raise RuntimeError(f"Merger run {merger_run_id} timed out")
460
+
406
461
 
407
462
  # ---------------------------------------------------------------------------
408
463
  # Project-scoped agent (original)
@@ -13,7 +13,7 @@ from steerdev_agent.api.client import get_agent_id, get_api_endpoint, get_api_ke
13
13
 
14
14
  console = Console()
15
15
 
16
- CommandType = Literal["task", "prompt", "control"]
16
+ CommandType = Literal["task", "prompt", "control", "merger"]
17
17
  CommandStatus = Literal[
18
18
  "pending", "claimed", "executing", "completed", "failed", "cancelled", "expired"
19
19
  ]
@@ -0,0 +1,71 @@
1
+ """Merger API client for merger agent operations."""
2
+
3
+ from typing import Any
4
+
5
+ from pydantic import BaseModel
6
+
7
+ from steerdev_agent.api.client import SteerDevClient
8
+
9
+
10
+ class MergerRunResponse(BaseModel):
11
+ id: str
12
+ status: str
13
+ wave_ids: list[str] = []
14
+ task_ids: list[str] = []
15
+ pr_ids: list[str] = []
16
+ evidence_report_ids: list[str] = []
17
+ summary: str | None = None
18
+ merged_branches: list[str] | None = None
19
+ error_message: str | None = None
20
+ started_at: str | None = None
21
+ completed_at: str | None = None
22
+
23
+
24
+ class GateResponse(BaseModel):
25
+ id: str
26
+ merger_run_id: str
27
+ canal_id: str
28
+ gate_number: int
29
+ status: str
30
+ started_at: str | None = None
31
+ completed_at: str | None = None
32
+ details: dict[str, Any] | None = None
33
+ error_message: str | None = None
34
+
35
+
36
+ class MergerClient(SteerDevClient):
37
+ """Client for merger agent API operations."""
38
+
39
+ def execute_merger_run(self, merger_run_id: str) -> dict[str, Any] | None:
40
+ """Trigger execution of a full merger run."""
41
+ response = self.post(f"/merger-runs/{merger_run_id}/execute")
42
+ if response and response.status_code == 200:
43
+ return response.json()
44
+ return None
45
+
46
+ def get_merger_run(self, merger_run_id: str) -> MergerRunResponse | None:
47
+ """Get merger run status."""
48
+ response = self.get(f"/merger-runs/{merger_run_id}")
49
+ if response and response.status_code == 200:
50
+ return MergerRunResponse(**response.json())
51
+ return None
52
+
53
+ def get_merger_gates(self, merger_run_id: str) -> list[GateResponse]:
54
+ """Get gate statuses for a merger run."""
55
+ response = self.get(f"/merger-runs/{merger_run_id}/gates")
56
+ if response and response.status_code == 200:
57
+ data = response.json()
58
+ return [GateResponse(**g) for g in data.get("gates", [])]
59
+ return []
60
+
61
+ def execute_gate(
62
+ self, canal_id: str, gate_number: int, merger_run_id: str, merge_id: str | None = None
63
+ ) -> dict[str, Any] | None:
64
+ """Trigger execution of a specific gate."""
65
+ payload: dict[str, Any] = {"merger_run_id": merger_run_id}
66
+ if merge_id:
67
+ payload["merge_id"] = merge_id
68
+ response = self.post(f"/canals/{canal_id}/gates/{gate_number}", json=payload)
69
+ if response and response.status_code == 200:
70
+ return response.json()
71
+ return None
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes