--- phase: 06-consensus-export plan: 02 type: execute --- Implement markdown export for discussions and projects. Purpose: Enable users to export discussion history and consensus to shareable markdown documents (M7 milestone). Output: Working /export command that generates and sends markdown files via Telegram. ~/.claude/get-shit-done/workflows/execute-phase.md ~/.claude/get-shit-done/templates/summary.md @.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md # Prior plan context: @.planning/phases/06-consensus-export/06-01-SUMMARY.md # Source files to reference: @src/moai/core/models.py @src/moai/core/services/discussion.py @src/moai/core/services/project.py @src/moai/bot/handlers/__init__.py @src/moai/bot/handlers/commands.py **Tech stack available:** python-telegram-bot, sqlalchemy **Established patterns:** Service layer, handler registration, get_selected_project helper **SPEC.md export format:** ```markdown # {Project Name} **Date:** {date} **Models:** Claude, GPT, Gemini **Discussions:** {count} --- ## Discussion 1: {Question} ### Initial Responses (Open) **Claude:** > {response} ### Discussion (N rounds) **Round 1:** **Claude:** {response} **GPT:** {response} ### Consensus **Agreements:** - point 1 **Disagreements:** - **Topic:** {topic} - Claude: {position} ``` Task 1: Create exporter module src/moai/core/exporter.py Create new file src/moai/core/exporter.py with: 1. Module docstring explaining markdown export functionality. 2. `export_discussion(discussion: Discussion) -> str` function: - Format discussion as markdown following SPEC format - Include question as heading - Group messages by round, label round type (parallel = "Initial Responses", sequential = "Round N") - Format each message as `**Model:** response` - Include consensus section if consensus exists (agreements as bullets, disagreements with positions) - Return markdown string 3. `export_project(project: Project, discussions: list[Discussion]) -> str` function: - Header with project name, date, models list, discussion count - Separator (---) - Each discussion formatted via export_discussion() - Separators between discussions - Return full markdown string 4. Helper `_format_consensus(consensus: Consensus) -> str`: - Format agreements as bullet list - Format disagreements with topic and model positions - Return formatted string or empty if no consensus Use datetime.now().strftime("%Y-%m-%d") for date formatting. `python -c "from moai.core.exporter import export_discussion, export_project"` succeeds Exporter module creates properly formatted markdown matching SPEC format Task 2: Create /export command handler src/moai/bot/handlers/export.py, src/moai/bot/handlers/__init__.py, src/moai/bot/handlers/commands.py 1. Create new file src/moai/bot/handlers/export.py with: - Import exporter functions, services, telegram types - `export_command(update, context)` handler: - Get selected project (error if none) - Parse args: no args = export active discussion, "project" = export full project - For discussion export: - Get active discussion (error if none) - Call export_discussion() - Send as document: `update.message.reply_document(io.BytesIO(md.encode()), filename=f"{project.name}-discussion.md")` - For project export: - Get all discussions for project via list_discussions() - Fetch each with full eager loading via get_discussion() - Call export_project() - Send as document with filename `{project.name}-export.md` - Use io.BytesIO for in-memory file, import io module 2. Update handlers/__init__.py: - Import export_command from export module - Register `CommandHandler("export", export_command)` 3. Update HELP_TEXT in commands.py, Output section: `/export` - Export current discussion as markdown `/export project` - Export entire project as markdown Bot responds to /export with a markdown document attachment /export sends discussion markdown, /export project sends full project markdown as Telegram documents Before declaring plan complete: - [ ] `ruff check src/moai/core/exporter.py src/moai/bot/handlers/export.py` - [ ] `python -c "from moai.core.exporter import export_discussion, export_project"` succeeds - [ ] `python -c "from moai.bot.handlers.export import export_command"` succeeds - Exporter module generates SPEC-compliant markdown - /export sends discussion as .md document - /export project sends full project as .md document - Help text updated - No ruff errors - Phase 6 complete (M6 + M7 milestones) After completion, create `.planning/phases/06-consensus-export/06-02-SUMMARY.md`