- Add DingTalk access-token management (_dingtalk_fetch_access_token,
_dingtalk_fetch_oapi_token) with process-wide cache, 5 min safety
margin, and asyncio.Lock for concurrent safety.
- Add _dingtalk_upload_media() — upload local files to /media/upload
(legacy OAPI token) with mime auto-detection and 20 MB guard.
- Add _dingtalk_classify_chat_id() — route on chat_id shape:
'cidXXX==' → group /groupMessages/send, plain staffId or
'user:<staffId>' → 1:1 /oToMessages/batchSend.
- Add dingtalk_send_proactive() orchestrator — text + media delivery.
- In send(), fall back to dingtalk_send_proactive() when no session
webhook is cached (proactive/cron/cross-platform delivery).
- Fix /sethome DM chat_id: persist 'user:<staffId>' instead of DM
conversation_id so proactive DM delivery works (gateway/run.py).
- Enhance send_message_tool.py: MEDIA:<path> tag extraction, native
DingTalk/Feishu routing with media_files support.
- Update test assertions for proactive-send error path.
Adds 15 regression tests for hermes_cli/dingtalk_auth.py covering:
* _api_post — network error mapping, errcode-nonzero mapping, success path
* begin_registration — 2-step chain, missing-nonce/device_code/uri
error cases
* wait_for_registration_success — success path, missing-creds guard,
on_waiting callback invocation
* render_qr_to_terminal — returns False when qrcode missing, prints
when available
* Configuration — BASE_URL default + override, SOURCE default
Also adds a one-line disclosure in dingtalk_qr_auth() telling users
the scan page will be OpenClaw-branded. Interim measure: DingTalk's
registration portal is hardcoded to route all sources to /openapp/
registration/openClaw, so users see OpenClaw branding regardless of
what 'source' value we send. We keep 'openClaw' as the source token
until DingTalk-Real-AI registers a Hermes-specific template.
Also adds meng93 to scripts/release.py AUTHOR_MAP.