butler/blackboard/snapshot.py
Rama main · réplica de lectura del repositorio original.
"""从 shifts/ + tasks/ 派生 state.md 摘要。"""
from __future__ import annotations
from datetime import datetime
from butler.blackboard.shift_io import list_shift_cards
from butler.blackboard.task_io import list_claims, load_backlog
def render_snapshot(now: datetime | None = None) -> str:
"""生成完整 state.md 文本(不写盘)。"""
now = now or datetime.now()
last_synced = now.strftime("%Y-%m-%d %H:%M")
cards = list_shift_cards()
last_shift = cards[-1].shift_id if cards else "(none)"
in_progress_lines: list[str] = []
for claim in list_claims():
if claim.status.value in ("claimed", "in_progress"):
in_progress_lines.append(
f"- [{claim.task_id}] ({claim.claimed_by}) status={claim.status.value}"
)
blocked_lines: list[str] = []
try:
bf = load_backlog()
for t in bf.tasks:
if t.status.value == "blocked":
blocked_lines.append(f"- [{t.id}] {t.title}")
except FileNotFoundError:
pass
recent_lines = [
f"- {c.shift_id}: {c.intent[:60]}"
for c in cards[-5:]
]
sections = [
"# WFXM BlackBoard State",
"",
f"_last_synced: {last_synced}_",
f"_last_shift: {last_shift}_",
"",
"## 进行中",
*(in_progress_lines or ["(暂无)"]),
"",
"## 待仲裁 / 阻塞",
*(blocked_lines or ["(暂无)"]),
"",
"## 待认领",
"- 详见 `tasks/backlog.yaml`",
"",
"## 最近 5 个班次",
*(recent_lines or ["(暂无)"]),
"",
]
return "\n".join(sections)
def build_snapshot_markdown() -> str:
"""render_snapshot 的别名,方便 CLI 调用。"""
return render_snapshot()