Private
Public Access
0
0

feat(api_hooks): add /api/project_switch_status endpoint for deterministic test signaling

Adds a new endpoint that exposes the project-switch state machine so tests
can poll for completion instead of guessing with timeouts.

- AppController: track _project_switch_error on failure paths
- src/api_hooks.py: GET /api/project_switch_status returns
  {in_progress, pending_path, active_path, error}
- src/api_hook_client.py: get_project_switch_status() helper
- tests/test_api_hooks_project_switch.py: 3 unit tests for client + endpoint
  shape, 1 live_gui test for the default-idle case
This commit is contained in:
2026-06-08 09:55:36 -04:00
parent c531cebe03
commit abb3856525
4 changed files with 91 additions and 0 deletions
+4
View File
@@ -803,6 +803,7 @@ class AppController:
self._project_switch_lock: threading.Lock = threading.Lock()
self._project_switch_in_progress: bool = False
self._project_switch_pending_path: Optional[str] = None
self._project_switch_error: Optional[str] = None
# --- Shared background pool + proactive warmup (startup_speedup_20260606) ---
self._io_pool = make_io_pool()
_install_sigint_exit_handler(self)
@@ -2690,12 +2691,14 @@ class AppController:
self.ai_status = "config saved"
def _do_project_switch(self, path: str) -> None:
self._project_switch_error = None
try:
self._flush_to_project()
try:
new_project = project_manager.load_project(path)
except Exception as e:
self.ai_status = f"failed to load project: {e}"
self._project_switch_error = f"load failed: {e}"
return
try:
self.project = new_project
@@ -2707,6 +2710,7 @@ class AppController:
self.persona_manager = PersonaManager(new_root)
except Exception as e:
self.ai_status = f"failed to init managers: {e}"
self._project_switch_error = f"manager init failed: {e}"
return
self._refresh_from_project()
file_items_as_dicts = [{"path": f.path if hasattr(f, "path") else str(f)} for f in self.files]