build-small-hackathon/hackathon-advisor
16
1from __future__ import annotations2 3from typing import Any4 5from hackathon_advisor.tools import goal_label6from hackathon_advisor._text import clean as _clean, list_of_dicts as _list_of_dicts, utc_now7 8 9def build_chapter_markdown(session: dict[str, Any], metadata: dict[str, Any]) -> str:10 ideas = _list_of_dicts(session.get("ideas"))11 goals = _goal_labels(session.get("goals"))12 artifact = session.get("last_artifact") if isinstance(session.get("last_artifact"), dict) else {}13 lines = [14 "# The Unwritten Almanac Chapter",15 "",16 f"Generated: {utc_now()}",17 f"Snapshot: {_clean(metadata.get('snapshot_generated_at'))} · {_clean(metadata.get('project_count'))} pages",18 f"Goals: {', '.join(goals) if goals else 'No specific goals'}",19 "",20 ]21 22 if not ideas:23 lines.extend(["No idea pages have been written yet.", ""])24 return "\n".join(lines)25 26 for index, idea in enumerate(ideas, start=1):27 lines.extend(_idea_page(index, idea))28 29 caption = _clean(artifact.get("caption")) if artifact else ""30 if caption:31 lines.extend(["## Share Caption", "", caption, ""])32 return "\n".join(lines).rstrip() + "\n"33 34 35def _idea_page(index: int, idea: dict[str, Any]) -> list[str]:36 title = _clean(idea.get("title") or f"Page {index}")37 pitch = _clean(idea.get("pitch"))38 goals = _goal_labels(idea.get("goals"))39 score = idea.get("score") if isinstance(idea.get("score"), dict) else {}40 verdict = _clean(score.get("verdict")) if score else "DRAFT"41 overall = _clean(score.get("overall")) if score else "0.0"42 lines = [43 f"## Page {index}: {title}",44 "",45 f"Verdict: {verdict} · {overall}/10",46 f"Goals: {', '.join(goals) if goals else 'No specific goals'}",47 "",48 pitch or "No pitch recorded.",49 "",50 ]51 echoes = _list_of_dicts(score.get("echoes")) if score else []52 if echoes:53 lines.extend(["Closest cited pages:", ""])54 for echo in echoes[:3]:55 project = echo.get("project") if isinstance(echo.get("project"), dict) else {}56 page = _clean(echo.get("page_number")) or "?"57 project_title = _clean(project.get("title") or project.get("id") or "Untitled")58 url = _clean(project.get("url") or project.get("host") or "")59 score_text = _clean(echo.get("score"))60 if url:61 lines.append(f"- Page {page}: [{project_title}]({url}) · echo {score_text}")62 else:63 lines.append(f"- Page {page}: {project_title} · echo {score_text}")64 lines.append("")65 return lines66 67 68def _goal_labels(value: Any) -> list[str]:69 if not isinstance(value, list):70 return []71 return [goal_label(str(goal)) for goal in value]72 