Setup skill fixes:
- Run QR auth in foreground with long timeout, not background
- Replace fragile message-based registration with DB group sync lookup
- Personal chats: ask for phone number instead of querying empty DB
- Consolidate trigger word + security model + channel selection into one step
- Remove `timeout` shell command (unavailable on macOS), use Bash tool timeout
- Query 40 groups, display 10 at a time, support name lookup
requiresTrigger support:
- Add requiresTrigger field to RegisteredGroup type and DB schema
- Skip trigger check when requiresTrigger is false (for solo/personal chats)
- Main group still always processes all messages (unchanged)
Agent-browser visibility:
- Append global CLAUDE.md to non-main agent system prompts via SDK
- Add browser tool docs to global and main CLAUDE.md
- Update skill description to be broader (not just "web testing")
- Reference agent-browser.md in root CLAUDE.md key files
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add per-group container locking with global concurrency limit to prevent
concurrent containers for the same group (#89) and cap total containers.
Fix message batching bug where lastAgentTimestamp advanced to trigger
message instead of latest in batch, causing redundant re-processing.
Move router state, sessions, and registered groups from JSON files to
SQLite with automatic one-time migration. Add SIGTERM/SIGINT handlers
with graceful shutdown (SIGTERM -> grace period -> SIGKILL). Add startup
recovery for messages missed during crash. Remove dead code: utils.ts,
Session type, isScheduledTask flag, ContainerConfig.env, getTaskRunLogs,
GroupQueue.isActive.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
updateChatName() was inserting new groups with last_message_time set to
Unix epoch (1970-01-01), causing newly discovered groups to appear at
the bottom of activity-ordered listings. Changed to use current time
for new groups while preserving existing timestamps for known groups.
https://claude.ai/code/session_018rcZvALfF3ND2jfcvBaFo2
Co-authored-by: Claude <noreply@anthropic.com>
- Add TIMEZONE config using system timezone for cron expressions
- Filter bot messages by content prefix instead of is_from_me
(user shares WhatsApp account with bot)
- Format messages as XML for cleaner agent parsing
- Update schedule_task tool to clarify local time usage
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Sync group names from WhatsApp via groupFetchAllParticipating()
- Store group names in chats table (jid -> name mapping)
- Daily sync with 24h cache, on-demand refresh via IPC
- Write available_groups.json snapshot for agent (main group only)
- Agent can request refresh_groups via IPC if group not found
- Update documentation in main CLAUDE.md and debug skill
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Scheduled tasks can now run in either:
- "group" mode: uses the group's conversation session for context
- "isolated" mode: runs with a fresh session (previous behavior)
The tool description guides the agent on when to use each mode and
prompts them to ask the user if unclear. Group mode is now the default.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Delete child records (task_run_logs) before parent (scheduled_tasks) to avoid foreign key constraint violation when cancelling tasks.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Keep only comments that explain non-obvious behavior or add context
not apparent from reading the code.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add authorization checks to IPC task operations (pause/resume/cancel)
to prevent cross-group task manipulation
- Only store message content for registered groups; unregistered chats
only get metadata stored for group discovery
- Container logs now only include full input/output in debug mode;
default logging omits sensitive message content
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Custom nanoclaw MCP server with scheduling tools (schedule_task,
list_tasks, get_task, update_task, pause/resume/cancel_task, send_message)
- Tasks run as full agents in their group's context
- Support for cron, interval, and one-time schedules
- Task run logging with duration and results
- Main channel has Bash access for admin tasks (query DB, manage groups)
- Other groups restricted to file operations only
- Updated docs and requirements
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use pushName from baileys to get the sender's display name instead
of just the phone number. Falls back to phone number if no name.
Includes migration to add sender_name column to existing databases.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a triggered message comes in, fetch all messages in that chat
since the last agent interaction and include them in the prompt.
Each message is formatted with timestamp and sender.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- src/db.ts: initDatabase, closeDatabase, storeMessage, getNewMessages
- Removes SQL from index.ts
- Database initialization happens once at startup
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>