* feat: per-group timezone architecture with context injection (#483)
Implement a comprehensive timezone consistency layer so the AI agent always
receives timestamps in the user's local timezone. The framework handles all
UTC↔local conversion transparently — the agent never performs manual timezone
math.
Key changes:
- Per-group timezone stored in containerConfig (no DB migration needed)
- Context injection: <context timezone="..." current_time="..." /> header
prepended to every agent prompt with local time and IANA timezone
- Message timestamps converted from UTC to local display in formatMessages()
- schedule_task translation layer: agent writes local times, framework
converts to UTC using per-group timezone for cron, once, and interval types
- Container TZ env var now uses per-group timezone instead of global constant
- New set_timezone MCP tool for users to update their timezone dynamically
- NANOCLAW_TIMEZONE passed to MCP server environment for tool confirmations
Architecture: Store UTC everywhere, convert at boundaries (display to agent,
parse from agent). Groups without timezone configured fall back to the server
TIMEZONE constant for full backward compatibility.
Closes#483Closes#526
Co-authored-by: shawnYJ <shawny011717@users.noreply.github.com>
Co-authored-by: Adrian <Lafunamor@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* style: apply prettier formatting
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: strip to minimalist context injection — global TIMEZONE only
Remove per-group timezone support, set_timezone MCP tool, and all
related IPC handlers. The implementation now uses the global system
TIMEZONE for all groups, keeping the diff focused on the message
formatting layer: mandatory timezone param in formatMessages(),
<context> header injection, and formatLocalTime/formatCurrentTime
helpers.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* refactor: drop formatCurrentTime and simplify context header
Address PR review: remove redundant formatCurrentTime() since message
timestamps already carry localized times. Simplify <context> header to
only include timezone name.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
---------
Co-authored-by: shawnYJ <shawny011717@users.noreply.github.com>
Co-authored-by: Adrian <Lafunamor@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>