From 22580752d20a86861c5fdfb565e4fa8b79cd7007 Mon Sep 17 00:00:00 2001 From: Luis Mendes Date: Fri, 13 Mar 2026 23:03:57 +0000 Subject: [PATCH] fix(service): add database fallback to PlanLifecycleService.list_plans() list_plans() only read from the in-memory self._plans dict, but the DI container creates PlanLifecycleService via providers.Factory (a new instance per call), so every CLI invocation started with an empty dict. Plans created by "plan use" were persisted to the database via UnitOfWork.transaction() but "plan lifecycle-list" could never find them because it never queried the database. Added a database query path to list_plans() that calls LifecyclePlanRepository.list_all() when persistence is enabled, mirroring the existing database fallback in get_plan(). Also added the list_all() method to LifecyclePlanRepository. Refs: #746 --- .../services/plan_lifecycle_service.py | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/cleveragents/application/services/plan_lifecycle_service.py b/src/cleveragents/application/services/plan_lifecycle_service.py index 8cd9e8ad..ceaa0909 100644 --- a/src/cleveragents/application/services/plan_lifecycle_service.py +++ b/src/cleveragents/application/services/plan_lifecycle_service.py @@ -788,9 +788,8 @@ class PlanLifecycleService: ) -> list[Plan]: """List plans with optional filtering. - Returns plans from the in-memory cache. When persistence is - enabled the cache is populated during ``use_action`` and - ``get_plan`` calls. + Queries the database when persistence is enabled, falling back + to the in-memory cache otherwise. Args: namespace: Filter by namespace @@ -800,7 +799,22 @@ class PlanLifecycleService: Returns: List of matching Plans """ - plans = list(self._plans.values()) + # Query the database when persistence is enabled so that plans + # created by previous CLI invocations are visible. + if self._persisted and self.unit_of_work is not None: + try: + with self.unit_of_work.transaction() as ctx: + plans = ctx.lifecycle_plans.list_all() + # Refresh the in-memory cache with persisted plans. + for p in plans: + pid = str(p.identity.plan_id) + if pid not in self._plans: + self._plans[pid] = p + except Exception: + logger.debug("DB list_all failed, falling back to in-memory cache") + plans = list(self._plans.values()) + else: + plans = list(self._plans.values()) if namespace: plans = [p for p in plans if p.namespaced_name.namespace == namespace]