{
  "schemaVersion": "1.0",
  "item": {
    "slug": "water-coach",
    "name": "Water Coach",
    "source": "tencent",
    "type": "skill",
    "category": "AI 智能",
    "sourceUrl": "https://clawhub.ai/oristides/water-coach",
    "canonicalUrl": "https://clawhub.ai/oristides/water-coach",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/water-coach",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=water-coach",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "CHANGELOG.md",
      "SKILL.md",
      "_meta.json",
      "evaluation/AGENT.md",
      "evaluation/agent_eval.json",
      "references/dynamic.md"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/water-coach"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/water-coach",
    "agentPageUrl": "https://openagent3.xyz/skills/water-coach/agent",
    "manifestUrl": "https://openagent3.xyz/skills/water-coach/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/water-coach/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "First-time Setup",
        "body": "Follow the first setup here references/setup.md"
      },
      {
        "title": "First-time Setup Check",
        "body": "water setup\n\nis_setupWhat to dofalseAsk: 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."
      },
      {
        "title": "❌ Don't Ask",
        "body": "Reminder schedules after first setup (user already configured)"
      },
      {
        "title": "✅ Do Ask",
        "body": "\"How much water did you drink?\"\nOnly weight/goal (first time)"
      },
      {
        "title": "CLI Structure",
        "body": "water_coach.py <namespace> <command> [options]\n\nNamespaces: water | body | analytics"
      },
      {
        "title": "CSV Format",
        "body": "logged_at,drank_at,date,slot,ml_drank,goal_at_time,message_id\n\nColumnDescriptionlogged_atWhen user told you (NOW)drank_atWhen user actually drank (user can specify past time)dateDerived from drank_atslotmorning/lunch/afternoon/evening/manualml_drankAmount in mlgoal_at_timeGoal at that momentmessage_idAudit trail - link to conversation\n\nKey Rules:\n\ndrank_at is MANDATORY - always required\nIf user doesn't specify drank_at → assume drank_at = logged_at\nCumulative is calculated at query time (not stored)\nUse drank_at to determine which day counts\n\nDetails at  references/log_format.md"
      },
      {
        "title": "Audit Trail",
        "body": "Every water log entry captures:\n\nmessage_id: Links to the conversation message where user requested the log\nAuto-capture: CLI automatically gets message_id from session transcript\nProof: Use water audit <message_id> to get entry + conversation context\n\n# Check proof of a water entry\nwater audit msg_123\n# Returns: entry data + surrounding messages for context\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# Edit water_config.json and set:\n\"audit_auto_capture\": true\n\nHow it works:\n\nWater log always saves the message_id (regardless of this setting) ✅\nWhen you run water audit <message_id>:\n\nIf false: Shows entry data only (message_id saved, but no context read)\nIf true: Also reads transcript to show conversation context (\"User said: I drank 500ml\")\n\n\n\nWhy disable it? If you discuss sensitive topics and don't need proof of intake, leave it off."
      },
      {
        "title": "Daily Commands",
        "body": "# 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)"
      },
      {
        "title": "Rules (MUST FOLLOW)",
        "body": "ALWAYS use CLI - never calculate manually\nLLM interprets first - \"eu tomei 2 copos\" → 500ml → water log 500\nThreshold from CLI - run water threshold, don't hardcode\nGOAL is USER'S CHOICE - weight × 35 is just a DEFAULT suggestion:\n\nAt setup: Ask weight → suggest goal → CONFIRM with user\nOn weight update: Ask \"Want to update your goal to the new suggested amount?\"\nUser can set any goal (doctor's orders, preference, etc.)"
      },
      {
        "title": "Config Tree",
        "body": "water-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"
      },
      {
        "title": "⚠️ IMPORTANT: Data Location",
        "body": "User data is stored in the AGENT WORKSPACE, NOT in the skill folder!\n\nDataLocationwater_log.csv<agent-workspace>/memory/data/water_log.csvwater_config.json<agent-workspace>/memory/data/water_config.jsonbody_metrics.csv`<agent-workspace>/memory/data/body_metrics.csv\n\nExample path: /home/oriel/.openclaw/workspace/memory/data/\n\nWhy? Keeps user data separate from skill code — makes backups, migrations, and skill updates easier."
      },
      {
        "title": "Notifications Schedule",
        "body": "TypeWhenCommandUser ConfiguredPer user's schedulewater statusDefault Suggestion9am, 12pm, 3pm, 6pm, 9pmwater statusDynamicEvery ~30 min (heartbeat)water dynamicWeeklySunday 8pmanalytics weekMonthly2nd day 8pmanalytics month"
      },
      {
        "title": "Notification Rules (MUST FOLLOW)",
        "body": "USER CONFIGURES THEIR SCHEDULE — Agent should ask user: \"What times do you want water reminders?\" and respect that\nNO \"no log\" skip logic — Always send notifications when scheduled, don't skip because user hasn't logged water\nNotifications STIMULATE logging — That's the point! Don't assume user will log on their own"
      },
      {
        "title": "Quick Reference",
        "body": "TaskCommandCheck progresswater_coach.py water statusLog waterwater_coach.py water log 500Need extra?water_coach.py water dynamicBody metricswater_coach.py body log --weight=80Weekly reportwater_coach.py analytics weekMonthly reportwater_coach.py analytics month"
      },
      {
        "title": "Dynamic Scheduling details",
        "body": "→ references/dynamic.md"
      },
      {
        "title": "⚠️ Bug Fix (Feb 2026)",
        "body": "The water dynamic command had a bug where the hourly notification counter wouldn't reset when the hour changed. This is now fixed:\n\nThe script now checks if the current hour differs from last_extra_hour and resets the counter accordingly\nThis ensures notifications work correctly after hour boundaries (e.g., 4PM)"
      },
      {
        "title": "⚠️ Bug Fix (Feb 2026) - Analytics",
        "body": "The analyticsPM → 5 week and analytics month commands had a bug:\n\nWas looking for non-existent cumulative_ml column in CSV\nFixed to sum ml_drank per day instead"
      },
      {
        "title": "✅ How to Build Good Weekly/Monthly Reports",
        "body": "Use these functions (don't reinvent):\n\nReportScriptFunctionWeeklywater_coach.py analytics weekanalytics_week() in water_coach.pyMonthlywater_coach.py analytics monthanalytics_month() in water_coach.py\n\nThese call get_week_stats() and get_month_stats() in water.py.\n\nWhen updating analytics functions, follow these rules:\n\n1. Include ALL days, even with 0ml\n\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\n2. Calculate true average\n\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\n3. Show all days in table format\n\n| Dia | ML | % | Status |\n| Sab 22 | 2250ml | 67.7% | ⚠️ |\n| Seg 17 | 0ml | 0.0% | ❌ |\n\nThis gives users an accurate picture of their habits!"
      },
      {
        "title": "Tests",
        "body": "python3 -m pytest skills/water-coach/scripts/test/test_water.py -v"
      },
      {
        "title": "Example",
        "body": "User: \"eu tomei 2 copos\"\nAgent: (LLM interprets: 2 copos ≈ 500ml)\nAgent: exec(\"water_coach.py water log 500\")\n→ Python logs to CSV\n\nAgent Evaluations → evaluation/AGENT.md"
      }
    ],
    "body": "💧 Water Coach\nFirst-time Setup\n\nFollow the first setup here references/setup.md\n\n🤖 How Other Agents Should Interact\nFirst-time Setup Check\nwater setup\n\nis_setup\tWhat to do\nfalse\tAsk: 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!\ntrue\tSkip setup. Just log water or show status.\n❌ Don't Ask\nReminder schedules after first setup (user already configured)\n✅ Do Ask\n\"How much water did you drink?\"\nOnly weight/goal (first time)\nCLI Structure\nwater_coach.py <namespace> <command> [options]\n\n\nNamespaces: water | body | analytics\n\nData Format\nCSV Format\nlogged_at,drank_at,date,slot,ml_drank,goal_at_time,message_id\n\nColumn\tDescription\nlogged_at\tWhen user told you (NOW)\ndrank_at\tWhen user actually drank (user can specify past time)\ndate\tDerived from drank_at\nslot\tmorning/lunch/afternoon/evening/manual\nml_drank\tAmount in ml\ngoal_at_time\tGoal at that moment\nmessage_id\tAudit trail - link to conversation\n\nKey Rules:\n\ndrank_at is MANDATORY - always required\nIf user doesn't specify drank_at → assume drank_at = logged_at\nCumulative is calculated at query time (not stored)\nUse drank_at to determine which day counts\n\nDetails at references/log_format.md\n\nAudit Trail\n\nEvery water log entry captures:\n\nmessage_id: Links to the conversation message where user requested the log\nAuto-capture: CLI automatically gets message_id from session transcript\nProof: Use water audit <message_id> to get entry + conversation context\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# Edit water_config.json and set:\n\"audit_auto_capture\": true\n\n\nHow it works:\n\nWater log always saves the message_id (regardless of this setting) ✅\nWhen you run water audit <message_id>:\nIf false: Shows entry data only (message_id saved, but no context read)\nIf true: Also reads transcript to show conversation context (\"User said: I drank 500ml\")\n\nWhy disable it? If you discuss sensitive topics and don't need proof of intake, leave it off.\n\nDaily Commands\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\nRules (MUST FOLLOW)\nALWAYS use CLI - never calculate manually\nLLM interprets first - \"eu tomei 2 copos\" → 500ml → water log 500\nThreshold from CLI - run water threshold, don't hardcode\nGOAL is USER'S CHOICE - weight × 35 is just a DEFAULT suggestion:\nAt setup: Ask weight → suggest goal → CONFIRM with user\nOn weight update: Ask \"Want to update your goal to the new suggested amount?\"\nUser can set any goal (doctor's orders, preference, etc.)\nConfig Tree\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⚠️ IMPORTANT: Data Location\n\nUser data is stored in the AGENT WORKSPACE, NOT in the skill folder!\n\nData\tLocation\nwater_log.csv\t<agent-workspace>/memory/data/water_log.csv\nwater_config.json\t<agent-workspace>/memory/data/water_config.json\nbody_metrics.csv\t`<agent-workspace>/memory/data/body_metrics.csv\n\nExample path: /home/oriel/.openclaw/workspace/memory/data/\n\nWhy? Keeps user data separate from skill code — makes backups, migrations, and skill updates easier.\n\nNotifications Schedule\nType\tWhen\tCommand\nUser Configured\tPer user's schedule\twater status\nDefault Suggestion\t9am, 12pm, 3pm, 6pm, 9pm\twater status\nDynamic\tEvery ~30 min (heartbeat)\twater dynamic\nWeekly\tSunday 8pm\tanalytics week\nMonthly\t2nd day 8pm\tanalytics month\nNotification Rules (MUST FOLLOW)\nUSER CONFIGURES THEIR SCHEDULE — Agent should ask user: \"What times do you want water reminders?\" and respect that\nNO \"no log\" skip logic — Always send notifications when scheduled, don't skip because user hasn't logged water\nNotifications STIMULATE logging — That's the point! Don't assume user will log on their own\nQuick Reference\nTask\tCommand\nCheck progress\twater_coach.py water status\nLog water\twater_coach.py water log 500\nNeed extra?\twater_coach.py water dynamic\nBody metrics\twater_coach.py body log --weight=80\nWeekly report\twater_coach.py analytics week\nMonthly report\twater_coach.py analytics month\nDynamic Scheduling details\n\n→ references/dynamic.md\n\n⚠️ Bug Fix (Feb 2026)\n\nThe water dynamic command had a bug where the hourly notification counter wouldn't reset when the hour changed. This is now fixed:\n\nThe script now checks if the current hour differs from last_extra_hour and resets the counter accordingly\nThis ensures notifications work correctly after hour boundaries (e.g., 4PM)\n⚠️ Bug Fix (Feb 2026) - Analytics\n\nThe analyticsPM → 5 week and analytics month commands had a bug:\n\nWas looking for non-existent cumulative_ml column in CSV\nFixed to sum ml_drank per day instead\n✅ How to Build Good Weekly/Monthly Reports\n\nUse these functions (don't reinvent):\n\nReport\tScript\tFunction\nWeekly\twater_coach.py analytics week\tanalytics_week() in water_coach.py\nMonthly\twater_coach.py analytics month\tanalytics_month() in water_coach.py\n\nThese call get_week_stats() and get_month_stats() in water.py.\n\nWhen updating analytics functions, follow these rules:\n\n1. Include ALL days, even with 0ml\n\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\n2. Calculate true average\n\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\n3. Show all days in table format\n\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\nTests\npython3 -m pytest skills/water-coach/scripts/test/test_water.py -v\n\nExample\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\nAgent Evaluations → evaluation/AGENT.md"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/oristides/water-coach",
    "publisherUrl": "https://clawhub.ai/oristides/water-coach",
    "owner": "oristides",
    "version": "1.7.0",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/water-coach",
    "downloadUrl": "https://openagent3.xyz/downloads/water-coach",
    "agentUrl": "https://openagent3.xyz/skills/water-coach/agent",
    "manifestUrl": "https://openagent3.xyz/skills/water-coach/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/water-coach/agent.md"
  }
}