From a92c624dbac2accaf90a71d4ae44fcc68b8ee57f Mon Sep 17 00:00:00 2001 From: ZdenekSrotyr Date: Mon, 4 May 2026 17:46:50 +0200 Subject: [PATCH] feat(admin): yellow banner for legacy CLI verbs in workspace-prompt override --- app/web/router.py | 2 + app/web/templates/admin_workspace_prompt.html | 14 ++++++ tests/test_legacy_strings_scan.py | 48 +++++++++++++++++++ 3 files changed, 64 insertions(+) diff --git a/app/web/router.py b/app/web/router.py index e204d7d..fdae031 100644 --- a/app/web/router.py +++ b/app/web/router.py @@ -974,6 +974,7 @@ async def admin_workspace_prompt_page( ): from src.repositories.claude_md_template import ClaudeMdTemplateRepository from src.claude_md import compute_default_claude_md + from app.api.claude_md import _scan_legacy_strings row = ClaudeMdTemplateRepository(conn).get() server_url = str(request.base_url).rstrip("/") @@ -986,6 +987,7 @@ async def admin_workspace_prompt_page( updated_at=row["updated_at"], updated_by=row["updated_by"], is_override=row["content"] is not None, + legacy_strings_detected=_scan_legacy_strings(row["content"] or ""), ) return templates.TemplateResponse(request, "admin_workspace_prompt.html", ctx) diff --git a/app/web/templates/admin_workspace_prompt.html b/app/web/templates/admin_workspace_prompt.html index e8c1d2b..51206be 100644 --- a/app/web/templates/admin_workspace_prompt.html +++ b/app/web/templates/admin_workspace_prompt.html @@ -271,6 +271,20 @@ + {% if legacy_strings_detected %} + + {% endif %} +

Editor

diff --git a/tests/test_legacy_strings_scan.py b/tests/test_legacy_strings_scan.py index 73937b9..4120327 100644 --- a/tests/test_legacy_strings_scan.py +++ b/tests/test_legacy_strings_scan.py @@ -121,3 +121,51 @@ def test_admin_get_template_returns_empty_when_clean(web_session): resp = web_session.get("/api/admin/workspace-prompt-template") assert resp.status_code == 200, resp.text assert resp.json()["legacy_strings_detected"] == [] + + +# --------------------------------------------------------------------------- +# HTML banner tests — admin /admin/workspace-prompt page renders a yellow +# warning banner above the editor when the saved override contains stale +# CLI verbs / paths. +# --------------------------------------------------------------------------- + + +def test_admin_workspace_prompt_page_renders_banner_when_legacy_present(web_session): + """When the saved override contains legacy strings, the admin UI renders + a yellow warning banner above the editor listing the hits.""" + web_session.put( + "/api/admin/workspace-prompt-template", + json={"content": "Run `da sync` and check data/parquet/."}, + ) + resp = web_session.get("/admin/workspace-prompt") + assert resp.status_code == 200 + text = resp.text + # Banner is rendered (id, class, or distinctive styling) + assert "legacy-banner" in text or "renamed" in text.lower() or "warning" in text.lower() + # Specific hits appear in the banner content + assert "da sync" in text + assert "data/parquet" in text + + +def test_admin_workspace_prompt_page_no_banner_when_clean(web_session): + """When the override has no legacy strings, the banner block is absent + (or rendered as empty/hidden).""" + web_session.put( + "/api/admin/workspace-prompt-template", + json={"content": "Use `agnes pull` and `server/parquet/`."}, + ) + resp = web_session.get("/admin/workspace-prompt") + assert resp.status_code == 200 + text = resp.text + # The banner div should not appear (or its content should not list hits) + # Pin to the legacy-banner id; the {% if %} guard means absent when clean + assert "legacy-banner" not in text + + +def test_admin_workspace_prompt_page_no_banner_when_no_override(web_session): + """No saved override at all → banner absent.""" + # Reset to default by deleting any existing override + web_session.delete("/api/admin/workspace-prompt-template") + resp = web_session.get("/admin/workspace-prompt") + assert resp.status_code == 200 + assert "legacy-banner" not in resp.text