"""Entry point for agent-core bot. Loads config from environment, optionally reads .env from workspace, builds and runs the Telegram bot. """ import logging import sys from pathlib import Path from core.bot import build_app from core.config import Config def _load_dotenv(workspace_dir: Path | None) -> None: """Load .env file from workspace directory if it exists.""" if not workspace_dir: return env_file = workspace_dir / ".env" if not env_file.exists(): return import os for line in env_file.read_text().splitlines(): line = line.strip() if not line or line.startswith("#"): continue if "=" not in line: continue key, _, value = line.partition("=") key = key.strip() value = value.strip().strip('"').strip("'") # Don't override existing env vars if key not in os.environ: os.environ[key] = value def main() -> None: logging.basicConfig( level=logging.INFO, format="%(asctime)s %(name)s %(levelname)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S", ) import os workspace_dir = os.environ.get("WORKSPACE_DIR") if workspace_dir: _load_dotenv(Path(workspace_dir)) try: config = Config.from_env() except ValueError as e: logging.error("Config error: %s", e) sys.exit(1) if config.workspace_dir: logging.info("Workspace: %s", config.workspace_dir) # Symlink workspace CLAUDE.md into data dir so Claude CLI finds it # when running in topic subdirectories claude_md_link = config.data_dir / "CLAUDE.md" claude_md_src = config.workspace_dir / "CLAUDE.md" if claude_md_src.exists() and not claude_md_link.exists(): claude_md_link.symlink_to(claude_md_src) logging.info("Symlinked CLAUDE.md into data dir") logging.info("Data dir: %s", config.data_dir) app = build_app(config) app.run_polling( allowed_updates=["message", "edited_message"], stop_signals=None, ) if __name__ == "__main__": main()