feat: Phase 2 — web server, REST API, WebSocket/SSE, UI [v0.2.0]

AsyncEventBridge bridges sync EventEmitter to asyncio consumers.
FastAPI app with session management, discussion control, roles/providers.
WebSocket for real-time events + inject, SSE for read-only streaming.
Minimal dark-theme HTML/JS UI. `meeting-room serve` CLI subcommand.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-04 08:50:04 +03:00
parent 069462953b
commit 1dffaae822
13 changed files with 1393 additions and 6 deletions

View File

@@ -426,6 +426,11 @@ def main():
init_parser = subparsers.add_parser("init", help="Initialize .meeting-room workspace")
init_parser.add_argument("path", nargs="?", default=".", help="Where to create .meeting-room")
serve_parser = subparsers.add_parser("serve", help="Start web server")
serve_parser.add_argument("--host", default="0.0.0.0", help="Host to bind (default: 0.0.0.0)")
serve_parser.add_argument("--port", type=int, default=8000, help="Port to bind (default: 8000)")
serve_parser.add_argument("--reload", action="store_true", help="Enable auto-reload for development")
args = parser.parse_args()
# Handle init command
@@ -433,6 +438,18 @@ def main():
init_workspace(args.path)
return
# Handle serve command
if args.command == "serve":
import uvicorn
from meeting_room.server import app
uvicorn.run(
"meeting_room.server:app" if args.reload else app,
host=args.host,
port=args.port,
reload=args.reload,
)
return
# Find config: CLI arg > .meeting-room/config.yaml > package default
if args.config:
config = load_config(args.config)