fix(workflows): escape rich markup in search output

workflow search now escapes catalog-derived name/id/version/description/
tags before printing, matching extension search and workflow list.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
marcelsafin
2026-07-10 08:38:12 +02:00
parent 129362f29b
commit 4ca50f588b
2 changed files with 34 additions and 3 deletions

View File

@@ -1197,13 +1197,17 @@ def workflow_search(
console.print(f"\n[bold cyan]Workflows ({len(results)}):[/bold cyan]\n")
for wf in results:
console.print(f" [bold]{wf.get('name', wf.get('id', '?'))}[/bold] ({wf.get('id', '?')}) v{wf.get('version', '?')}")
name = _escape_markup(str(wf.get("name", wf.get("id", "?"))))
wf_id = _escape_markup(str(wf.get("id", "?")))
version = _escape_markup(str(wf.get("version", "?")))
console.print(f" [bold]{name}[/bold] ({wf_id}) v{version}")
desc = wf.get("description", "")
if desc:
console.print(f" {desc}")
console.print(f" {_escape_markup(str(desc))}")
tags = wf.get("tags", [])
if tags:
console.print(f" [dim]Tags: {', '.join(tags)}[/dim]")
safe_tags = _escape_markup(", ".join(str(t) for t in tags))
console.print(f" [dim]Tags: {safe_tags}[/dim]")
console.print()

View File

@@ -7379,6 +7379,33 @@ steps:
assert "wf-a" in result.output
assert "wf-b" not in result.output
def test_search_escapes_rich_markup_in_catalog_fields(self, project_dir, monkeypatch):
"""Catalog-derived name/description/tags must not be parsed as Rich markup."""
from typer.testing import CliRunner
from specify_cli import app
from specify_cli.workflows.catalog import WorkflowCatalog
monkeypatch.chdir(project_dir)
workflows = {
"wf-a": {
"name": "Bracket [Search]",
"version": "1.0.0",
"description": "desc [with] brackets",
"tags": ["tag[1]", "tag2"],
},
}
monkeypatch.setattr(
WorkflowCatalog,
"_get_merged_workflows",
lambda self, force_refresh=False: {k: dict(v) for k, v in workflows.items()},
)
runner = CliRunner()
result = runner.invoke(app, ["workflow", "search"])
assert result.exit_code == 0, result.output
assert "Bracket [Search]" in result.output
assert "desc [with] brackets" in result.output
assert "tag[1]" in result.output
# -- update ----------------------------------------------------------
def test_update_no_workflows_installed(self, project_dir, monkeypatch):