diff --git a/dashboard/handlers/projects.py b/dashboard/handlers/projects.py index 17d815f..2ebc773 100644 --- a/dashboard/handlers/projects.py +++ b/dashboard/handlers/projects.py @@ -690,6 +690,35 @@ class ProjectsHandlers: """Dashboard planning sessions live in adapter='dashboard', channel=slug.""" return ("dashboard", slug) + @staticmethod + def _resolve_planning_key(slug: str) -> tuple[str, str]: + """Find the active session's (adapter, channel) for slug, regardless of + where it was started. Falls back to ('dashboard', slug) if nothing + matches — preserving prior behavior for the no-session case. + + Picks the most-recently-updated entry when multiple exist. + """ + try: + from src.planning_session import _load_planning_state # type: ignore + except Exception: + return ("dashboard", slug) + try: + all_state = _load_planning_state() + except Exception: + return ("dashboard", slug) + + matches = [ + entry for entry in all_state.values() + if (entry.get("slug") or "").lower() == slug.lower() + ] + if not matches: + return ("dashboard", slug) + matches.sort(key=lambda e: e.get("updated_at") or "", reverse=True) + best = matches[0] + adapter = best.get("adapter") or "dashboard" + channel = best.get("channel_id") or slug + return (adapter, channel) + # ── POST /api/projects//plan/start ────────────────────── def handle_plan_start(self, slug: str): if validate_slug(slug): @@ -793,7 +822,7 @@ class ProjectsHandlers: self.send_json({"error": "message required"}, 400) return - adapter, channel = self._planning_key(slug) + adapter, channel = self._resolve_planning_key(slug) try: from src.planning_orchestrator import PlanningOrchestrator # type: ignore session, text, phase_ready = PlanningOrchestrator.respond( @@ -915,7 +944,7 @@ class ProjectsHandlers: if validate_slug(slug): self.send_json({"error": "invalid_slug"}, 400) return - adapter, channel = self._planning_key(slug) + adapter, channel = self._resolve_planning_key(slug) try: from src.planning_session import get_planning_state, clear_planning_state # type: ignore from src.planning_orchestrator import PlanningOrchestrator # type: ignore @@ -964,7 +993,7 @@ class ProjectsHandlers: if validate_slug(slug): self.send_json({"error": "invalid_slug"}, 400) return - adapter, channel = self._planning_key(slug) + adapter, channel = self._resolve_planning_key(slug) try: from src.planning_orchestrator import PlanningOrchestrator # type: ignore except Exception as exc: @@ -992,7 +1021,7 @@ class ProjectsHandlers: if validate_slug(slug): self.send_json({"error": "invalid_slug"}, 400) return - adapter, channel = self._planning_key(slug) + adapter, channel = self._resolve_planning_key(slug) try: from src.planning_orchestrator import PlanningOrchestrator # type: ignore session, text, completed = PlanningOrchestrator.advance(adapter, channel)