Each Log Entry logo

Each Log Entry

oristides/water-coach

Installation

clawhub install oristides/water-coach

Summary

Follow the first setup here references/setup.md

SKILL.md

πŸ’§ Water Coach

First-time Setup

Follow the first setup here references/setup.md


πŸ€– How Other Agents Should Interact

First-time Setup Check

bash
water setup
is_setupWhat to do
falseAsk: 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!
trueSkip setup. Just log water or show status.

❌ Don't Ask

  • Reminder schedules after first setup (user already configured)

βœ… Do Ask

  • "How much water did you drink?"
  • Only weight/goal (first time)

CLI Structure

bash
water_coach.py <namespace> <command> [options]

Namespaces: water | body | analytics


Data Format

CSV Format

text
logged_at,drank_at,date,slot,ml_drank,goal_at_time,message_id
ColumnDescription
logged_atWhen user told you (NOW)
drank_atWhen user actually drank (user can specify past time)
dateDerived from drank_at
slotmorning/lunch/afternoon/evening/manual
ml_drankAmount in ml
goal_at_timeGoal at that moment
message_idAudit trail - link to conversation

Key Rules:

  • drank_at is MANDATORY - always required
  • If user doesn't specify drank_at β†’ assume drank_at = logged_at
  • Cumulative is calculated at query time (not stored)
  • Use drank_at to determine which day counts

Details at references/log_format.md

Audit Trail

Every water log entry captures:

  • message_id: Links to the conversation message where user requested the log
  • Auto-capture: CLI automatically gets message_id from session transcript
  • Proof: Use water audit <message_id> to get entry + conversation context
bash
# Check proof of a water entry
water audit msg_123
# Returns: entry data + surrounding messages for context

⚠️ 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).

bash
# Edit water_config.json and set:
"audit_auto_capture": true

How it works:

  • Water log always saves the message_id (regardless of this setting) βœ…
  • When you run water audit <message_id>:
    • If false: Shows entry data only (message_id saved, but no context read)
    • If true: Also reads transcript to show conversation context ("User said: I drank 500ml")

Why disable it? If you discuss sensitive topics and don't need proof of intake, leave it off.


Daily Commands

bash
# Water
water status                                      # Current progress (calculated from drank_at)
water log 500                                    # Log intake (drank_at = now)
water log 500 --drank-at=2026-02-18T18:00:00Z  # Log with past time
water log 500 --drank-at=2026-02-18T18:00:00Z --message-id=msg_123
water dynamic                                    # Check if extra notification needed
water threshold                                  # Get expected % for current hour
water set_body_weight 80                        # Update weight + logs to body_metrics
water set_body_weight 80 --update-goal          # + update goal
water audit <message_id>                        # Get entry + conversation context

# Body
body log --weight=80 --height=1.75 --body-fat=18
body latest          # Get latest metrics
body history 30     # Get history

# Analytics
analytics week       # Weekly briefing (Sunday 8pm)
analytics month     # Monthly briefing (2nd day 8pm)

Rules (MUST FOLLOW)

  1. ALWAYS use CLI - never calculate manually
  2. LLM interprets first - "eu tomei 2 copos" β†’ 500ml β†’ water log 500
  3. Threshold from CLI - run water threshold, don't hardcode
  4. GOAL is USER'S CHOICE - weight Γ— 35 is just a DEFAULT suggestion:
    • At setup: Ask weight β†’ suggest goal β†’ CONFIRM with user
    • On weight update: Ask "Want to update your goal to the new suggested amount?"
    • User can set any goal (doctor's orders, preference, etc.)

Config Tree

text
water-coach/
β”œβ”€β”€ SKILL.md              ← You are here
β”œβ”€β”€ scripts/
β”‚   β”œβ”€β”€ water_coach.py   ← Unified CLI
β”‚   └── water.py         ← Core functions
β”œβ”€β”€ data/                 ← DO NOT USE - keep skill code separate from user data
└── references/
    β”œβ”€β”€ setup.md
    β”œβ”€β”€ dynamic.md
    └── log_format.md

⚠️ IMPORTANT: Data Location

User data is stored in the AGENT WORKSPACE, NOT in the skill folder!

DataLocation
water_log.csv<agent-workspace>/memory/data/water_log.csv
water_config.json<agent-workspace>/memory/data/water_config.json
body_metrics.csv`/memory/data/body_metrics.csv

Example path: /home/oriel/.openclaw/workspace/memory/data/

Why? Keeps user data separate from skill code β€” makes backups, migrations, and skill updates easier.


Notifications Schedule

TypeWhenCommand
User ConfiguredPer user's schedulewater status
Default Suggestion9am, 12pm, 3pm, 6pm, 9pmwater status
DynamicEvery ~30 min (heartbeat)water dynamic
WeeklySunday 8pmanalytics week
Monthly2nd day 8pmanalytics month

Notification Rules (MUST FOLLOW)

  • USER CONFIGURES THEIR SCHEDULE β€” Agent should ask user: "What times do you want water reminders?" and respect that
  • NO "no log" skip logic β€” Always send notifications when scheduled, don't skip because user hasn't logged water
  • Notifications STIMULATE logging β€” That's the point! Don't assume user will log on their own

Quick Reference

TaskCommand
Check progresswater_coach.py water status
Log waterwater_coach.py water log 500
Need extra?water_coach.py water dynamic
Body metricswater_coach.py body log --weight=80
Weekly reportwater_coach.py analytics week
Monthly reportwater_coach.py analytics month

Dynamic Scheduling details

β†’ references/dynamic.md

⚠️ Bug Fix (Feb 2026)

The water dynamic command had a bug where the hourly notification counter wouldn't reset when the hour changed. This is now fixed:

  • The script now checks if the current hour differs from last_extra_hour and resets the counter accordingly
  • This ensures notifications work correctly after hour boundaries (e.g., 4PM)

⚠️ Bug Fix (Feb 2026) - Analytics

The analyticsPM β†’ 5 week and analytics month commands had a bug:

  • Was looking for non-existent cumulative_ml column in CSV
  • Fixed to sum ml_drank per day instead

βœ… How to Build Good Weekly/Monthly Reports

Use these functions (don't reinvent):

ReportScriptFunction
Weeklywater_coach.py analytics weekanalytics_week() in water_coach.py
Monthlywater_coach.py analytics monthanalytics_month() in water_coach.py

These call get_week_stats() and get_month_stats() in water.py.

When updating analytics functions, follow these rules:

1. Include ALL days, even with 0ml

python
# In get_week_stats() / get_month_stats()
# Include every day in the range, not just days with data
for i in range(days):
    d = (date.today() - timedelta(days=i)).strftime("%Y-%m-%d")
    ml = by_date.get(d, {}).get("ml", 0)  # Default to 0, not skip

2. Calculate true average

python
# Average = total_ml / ALL days (including zeros), not just tracked days
avg_ml = total_ml / days  # e.g., 15440ml / 7 days = 2205ml/day

3. Show all days in table format

python
| Dia | ML | % | Status |
| Sab 22 | 2250ml | 67.7% | ⚠️ |
| Seg 17 | 0ml | 0.0% | ❌ |

This gives users an accurate picture of their habits!

Tests

bash
python3 -m pytest skills/water-coach/scripts/test/test_water.py -v

Example

text
User: "eu tomei 2 copos"
Agent: (LLM interprets: 2 copos β‰ˆ 500ml)
Agent: exec("water_coach.py water log 500")
β†’ Python logs to CSV

Agent Evaluations β†’ evaluation/AGENT.md

Recommended skills

Browse all β†’

Related guides

Hand-picked reading to help you choose, install, and use agent skills.