From 4d6768e55cf68ace2f6a16898d359a79edbdd5f6 Mon Sep 17 00:00:00 2001 From: Mikkel Georgsen Date: Fri, 16 Jan 2026 15:33:31 +0000 Subject: [PATCH] docs(02): create phase plan for bot core Phase 02: Bot Core - 2 plans created (02-01 infrastructure, 02-02 handlers) - 6 total tasks defined - Ready for execution Co-Authored-By: Claude Opus 4.5 --- .planning/phases/02-bot-core/02-01-PLAN.md | 167 ++++++++++++++++++ .planning/phases/02-bot-core/02-02-PLAN.md | 192 +++++++++++++++++++++ 2 files changed, 359 insertions(+) create mode 100644 .planning/phases/02-bot-core/02-01-PLAN.md create mode 100644 .planning/phases/02-bot-core/02-02-PLAN.md diff --git a/.planning/phases/02-bot-core/02-01-PLAN.md b/.planning/phases/02-bot-core/02-01-PLAN.md new file mode 100644 index 0000000..1248f1b --- /dev/null +++ b/.planning/phases/02-bot-core/02-01-PLAN.md @@ -0,0 +1,167 @@ +--- +phase: 02-bot-core +plan: 01 +type: execute +--- + + +Set up Telegram bot infrastructure with Application builder, config loading, and handler registration pattern. + +Purpose: Establish the bot entry point and configuration loading so handlers can be added incrementally. +Output: Working bot main.py that starts, loads config, and registers handlers (empty initially). + + + +~/.claude/get-shit-done/workflows/execute-phase.md +~/.claude/get-shit-done/templates/summary.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/phases/01-foundation/01-03-SUMMARY.md +@src/moai/core/database.py +@pyproject.toml + +**Tech stack available:** +- SQLAlchemy async with aiosqlite (from Phase 1) +- python-telegram-bot (in dependencies, not yet used) + +**Established patterns:** +- Async context manager for sessions +- Module-level globals for engine/session factory + +**Constraining decisions:** +- Phase 1: Module-level globals for database (simple singleton) +- Phase 1: expire_on_commit=False for async sessions + + + + + + Task 1: Create bot configuration module + src/moai/bot/config.py + +Create config.py that loads bot configuration from environment variables: +- BOT_TOKEN (required): Telegram bot token +- ALLOWED_USERS (optional): Comma-separated list of Telegram user IDs for allowlist auth +- DATABASE_URL (optional): Database URL, defaults to sqlite+aiosqlite:///./moai.db +- LOG_LEVEL (optional): Logging level, defaults to INFO + +Use pydantic-settings or simple os.environ with dataclass. Keep it simple - use dataclass with classmethod from_env(). +Raise ValueError if BOT_TOKEN is missing. + +Do NOT use pydantic-settings - it adds a dependency. Use stdlib dataclass + os.environ. + + python -c "from moai.bot.config import BotConfig; print('Config module loads')" + BotConfig dataclass exists with from_env() classmethod, raises on missing BOT_TOKEN + + + + Task 2: Create bot main.py with Application setup + src/moai/bot/main.py + +Create main.py as the bot entry point using python-telegram-bot v21+ patterns: + +1. Import ApplicationBuilder from telegram.ext +2. Load config via BotConfig.from_env() +3. Create Application with ApplicationBuilder().token(config.bot_token).build() +4. Add post_init callback to initialize database (init_db, create_tables) +5. Add post_shutdown callback to close database (close_db) +6. Import and register handlers from handlers/ (empty for now, will add in 02-02) +7. Call app.run_polling() + +Structure: +```python +import logging +from telegram.ext import ApplicationBuilder +from moai.bot.config import BotConfig +from moai.core.database import init_db, create_tables, close_db + +logging.basicConfig(level=logging.INFO) +logger = logging.getLogger(__name__) + +async def post_init(application): + init_db(config.database_url) + await create_tables() + logger.info("Database initialized") + +async def post_shutdown(application): + await close_db() + logger.info("Database closed") + +def main(): + config = BotConfig.from_env() + app = ( + ApplicationBuilder() + .token(config.bot_token) + .post_init(post_init) + .post_shutdown(post_shutdown) + .build() + ) + # Handlers will be registered here in 02-02 + logger.info("Starting bot...") + app.run_polling() + +if __name__ == "__main__": + main() +``` + +Note: post_init receives the application as argument. Store config at module level or pass via application.bot_data. + + python -c "from moai.bot.main import main; print('Main module loads')" (will fail at runtime without BOT_TOKEN, but import should work) + main.py exists with ApplicationBuilder setup, post_init/post_shutdown hooks for database lifecycle + + + + Task 3: Create handlers package structure + src/moai/bot/handlers/__init__.py + +Create handlers/__init__.py with a register_handlers function that takes an Application and registers all handlers. + +For now, it's empty (no handlers yet), but the structure allows 02-02 to add handlers cleanly: + +```python +"""Telegram command handlers for MoAI bot.""" + +from telegram.ext import Application + +def register_handlers(app: Application) -> None: + """Register all command handlers with the application. + + Args: + app: The telegram Application instance. + """ + # Handlers will be imported and registered here + # from moai.bot.handlers import commands + # app.add_handler(CommandHandler("help", commands.help_command)) + pass +``` + +Update main.py to call register_handlers(app) before run_polling(). + + python -c "from moai.bot.handlers import register_handlers; print('Handlers package loads')" + handlers/__init__.py exists with register_handlers function, main.py calls it + + + + + +Before declaring plan complete: +- [ ] `python -c "from moai.bot.config import BotConfig"` succeeds +- [ ] `python -c "from moai.bot.main import main"` succeeds +- [ ] `python -c "from moai.bot.handlers import register_handlers"` succeeds +- [ ] `ruff check src/moai/bot/` passes +- [ ] All new files have docstrings + + + +- All tasks completed +- All verification checks pass +- Bot infrastructure ready for handler registration +- No TypeScript errors or ruff violations + + + +After completion, create `.planning/phases/02-bot-core/02-01-SUMMARY.md` using summary template. + diff --git a/.planning/phases/02-bot-core/02-02-PLAN.md b/.planning/phases/02-bot-core/02-02-PLAN.md new file mode 100644 index 0000000..2bbccfb --- /dev/null +++ b/.planning/phases/02-bot-core/02-02-PLAN.md @@ -0,0 +1,192 @@ +--- +phase: 02-bot-core +plan: 02 +type: execute +--- + + +Implement /help and /status command handlers completing M1 milestone. + +Purpose: Get the bot responding to basic commands, proving the infrastructure works end-to-end. +Output: Working /help and /status commands that respond in Telegram. + + + +~/.claude/get-shit-done/workflows/execute-phase.md +~/.claude/get-shit-done/templates/summary.md +~/.claude/get-shit-done/references/checkpoints.md + + + +@.planning/PROJECT.md +@.planning/ROADMAP.md +@.planning/phases/02-bot-core/02-01-SUMMARY.md (created in previous plan) +@src/moai/bot/main.py +@src/moai/bot/config.py +@src/moai/bot/handlers/__init__.py +@SPEC.md (for command format reference) + +**From SPEC.md:** +- /help - Show commands +- /status - Show current project/discussion state + +**Tech stack available:** +- python-telegram-bot v21+ with ApplicationBuilder +- Async handlers with Update, ContextTypes + +**Constraining decisions:** +- Phase 2-01: Handlers registered via register_handlers() in handlers/__init__.py + + + + + + Task 1: Create commands.py with /help and /start handlers + src/moai/bot/handlers/commands.py + +Create commands.py with help_command and start_command handlers: + +```python +"""Basic command handlers for MoAI bot.""" + +from telegram import Update +from telegram.ext import ContextTypes + +HELP_TEXT = """ +*MoAI - Master of AIs* + +Multi-AI collaborative brainstorming platform. + +*Project Commands:* +/projects - List all projects +/project new "Name" - Create new project +/project select - Switch to project +/project delete - Delete project +/project models claude,gpt - Set models +/project info - Show current project + +*Discussion Commands:* +/open - Ask all models (parallel) +/discuss [rounds] - Start discussion (default: 3) +/next - Trigger next round +/stop - Stop current discussion + +*Output Commands:* +/consensus - Generate consensus summary +/export - Export project as markdown + +*Utility:* +/status - Show current state +/help - Show this message +""".strip() + +async def start_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + """Handle /start command - welcome message.""" + await update.message.reply_text( + "Welcome to MoAI! 🤖\n\n" + "Use /help to see available commands.\n" + "Use /project new \"Name\" to create your first project." + ) + +async def help_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + """Handle /help command - show available commands.""" + await update.message.reply_text(HELP_TEXT, parse_mode="Markdown") +``` + +Note: Use Markdown parse_mode for formatting. Keep HELP_TEXT as a module constant for easy updates. + + python -c "from moai.bot.handlers.commands import help_command, start_command; print('Commands module loads')" + commands.py has start_command and help_command handlers with proper docstrings + + + + Task 2: Create status.py with /status handler + src/moai/bot/handlers/status.py + +Create status.py with status_command handler: + +```python +"""Status command handler for MoAI bot.""" + +from telegram import Update +from telegram.ext import ContextTypes + +async def status_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None: + """Handle /status command - show current project/discussion state. + + For now, shows a placeholder since project management isn't implemented yet. + Will be expanded in Phase 3 to show actual project state. + """ + # TODO: Phase 3 - Query actual project/discussion state from database + status_text = ( + "*MoAI Status*\n\n" + "Bot: ✅ Online\n" + "Database: ✅ Connected\n\n" + "_No project selected. Use /project new \"Name\" to create one._" + ) + await update.message.reply_text(status_text, parse_mode="Markdown") +``` + +This is a placeholder that will be enhanced in Phase 3 when project CRUD is implemented. + + python -c "from moai.bot.handlers.status import status_command; print('Status module loads')" + status.py has status_command handler with placeholder implementation + + + + Task 3: Register handlers in __init__.py + src/moai/bot/handlers/__init__.py + +Update handlers/__init__.py to import and register all command handlers: + +```python +"""Telegram command handlers for MoAI bot.""" + +from telegram.ext import Application, CommandHandler + +from moai.bot.handlers.commands import help_command, start_command +from moai.bot.handlers.status import status_command + + +def register_handlers(app: Application) -> None: + """Register all command handlers with the application. + + Args: + app: The telegram Application instance. + """ + # Basic commands + app.add_handler(CommandHandler("start", start_command)) + app.add_handler(CommandHandler("help", help_command)) + + # Status + app.add_handler(CommandHandler("status", status_command)) +``` + + python -c "from moai.bot.handlers import register_handlers; from telegram.ext import ApplicationBuilder; print('Handler registration ready')" + register_handlers imports and registers start, help, and status command handlers + + + + + +Before declaring plan complete: +- [ ] `python -c "from moai.bot.handlers.commands import help_command, start_command"` succeeds +- [ ] `python -c "from moai.bot.handlers.status import status_command"` succeeds +- [ ] `python -c "from moai.bot.handlers import register_handlers"` succeeds +- [ ] `ruff check src/moai/bot/` passes +- [ ] All handler files have module and function docstrings + + + +- All tasks completed +- All verification checks pass +- /start, /help, and /status handlers implemented +- Handlers registered via register_handlers() +- M1 milestone requirements met (bot responds to /help, /status) + + + +After completion, create `.planning/phases/02-bot-core/02-02-SUMMARY.md` using summary template. + +Note: Phase 2 complete after this plan. Ready for Phase 3 (Project CRUD). +