Background
PRs #224 (CodexAdapter) and #225 (GeminiAdapter) each contain identical _build_prompt and _derive_artifacts module-level functions. ClaudeAdapter also contains its own _derive_artifacts (at claude.py:317). Any future ProviderAdapter implementation would need to duplicate them again.
Work
- Create
orchestrator-api/app/providers/utils.py (or subprocess_helpers.py) exporting:
build_prompt(prompt: str, context_files: list[Path]) -> str
derive_artifacts(repo: GitRepo, head_before: str) -> Coroutine[..., list[str]]
- Update
claude.py, codex.py, and gemini.py to import from the shared module and delete the local copies.
- No behaviour change — pure refactor.
Acceptance criteria
Background
PRs #224 (CodexAdapter) and #225 (GeminiAdapter) each contain identical
_build_promptand_derive_artifactsmodule-level functions.ClaudeAdapteralso contains its own_derive_artifacts(atclaude.py:317). Any futureProviderAdapterimplementation would need to duplicate them again.Work
orchestrator-api/app/providers/utils.py(orsubprocess_helpers.py) exporting:build_prompt(prompt: str, context_files: list[Path]) -> strderive_artifacts(repo: GitRepo, head_before: str) -> Coroutine[..., list[str]]claude.py,codex.py, andgemini.pyto import from the shared module and delete the local copies.Acceptance criteria
uv run pytest)ruff checkandpyrightclean