{"skill":{"slug":"water-coach","displayName":"Water Coach","summary":"Hydration tracking and coaching skill. Use when user wants to track water intake, get reminders to drink water, log body metrics (weight, body fat, muscle %,...","description":"---\nname: water-coach\ndescription: \"Hydration tracking and coaching skill. Use when user wants to track water intake, get reminders to drink water, log body metrics, or get analytics on hydration habits.\"\ncompatibility: \"Requires python3, openclaw cron feature, heartbeat feature\"\nmetadata: {\"clawdbot\":{\"emoji\":\"💧\"} \n  author: oristides\n---\n\n# 💧 Water Coach\n\n\n\n## First-time Setup \n\nFollow the first setup here [references/setup.md](references/setup.md)\n\n---\n\n## 🤖 How Other Agents Should Interact\n\n### First-time Setup Check\n```bash\nwater setup\n```\n\n| is_setup | What to do |\n|----------|-------------|\n| **false** | Ask: weight OR desired goal. Also ask: \"What times do you want water reminders?\" (let user configure their schedule). Then use `water set_body_weight 80` or `water set_goal 3000`. Don't assume hardcoded times! |\n| **true** | Skip setup. Just log water or show status. |\n\n### ❌ Don't Ask\n- Reminder schedules after first setup (user already configured)\n\n### ✅ Do Ask  \n- \"How much water did you drink?\"\n- Only weight/goal (first time)\n\n---\n\n## CLI Structure\n\n```bash\nwater_coach.py <namespace> <command> [options]\n```\n\nNamespaces: `water` | `body` | `analytics`\n\n---\n\n## Data Format \n\n### CSV Format\n```\nlogged_at,drank_at,date,slot,ml_drank,goal_at_time,message_id\n```\n\n| Column | Description |\n|--------|-------------|\n| logged_at | When user told you (NOW) |\n| drank_at | When user actually drank (user can specify past time) |\n| date | Derived from drank_at |\n| slot | morning/lunch/afternoon/evening/manual |\n| ml_drank | Amount in ml |\n| goal_at_time | Goal at that moment |\n| message_id | Audit trail - link to conversation |\n\n**Key Rules:**\n- **drank_at is MANDATORY** - always required\n- If user doesn't specify drank_at → assume drank_at = logged_at\n- **Cumulative is calculated at query time** (not stored)\n- Use drank_at to determine which day counts\n\nDetails at  [references/log_format.md](references/log_format.md)\n\n### Audit Trail\n\nEvery water log entry captures:\n- **message_id**: Links to the conversation message where user requested the log\n- **Auto-capture**: CLI automatically gets message_id from session transcript\n- **Proof**: Use `water audit <message_id>` to get entry + conversation context\n\n```bash\n# Check proof of a water entry\nwater audit msg_123\n# Returns: entry data + surrounding messages for context\n```\n\n> ⚠️ **Privacy Notice**: The audit feature can read your conversation transcripts, but **only when you explicitly run `water audit <message_id>`**. This is off by default (`audit_auto_capture: false`).\n>\n> ```bash\n> # Edit water_config.json and set:\n> \"audit_auto_capture\": true\n> ```\n>\n> **How it works:**\n> - Water log **always** saves the `message_id` (regardless of this setting) ✅\n> - When you run `water audit <message_id>`:\n>   - If `false`: Shows entry data only (message_id saved, but no context read)\n>   - If `true`: Also reads transcript to show conversation context (\"User said: I drank 500ml\")\n>\n> **Why disable it?** If you discuss sensitive topics and don't need proof of intake, leave it off.\n\n---\n\n## Daily Commands\n\n```bash\n# Water\nwater status                                      # Current progress (calculated from drank_at)\nwater log 500                                    # Log intake (drank_at = now)\nwater log 500 --drank-at=2026-02-18T18:00:00Z  # Log with past time\nwater log 500 --drank-at=2026-02-18T18:00:00Z --message-id=msg_123\nwater dynamic                                    # Check if extra notification needed\nwater threshold                                  # Get expected % for current hour\nwater set_body_weight 80                        # Update weight + logs to body_metrics\nwater set_body_weight 80 --update-goal          # + update goal\nwater audit <message_id>                        # Get entry + conversation context\n\n# Body\nbody log --weight=80 --height=1.75 --body-fat=18\nbody latest          # Get latest metrics\nbody history 30     # Get history\n\n# Analytics\nanalytics week       # Weekly briefing (Sunday 8pm)\nanalytics month     # Monthly briefing (2nd day 8pm)\n```\n\n---\n\n## Rules (MUST FOLLOW)\n\n1. **ALWAYS use CLI** - never calculate manually\n2. **LLM interprets first** - \"eu tomei 2 copos\" → 500ml → water log 500\n3. **Threshold from CLI** - run `water threshold`, don't hardcode\n4. **GOAL is USER'S CHOICE** - weight × 35 is just a DEFAULT suggestion:\n   - At setup: Ask weight → suggest goal → **CONFIRM with user**\n   - On weight update: Ask \"Want to update your goal to the new suggested amount?\"\n   - User can set any goal (doctor's orders, preference, etc.)\n\n---\n\n## Config Tree\n\n```\nwater-coach/\n├── SKILL.md              ← You are here\n├── scripts/\n│   ├── water_coach.py   ← Unified CLI\n│   └── water.py         ← Core functions\n├── data/                 ← DO NOT USE - keep skill code separate from user data\n└── references/\n    ├── setup.md\n    ├── dynamic.md\n    └── log_format.md\n```\n\n### ⚠️ IMPORTANT: Data Location\n**User data is stored in the AGENT WORKSPACE, NOT in the skill folder!**\n\n| Data | Location |\n|------|----------|\n| water_log.csv | `<agent-workspace>/memory/data/water_log.csv` |\n| water_config.json | `<agent-workspace>/memory/data/water_config.json` |\n| body_metrics.csv | `<agent-workspace>/memory/data/body_metrics.csv |\n\nExample path: `/home/oriel/.openclaw/workspace/memory/data/`\n\n**Why?** Keeps user data separate from skill code — makes backups, migrations, and skill updates easier.\n\n---\n\n## Notifications Schedule\n\n| Type | When | Command |\n|------|------|---------|\n| User Configured | Per user's schedule | water status |\n| Default Suggestion | 9am, 12pm, 3pm, 6pm, 9pm | water status |\n| Dynamic | Every ~30 min (heartbeat) | water dynamic |\n| Weekly | Sunday 8pm | analytics week |\n| Monthly | 2nd day 8pm | analytics month |\n\n### Notification Rules (MUST FOLLOW)\n- **USER CONFIGURES THEIR SCHEDULE** — Agent should ask user: \"What times do you want water reminders?\" and respect that\n- **NO \"no log\" skip logic** — Always send notifications when scheduled, don't skip because user hasn't logged water\n- **Notifications STIMULATE logging** — That's the point! Don't assume user will log on their own\n\n---\n\n## Quick Reference\n\n| Task | Command |\n|------|---------|\n| Check progress | `water_coach.py water status` |\n| Log water | `water_coach.py water log 500` |\n| Need extra? | `water_coach.py water dynamic` |\n| Body metrics | `water_coach.py body log --weight=80` |\n| Weekly report | `water_coach.py analytics week` |\n| Monthly report | `water_coach.py analytics month` |\n\n## Dynamic Scheduling details\n→ [references/dynamic.md](references/dynamic.md)\n\n### ⚠️ Bug Fix (Feb 2026)\nThe `water dynamic` command had a bug where the hourly notification counter wouldn't reset when the hour changed. This is now fixed:\n- The script now checks if the current hour differs from `last_extra_hour` and resets the counter accordingly\n- This ensures notifications work correctly after hour boundaries (e.g., 4PM)\n\n### ⚠️ Bug Fix (Feb 2026) - Analytics\nThe `analyticsPM → 5 week` and `analytics month` commands had a bug:\n- Was looking for non-existent `cumulative_ml` column in CSV\n- Fixed to sum `ml_drank` per day instead\n\n### ✅ How to Build Good Weekly/Monthly Reports\n\n**Use these functions (don't reinvent):**\n\n| Report | Script | Function |\n|--------|--------|----------|\n| Weekly | `water_coach.py analytics week` | `analytics_week()` in `water_coach.py` |\n| Monthly | `water_coach.py analytics month` | `analytics_month()` in `water_coach.py` |\n\nThese call `get_week_stats()` and `get_month_stats()` in `water.py`.\n\n**When updating analytics functions, follow these rules:**\n\n**1. Include ALL days, even with 0ml**\n```python\n# In get_week_stats() / get_month_stats()\n# Include every day in the range, not just days with data\nfor i in range(days):\n    d = (date.today() - timedelta(days=i)).strftime(\"%Y-%m-%d\")\n    ml = by_date.get(d, {}).get(\"ml\", 0)  # Default to 0, not skip\n```\n\n**2. Calculate true average**\n```python\n# Average = total_ml / ALL days (including zeros), not just tracked days\navg_ml = total_ml / days  # e.g., 15440ml / 7 days = 2205ml/day\n```\n\n**3. Show all days in table format**\n```python\n| Dia | ML | % | Status |\n| Sab 22 | 2250ml | 67.7% | ⚠️ |\n| Seg 17 | 0ml | 0.0% | ❌ |\n```\n\nThis gives users an accurate picture of their habits!\n\n\n\n## Tests\n\n```bash\npython3 -m pytest skills/water-coach/scripts/test/test_water.py -v\n```\n\n## Example\n\n```\nUser: \"eu tomei 2 copos\"\nAgent: (LLM interprets: 2 copos ≈ 500ml)\nAgent: exec(\"water_coach.py water log 500\")\n→ Python logs to CSV\n```\n\n\n\nAgent Evaluations → [evaluation/AGENT.md](evaluation/AGENT.md)\n\n","tags":{"latest":"1.7.0"},"stats":{"comments":0,"downloads":1517,"installsAllTime":57,"installsCurrent":2,"stars":2,"versions":21},"createdAt":1771169987659,"updatedAt":1778990743165},"latestVersion":{"version":"1.7.0","createdAt":1771809092144,"changelog":"water-coach 1.7.0\n\n- Fixed: The `water dynamic` command now correctly resets the hourly notification counter when the hour changes, preventing missed notifications at hour boundaries.\n- Fixed: Weekly and monthly analytics now sum water intake per day using the correct CSV column (`ml_drank`), resolving errors from missing `cumulative_ml`.\n- Documentation updated to clarify bug fixes and reference correct analytics usage.\n- No database, config, or CLI changes to user experience expected outside these bug fixes.","license":null},"metadata":null,"owner":{"handle":"oristides","userId":"s17d2gjyx3sn2kt5z3fnvpmc4d885nky","displayName":"oristides","image":"https://avatars.githubusercontent.com/u/11547862?v=4"},"moderation":{"isSuspicious":false,"isMalwareBlocked":false,"verdict":"clean","reasonCodes":["review.llm_review"],"summary":"Review: review.llm_review","engineVersion":"v2.4.24","updatedAt":1779968386461}}