- harden Matrix onboarding/chat lifecycle after manual QA - refresh README and Matrix docs to match current behavior - add local ignores for runtime artifacts and include current planning/report docs Closes #7 Closes #9 Closes #14
75 lines
2.1 KiB
Python
75 lines
2.1 KiB
Python
"""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()
|