muse.py
python
| 1 | """Muse VCS client stub for TourDeForce. |
| 2 | |
| 3 | The full MuseClient was extracted to cgcardona/muse. |
| 4 | This stub preserves the type signatures so tourdeforce/runner.py can import |
| 5 | without errors. All MuseClient methods raise NotImplementedError at runtime. |
| 6 | |
| 7 | TODO(muse-extraction): re-integrate MuseClient once Muse exposes a |
| 8 | standalone service API. |
| 9 | """ |
| 10 | from __future__ import annotations |
| 11 | |
| 12 | from pathlib import Path |
| 13 | from typing import Any |
| 14 | |
| 15 | |
| 16 | class MuseError(Exception): |
| 17 | pass |
| 18 | |
| 19 | |
| 20 | class CheckoutResult: |
| 21 | """Structured checkout result.""" |
| 22 | |
| 23 | def __init__( |
| 24 | self, |
| 25 | success: bool, |
| 26 | blocked: bool = False, |
| 27 | target: str = "", |
| 28 | head_moved: bool = False, |
| 29 | executed: int = 0, |
| 30 | failed: int = 0, |
| 31 | plan_hash: str = "", |
| 32 | drift_severity: str = "", |
| 33 | drift_total_changes: int = 0, |
| 34 | status_code: int = 200, |
| 35 | ) -> None: |
| 36 | self.success = success |
| 37 | self.blocked = blocked |
| 38 | self.target = target |
| 39 | self.head_moved = head_moved |
| 40 | self.executed = executed |
| 41 | self.failed = failed |
| 42 | self.plan_hash = plan_hash |
| 43 | self.drift_severity = drift_severity |
| 44 | self.drift_total_changes = drift_total_changes |
| 45 | self.status_code = status_code |
| 46 | |
| 47 | def to_dict(self) -> dict[str, Any]: |
| 48 | return { |
| 49 | "success": self.success, |
| 50 | "blocked": self.blocked, |
| 51 | "target": self.target, |
| 52 | "head_moved": self.head_moved, |
| 53 | "executed": self.executed, |
| 54 | "plan_hash": self.plan_hash[:12] if self.plan_hash else "", |
| 55 | "drift_severity": self.drift_severity, |
| 56 | "drift_total_changes": self.drift_total_changes, |
| 57 | } |
| 58 | |
| 59 | |
| 60 | class MergeResult: |
| 61 | """Structured merge result.""" |
| 62 | |
| 63 | def __init__( |
| 64 | self, |
| 65 | success: bool, |
| 66 | merge_variation_id: str = "", |
| 67 | conflicts: list[dict[str, Any]] | None = None, |
| 68 | executed: int = 0, |
| 69 | status_code: int = 200, |
| 70 | ) -> None: |
| 71 | self.success = success |
| 72 | self.merge_variation_id = merge_variation_id |
| 73 | self.conflicts: list[dict[str, Any]] = conflicts or [] |
| 74 | self.executed = executed |
| 75 | self.status_code = status_code |
| 76 | |
| 77 | def to_dict(self) -> dict[str, Any]: |
| 78 | return { |
| 79 | "success": self.success, |
| 80 | "merge_variation_id": self.merge_variation_id, |
| 81 | "conflict_count": len(self.conflicts), |
| 82 | "conflicts": self.conflicts, |
| 83 | "executed": self.executed, |
| 84 | } |
| 85 | |
| 86 | |
| 87 | class MuseClient: |
| 88 | """Stub — the real client was extracted to cgcardona/muse. |
| 89 | |
| 90 | TODO(muse-extraction): re-integrate once Muse exposes a standalone HTTP API. |
| 91 | """ |
| 92 | |
| 93 | def __init__(self, config: Any, *args: Any, **kwargs: Any) -> None: |
| 94 | self._config = config |
| 95 | |
| 96 | async def close(self) -> None: |
| 97 | pass |
| 98 | |
| 99 | async def save_variation(self, *args: Any, **kwargs: Any) -> str: |
| 100 | raise NotImplementedError("MuseClient: extracted to cgcardona/muse — re-integrate via service API") |
| 101 | |
| 102 | async def set_head(self, *args: Any, **kwargs: Any) -> None: |
| 103 | raise NotImplementedError("MuseClient: extracted to cgcardona/muse — re-integrate via service API") |
| 104 | |
| 105 | async def get_log(self, *args: Any, **kwargs: Any) -> dict[str, Any]: |
| 106 | raise NotImplementedError("MuseClient: extracted to cgcardona/muse — re-integrate via service API") |
| 107 | |
| 108 | async def checkout(self, *args: Any, **kwargs: Any) -> CheckoutResult: |
| 109 | raise NotImplementedError("MuseClient: extracted to cgcardona/muse — re-integrate via service API") |
| 110 | |
| 111 | async def merge(self, *args: Any, **kwargs: Any) -> MergeResult: |
| 112 | raise NotImplementedError("MuseClient: extracted to cgcardona/muse — re-integrate via service API") |