steerdev 1.1.26__tar.gz → 1.1.28__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.
- {steerdev-1.1.26 → steerdev-1.1.28}/PKG-INFO +1 -1
- {steerdev-1.1.26 → steerdev-1.1.28}/pyproject.toml +1 -1
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/agent_loop.py +24 -2
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/runner.py +24 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/workspace/preparation.py +7 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_agent_loop.py +31 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_preparation.py +9 -1
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_runner_worktrees.py +24 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/.github/workflows/pre-commit.yml +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/.github/workflows/publish.yml +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/.gitignore +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/.pre-commit-config.yaml +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/AGENTS.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/CLAUDE.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/README.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/docs/superpowers/plans/2026-06-05-wave-id-implies-unlimited-max-tasks.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/docs/superpowers/specs/2026-06-05-wave-id-implies-unlimited-max-tasks-design.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/scripts/pre-commit-version-bump.sh +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/snapshots/steerdev-agent-v1/Dockerfile +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/snapshots/steerdev-agent-v1/start-agent.sh +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/__init__.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/__init__.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/activity.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/agents.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/canals.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/client.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/commands.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/configs.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/context.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/events.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/hooks.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/implementation_plan.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/merger.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/messages.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/prd.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/reports.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/runs.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/sessions.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/specs.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/tasks.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/workflow_runs.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/api/workflows.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/cli.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/config/__init__.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/config/models.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/config/platform.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/config/settings.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/evidence.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/evidence_assets.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/executor/__init__.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/executor/base.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/executor/claude.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/executor/stream.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/git_ops.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/handlers/__init__.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/handlers/prd.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/integration.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/prompt/__init__.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/prompt/builder.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/prompt/templates.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/prompt/workflow_template.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/py.typed +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/retry.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/__init__.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/claude_setup.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/repo_setup.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/ci/canal-integration.yml +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/claude_md_section.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/settings.json +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/skills/steerdev-activity-skill/SKILL.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/skills/steerdev-canal-workflow-skill/SKILL.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/skills/steerdev-context-skill/SKILL.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/skills/steerdev-git-workflow-skill/SKILL.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/skills/steerdev-merge-into-canal-skill/SKILL.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/skills/steerdev-progress-logging-skill/SKILL.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/skills/steerdev-single-task-merge-skill/SKILL.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/skills/steerdev-specs-management-skill/SKILL.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/skills/steerdev-task-management-skill/SKILL.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/skills/steerdev-wave-tasks-merge-skill/SKILL.md +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/steerdev.yaml +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/worktrunk.config.toml +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/update_check.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/version.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/workflow/__init__.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/workflow/context.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/workflow/executor.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/workflow/memory.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/workspace/__init__.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/workspace/project_manager.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/workspace/tool_detection.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/worktree.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/__init__.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_agent_loop_extended.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_agents_api.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_api_client.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_claude_executor.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_claude_setup.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_client_methods.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_commands_api.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_config.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_config_extended.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_conflict_mitigation.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_context_search.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_executor.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_git_ops.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_hooks_post_tool_use.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_platform_config.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_preparation_provenance.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_prompt.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_reports_client.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_resolve_max_tasks.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_retry.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_runner_merge_modes.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_stream_parser.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_tasks.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_tasks_update_branch.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_version.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_wave_scoped_fetch.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_workflow_context.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_workflow_memory.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_workflow_prompt_template.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_workflow_runs_api.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_workspace.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_workspace_extended.py +0 -0
- {steerdev-1.1.26 → steerdev-1.1.28}/tests/test_worktree.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: steerdev
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.28
|
|
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
|
|
@@ -582,10 +582,15 @@ class AgentLoop(CommandExecutor):
|
|
|
582
582
|
# Step 2: Recover stale commands
|
|
583
583
|
await self._recover_stale_commands()
|
|
584
584
|
|
|
585
|
-
# Step 3:
|
|
585
|
+
# Step 3: Reconcile .claude config (hooks) for this checkout, so a
|
|
586
|
+
# repo that predates newer steerdev hooks (e.g. the PostToolUse
|
|
587
|
+
# checkpoint-push hook) self-heals before any task launches Claude.
|
|
588
|
+
self._reconcile_settings()
|
|
589
|
+
|
|
590
|
+
# Step 4: Start heartbeat
|
|
586
591
|
self._heartbeat_task = asyncio.create_task(self._heartbeat_loop())
|
|
587
592
|
|
|
588
|
-
# Step
|
|
593
|
+
# Step 5: Main poll loop
|
|
589
594
|
await self._poll_loop()
|
|
590
595
|
|
|
591
596
|
except AgentLoopError as e:
|
|
@@ -647,6 +652,23 @@ class AgentLoop(CommandExecutor):
|
|
|
647
652
|
)
|
|
648
653
|
await self._commands_client.mark_pending(cmd.id)
|
|
649
654
|
|
|
655
|
+
def _reconcile_settings(self) -> None:
|
|
656
|
+
"""Re-apply steerdev-owned .claude/settings.json hooks for this checkout.
|
|
657
|
+
|
|
658
|
+
Single-project mode runs against an already-existing repo that never
|
|
659
|
+
went through project bootstrap, so its .claude config can be missing or
|
|
660
|
+
predate newer steerdev hooks. Reconciling here (idempotent, best-effort)
|
|
661
|
+
ensures the PostToolUse checkpoint-push hook is present before Claude
|
|
662
|
+
launches. A setup failure must never block the agent.
|
|
663
|
+
"""
|
|
664
|
+
from steerdev_agent.setup.claude_setup import ClaudeSetup
|
|
665
|
+
|
|
666
|
+
try:
|
|
667
|
+
setup = ClaudeSetup(self.working_directory, install_target="project")
|
|
668
|
+
setup.setup_settings(force=False, include_hooks=True)
|
|
669
|
+
except Exception:
|
|
670
|
+
logger.exception(f"Failed to reconcile .claude settings for {self.working_directory}")
|
|
671
|
+
|
|
650
672
|
async def _poll_loop(self) -> None:
|
|
651
673
|
"""Main loop: poll for commands and execute them."""
|
|
652
674
|
logger.info("Entering poll loop")
|
|
@@ -1109,6 +1109,23 @@ class Runner:
|
|
|
1109
1109
|
except Exception:
|
|
1110
1110
|
logger.debug(f"Failed to cleanup worktree {worktree_branch}", exc_info=True)
|
|
1111
1111
|
|
|
1112
|
+
def _reconcile_settings(self) -> None:
|
|
1113
|
+
"""Re-apply steerdev-owned .claude/settings.json hooks for this checkout.
|
|
1114
|
+
|
|
1115
|
+
`steerdev run` operates on an existing or freshly-cloned repo that never
|
|
1116
|
+
went through project bootstrap (notably sandbox dispatch, which clones
|
|
1117
|
+
and immediately runs). Reconciling here (idempotent, best-effort)
|
|
1118
|
+
installs/heals the PostToolUse checkpoint-push hook before Claude
|
|
1119
|
+
launches, so commits push. A setup failure must never block the run.
|
|
1120
|
+
"""
|
|
1121
|
+
from steerdev_agent.setup.claude_setup import ClaudeSetup
|
|
1122
|
+
|
|
1123
|
+
try:
|
|
1124
|
+
setup = ClaudeSetup(self.working_directory, install_target="project")
|
|
1125
|
+
setup.setup_settings(force=False, include_hooks=True)
|
|
1126
|
+
except Exception:
|
|
1127
|
+
logger.exception(f"Failed to reconcile .claude settings for {self.working_directory}")
|
|
1128
|
+
|
|
1112
1129
|
async def run(self) -> dict[str, Any]:
|
|
1113
1130
|
"""Run the agent.
|
|
1114
1131
|
|
|
@@ -1137,6 +1154,13 @@ class Runner:
|
|
|
1137
1154
|
try:
|
|
1138
1155
|
await self._notify_state_change(RunState.RUNNING)
|
|
1139
1156
|
|
|
1157
|
+
# Reconcile .claude config (hooks) for this checkout before any task
|
|
1158
|
+
# launches Claude. `steerdev run` (used by sandbox dispatch) operates
|
|
1159
|
+
# on a fresh clone with no .claude config, so without this the
|
|
1160
|
+
# PostToolUse checkpoint-push hook is absent and sandbox commits
|
|
1161
|
+
# never push. Idempotent and best-effort.
|
|
1162
|
+
self._reconcile_settings()
|
|
1163
|
+
|
|
1140
1164
|
from steerdev_agent.retry import execute_with_retry
|
|
1141
1165
|
|
|
1142
1166
|
# Multi-task loop
|
|
@@ -322,6 +322,13 @@ class WorkspacePreparation:
|
|
|
322
322
|
if wave_context and current_branch == target_branch:
|
|
323
323
|
logger.info(f"Continuing wave on branch {target_branch}, fetching only")
|
|
324
324
|
await _run_git("fetch", "origin", cwd=cwd, check=False)
|
|
325
|
+
# Persist provenance here too: a wave-continuation task arrives
|
|
326
|
+
# already on the branch, so it skips the create/checkout path
|
|
327
|
+
# below where provenance is normally written. Without this, the
|
|
328
|
+
# second+ task in a wave never records its branch on the task.
|
|
329
|
+
await persist_branch_provenance(
|
|
330
|
+
task_id=task_id, branch=target_branch, base_branch=default_branch
|
|
331
|
+
)
|
|
325
332
|
return PreparationResult(
|
|
326
333
|
success=True,
|
|
327
334
|
branch_name=target_branch,
|
|
@@ -72,6 +72,37 @@ class TestAgentLoopError:
|
|
|
72
72
|
assert str(err) == "test error"
|
|
73
73
|
|
|
74
74
|
|
|
75
|
+
class TestAgentLoopReconcileSettings:
|
|
76
|
+
"""Tests for single-project AgentLoop hook reconciliation."""
|
|
77
|
+
|
|
78
|
+
def _make_agent_loop(self, working_directory):
|
|
79
|
+
from steerdev_agent.agent_loop import AgentLoop
|
|
80
|
+
|
|
81
|
+
return AgentLoop(
|
|
82
|
+
project_id="proj-1",
|
|
83
|
+
agent_name="test-agent",
|
|
84
|
+
working_directory=working_directory,
|
|
85
|
+
api_key="test-key",
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
def test_reconciles_settings_at_working_directory(self, tmp_path):
|
|
89
|
+
agent = self._make_agent_loop(tmp_path)
|
|
90
|
+
|
|
91
|
+
with patch("steerdev_agent.setup.claude_setup.ClaudeSetup") as cls:
|
|
92
|
+
agent._reconcile_settings()
|
|
93
|
+
|
|
94
|
+
cls.assert_called_once_with(tmp_path, install_target="project")
|
|
95
|
+
cls.return_value.setup_settings.assert_called_once_with(force=False, include_hooks=True)
|
|
96
|
+
|
|
97
|
+
def test_reconcile_swallows_errors(self, tmp_path):
|
|
98
|
+
agent = self._make_agent_loop(tmp_path)
|
|
99
|
+
|
|
100
|
+
with patch("steerdev_agent.setup.claude_setup.ClaudeSetup") as cls:
|
|
101
|
+
cls.return_value.setup_settings.side_effect = RuntimeError("disk full")
|
|
102
|
+
# Must not raise — durability must never block the agent.
|
|
103
|
+
agent._reconcile_settings()
|
|
104
|
+
|
|
105
|
+
|
|
75
106
|
class TestCommandExecutor:
|
|
76
107
|
"""Tests for CommandExecutor._execute_command dispatch logic."""
|
|
77
108
|
|
|
@@ -232,7 +232,10 @@ class TestWorkspacePreparationInPlace:
|
|
|
232
232
|
return (0, "", "")
|
|
233
233
|
return (0, "", "")
|
|
234
234
|
|
|
235
|
-
with
|
|
235
|
+
with (
|
|
236
|
+
patch("steerdev_agent.workspace.preparation._run_git", side_effect=mock_run_git),
|
|
237
|
+
patch("steerdev_agent.workspace.preparation.persist_branch_provenance") as mock_persist,
|
|
238
|
+
):
|
|
236
239
|
result = await prep.prepare(sample_task, wave_ctx)
|
|
237
240
|
|
|
238
241
|
assert result.success is True
|
|
@@ -240,6 +243,11 @@ class TestWorkspacePreparationInPlace:
|
|
|
240
243
|
# Should NOT have checkout commands (stayed on branch)
|
|
241
244
|
checkout_cmds = [c for c in calls if c[0] == "checkout"]
|
|
242
245
|
assert len(checkout_cmds) == 0
|
|
246
|
+
# Wave-continuation must still record branch provenance on the task,
|
|
247
|
+
# even though it skips the create/checkout path.
|
|
248
|
+
mock_persist.assert_awaited_once_with(
|
|
249
|
+
task_id=sample_task["id"], branch="wave-a1b2c3", base_branch="main"
|
|
250
|
+
)
|
|
243
251
|
|
|
244
252
|
@pytest.mark.asyncio
|
|
245
253
|
async def test_dirty_repo_stashes(self, worktree_disabled, default_config, sample_task):
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
"""Tests for worktree configuration and Runner worktree integration."""
|
|
2
2
|
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from unittest.mock import patch
|
|
5
|
+
|
|
3
6
|
from steerdev_agent.config.models import EvidenceConfig, WorktreeConfig
|
|
4
7
|
from steerdev_agent.prompt.builder import WaveContext
|
|
5
8
|
from steerdev_agent.runner import Runner
|
|
@@ -50,6 +53,27 @@ class TestComputeBranchName:
|
|
|
50
53
|
assert compute_branch_name(task) == "task/JIRA-456-fix"
|
|
51
54
|
|
|
52
55
|
|
|
56
|
+
class TestRunnerReconcileSettings:
|
|
57
|
+
"""Hook reconciliation for `steerdev run` (sandbox + local)."""
|
|
58
|
+
|
|
59
|
+
def test_reconciles_settings_at_working_directory(self):
|
|
60
|
+
r = Runner(project_id="p", api_key="k", working_directory=Path("/code/repo"))
|
|
61
|
+
|
|
62
|
+
with patch("steerdev_agent.setup.claude_setup.ClaudeSetup") as cls:
|
|
63
|
+
r._reconcile_settings()
|
|
64
|
+
|
|
65
|
+
cls.assert_called_once_with(Path("/code/repo"), install_target="project")
|
|
66
|
+
cls.return_value.setup_settings.assert_called_once_with(force=False, include_hooks=True)
|
|
67
|
+
|
|
68
|
+
def test_reconcile_swallows_errors(self):
|
|
69
|
+
r = Runner(project_id="p", api_key="k", working_directory=Path("/code/repo"))
|
|
70
|
+
|
|
71
|
+
with patch("steerdev_agent.setup.claude_setup.ClaudeSetup") as cls:
|
|
72
|
+
cls.return_value.setup_settings.side_effect = RuntimeError("disk full")
|
|
73
|
+
# Must not raise — durability must never block the run.
|
|
74
|
+
r._reconcile_settings()
|
|
75
|
+
|
|
76
|
+
|
|
53
77
|
class TestRunnerWorktreeConfig:
|
|
54
78
|
def test_disabled_by_default(self):
|
|
55
79
|
r = Runner(project_id="p", api_key="k")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/ci/canal-integration.yml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{steerdev-1.1.26 → steerdev-1.1.28}/src/steerdev_agent/setup/templates/worktrunk.config.toml
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|