mirror of
https://github.com/himanshudongre/smriti.git
synced 2026-08-28 05:14:59 +00:00
Render list-valued blocked_by consistently in state --compact
`smriti current` already normalizes a list-valued blocked_by to a clean comma-separated string via the backend CurrentTask validator, but `smriti state` rendered it through an f-string and leaked the raw Python list repr (['a', 'b']) into the state brief — the surface agents read at session start. Add a `_coerce_blocked_by` helper in the CLI formatters mirroring that validator, and apply it in `_normalize_task_item` so every `smriti state` task line renders blocked_by the same way `smriti current` does. Adds regression tests.
This commit is contained in:
parent
c43310caa1
commit
eb60d03f4b
2 changed files with 39 additions and 0 deletions
|
|
@ -120,6 +120,25 @@ def _list_section(heading: str, items: list[str]) -> str:
|
||||||
return "\n".join(lines) + "\n"
|
return "\n".join(lines) + "\n"
|
||||||
|
|
||||||
|
|
||||||
|
def _coerce_blocked_by(value: object) -> str | None:
|
||||||
|
"""Normalize blocked_by — string, list of dependency labels, or null —
|
||||||
|
to a single display string.
|
||||||
|
|
||||||
|
Real task payloads carry blocked_by as a plain string or as a list (a
|
||||||
|
task blocked by several others). Mirrors the backend CurrentTask
|
||||||
|
validator so `smriti state` and `smriti current` render it identically
|
||||||
|
instead of leaking a raw Python list repr into the state brief.
|
||||||
|
"""
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
if isinstance(value, str):
|
||||||
|
return value.strip() or None
|
||||||
|
if isinstance(value, (list, tuple)):
|
||||||
|
labels = [str(item).strip() for item in value if str(item).strip()]
|
||||||
|
return ", ".join(labels) or None
|
||||||
|
return str(value).strip() or None
|
||||||
|
|
||||||
|
|
||||||
def _normalize_task_item(item) -> dict:
|
def _normalize_task_item(item) -> dict:
|
||||||
"""Normalize a task to a dict with at least a 'text' key.
|
"""Normalize a task to a dict with at least a 'text' key.
|
||||||
|
|
||||||
|
|
@ -131,6 +150,8 @@ def _normalize_task_item(item) -> dict:
|
||||||
task = dict(item)
|
task = dict(item)
|
||||||
if not task.get("intent_hint") and task.get("intent_type"):
|
if not task.get("intent_hint") and task.get("intent_type"):
|
||||||
task["intent_hint"] = task["intent_type"]
|
task["intent_hint"] = task["intent_type"]
|
||||||
|
if "blocked_by" in task:
|
||||||
|
task["blocked_by"] = _coerce_blocked_by(task["blocked_by"])
|
||||||
return task
|
return task
|
||||||
# Fallback: coerce to string
|
# Fallback: coerce to string
|
||||||
return {"text": str(item)}
|
return {"text": str(item)}
|
||||||
|
|
|
||||||
|
|
@ -504,6 +504,13 @@ def test_normalize_task_item_dict():
|
||||||
assert result == task
|
assert result == task
|
||||||
|
|
||||||
|
|
||||||
|
def test_normalize_task_item_coerces_list_blocked_by():
|
||||||
|
"""A list-valued blocked_by is normalized to a comma-separated string."""
|
||||||
|
task = {"text": "Wire the limiter", "blocked_by": ["middleware", "load-test"]}
|
||||||
|
result = _normalize_task_item(task)
|
||||||
|
assert result["blocked_by"] == "middleware, load-test"
|
||||||
|
|
||||||
|
|
||||||
def test_task_section_empty():
|
def test_task_section_empty():
|
||||||
"""Empty task list produces empty string."""
|
"""Empty task list produces empty string."""
|
||||||
assert _task_section([]) == ""
|
assert _task_section([]) == ""
|
||||||
|
|
@ -547,6 +554,17 @@ def test_task_section_structured_with_blocked_by():
|
||||||
assert "→ blocked by: freshness-impl" in out
|
assert "→ blocked by: freshness-impl" in out
|
||||||
|
|
||||||
|
|
||||||
|
def test_task_section_renders_list_valued_blocked_by():
|
||||||
|
"""A list-valued blocked_by renders as a clean comma-separated string,
|
||||||
|
not a raw Python list repr — consistent with `smriti current`."""
|
||||||
|
tasks = [
|
||||||
|
{"text": "Wire the limiter", "blocked_by": ["middleware", "load-test"]},
|
||||||
|
]
|
||||||
|
out = _task_section(tasks)
|
||||||
|
assert "→ blocked by: middleware, load-test" in out
|
||||||
|
assert "['" not in out # not the raw Python list repr
|
||||||
|
|
||||||
|
|
||||||
def test_task_section_structured_with_done_status():
|
def test_task_section_structured_with_done_status():
|
||||||
"""Task with status=done renders inline marker."""
|
"""Task with status=done renders inline marker."""
|
||||||
tasks = [
|
tasks = [
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue