Add HeXi bot codebase: custom plugins, web frontends, tests

- hexi core: message handling, rate limiting, cooldown, plugin manager
- Custom plugins: BF stats, daily check-in, quotes, persona cards, etc.
- Community plugins vendored under hexi/plugins with local fixes
- Web admin frontends (learning-chat, persona-admin), unified hexi/web
- Tests for rate_limit/cooldown/memes/persona; poetry.lock

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-09-01 13:13:40 +08:00
co-authored by Claude
parent 1783c60afa
commit b61d09f09f
3201 changed files with 160436 additions and 171 deletions
@@ -0,0 +1,34 @@
"""模板目录的本地访问(NoneBot 版,避免引入 AstrBot 消息组件)。"""
from __future__ import annotations
from pathlib import Path
_TEMPLATES_DIR = (
Path(__file__).resolve().parent
/ "core"
/ "infrastructure"
/ "reporting"
/ "templates"
)
_ASSETS_DIR = Path(__file__).resolve().parent / "assets"
def list_templates() -> list[str]:
"""按字典序返回可用模板名,与设置模板的 1..N 编号一致。"""
if not _TEMPLATES_DIR.exists():
return []
return sorted(
d.name
for d in _TEMPLATES_DIR.iterdir()
if d.is_dir() and not d.name.startswith("__")
)
def template_exists(template: str) -> bool:
return (_TEMPLATES_DIR / template).is_dir()
def preview_image(template: str) -> Path | None:
p = _ASSETS_DIR / f"{template}-demo.jpg"
return p if p.exists() else None