fix: escape workflow step metadata (#3863)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Marsel Safin
2026-07-30 18:10:22 +02:00
committed by GitHub
parent 81bf741b92
commit 0f3f2aa45e
2 changed files with 133 additions and 18 deletions

View File

@@ -2576,9 +2576,10 @@ def workflow_step_list():
console.print(" [bold]Custom (installed):[/bold]")
for key in sorted(installed):
meta = installed[key] or {}
name = meta.get("name", key)
version = meta.get("version", "?")
console.print(f" • [bold]{name}[/bold] ({key}) v{version}")
name = _escape_markup(str(meta.get("name", key)))
safe_key = _escape_markup(str(key))
version = _escape_markup(str(meta.get("version", "?")))
console.print(f" • [bold]{name}[/bold] ({safe_key}) v{version}")
console.print()
if not built_in and not installed:
@@ -3122,13 +3123,15 @@ def workflow_step_search(
install_note = (
"" if step.get("_install_allowed", True) else " [dim](discovery only)[/dim]"
)
name = _escape_markup(str(step.get("name", step.get("id", "?"))))
step_id = _escape_markup(str(step.get("id", "?")))
version = _escape_markup(str(step.get("version", "?")))
console.print(
f" [bold]{step.get('name', step.get('id', '?'))}[/bold]"
f" ({step.get('id', '?')}) v{step.get('version', '?')}{install_note}"
f" [bold]{name}[/bold] ({step_id}) v{version}{install_note}"
)
desc = step.get("description", "")
if desc:
console.print(f" {desc}")
console.print(f" {_escape_markup(str(desc))}")
console.print()
@@ -3141,6 +3144,7 @@ def workflow_step_info(
from .catalog import StepCatalog, StepCatalogError, StepRegistry
project_root = _require_specify_project()
safe_step_id = _escape_markup(str(step_id))
registry = StepRegistry(project_root)
installed_meta = registry.get(step_id)
@@ -3150,20 +3154,27 @@ def workflow_step_info(
is_builtin = builtin_step is not None and not installed_meta
if is_builtin:
console.print(f"\n[bold cyan]{step_id}[/bold cyan] [dim](built-in)[/dim]")
console.print(f" Type key: {step_id}")
console.print(f"\n[bold cyan]{safe_step_id}[/bold cyan] [dim](built-in)[/dim]")
console.print(f" Type key: {safe_step_id}")
console.print(" [green]Built-in step type[/green]")
return
if installed_meta:
name = _escape_markup(str(installed_meta.get("name", step_id)))
version = _escape_markup(str(installed_meta.get("version", "?")))
console.print(
f"\n[bold cyan]{installed_meta.get('name', step_id)}[/bold cyan] ({step_id})"
f"\n[bold cyan]{name}[/bold cyan] ({safe_step_id})"
)
console.print(f" Version: {installed_meta.get('version', '?')}")
console.print(f" Version: {version}")
if installed_meta.get("author"):
console.print(f" Author: {installed_meta['author']}")
console.print(
f" Author: {_escape_markup(str(installed_meta['author']))}"
)
if installed_meta.get("description"):
console.print(f" Description: {installed_meta['description']}")
console.print(
f" Description: "
f"{_escape_markup(str(installed_meta['description']))}"
)
console.print(" [green]Installed[/green]")
return
@@ -3175,20 +3186,24 @@ def workflow_step_info(
info = None
if info:
name = _escape_markup(str(info.get("name", step_id)))
version = _escape_markup(str(info.get("version", "?")))
console.print(
f"\n[bold cyan]{info.get('name', step_id)}[/bold cyan] ({step_id})"
f"\n[bold cyan]{name}[/bold cyan] ({safe_step_id})"
)
console.print(f" Version: {info.get('version', '?')}")
console.print(f" Version: {version}")
if info.get("author"):
console.print(f" Author: {info['author']}")
console.print(f" Author: {_escape_markup(str(info['author']))}")
if info.get("description"):
console.print(f" Description: {info['description']}")
console.print(
f" Description: {_escape_markup(str(info['description']))}"
)
console.print(" [yellow]Not installed[/yellow]")
console.print(
f"\n Install with: [cyan]specify workflow step add {step_id}[/cyan]"
f"\n Install with: [cyan]specify workflow step add {safe_step_id}[/cyan]"
)
else:
console.print(f"[red]Error:[/red] Step type '{step_id}' not found")
console.print(f"[red]Error:[/red] Step type '{safe_step_id}' not found")
raise typer.Exit(1)