Skill: agistack/medical (version 1.1.0)

--- name: medical description: Local-first health record management with strict privacy boundaries. Organize what happened, what you take, what changed, and what to bring to your doctor — never diagnosis or treatment advice. --- # Medical Medical is a private health organization tool, not a doctor. Use this skill when the user wants to: - Track medications - Log symptoms over time - Record vital signs - Store structured medical history - Generate an emergency health summary - Prepare a concise health summary for a doctor visit Never use this skill for: - Diagnosis - Treatment advice - Interpreting symptoms as medical conditions - Recommending starting, stopping, or changing medications - Replacing professional medical care ## Safety Boundaries ### Emergency First If the user describes a possible medical emergency, stop normal workflow and direct them to emergency care first. Examples include: - Chest pain or chest pressure - Trouble breathing or inability to breathe - Severe bleeding - Loss of consciousness - Suicidal thoughts or self-harm intent - Sudden severe neurological symptoms - “Worst headache of my life” In emergency situations: 1. Tell the user to call emergency services or seek urgent in-person care now 2. Do not continue normal tracking until that is addressed 3. If asked, generate the emergency health summary as fast as possible ### Medication Safety This skill may store medication lists and run a limited local interaction screen for a few common high-risk combinations, but it is not a comprehensive interaction checker. Always remind the user to verify medication questions with a doctor or pharmacist before making any changes. ### Lab and Vital Safety This skill may record lab-related or vital-sign information for personal organization, but it must not diagnose, triage, or decide what a result means clinically. It may: - Compare a recorded value against the range provided by the user or their lab report - Help organize questions for a doctor - Summarize trends for discussion with a clinician It must not: - Diagnose disease - Say a result is “nothing to worry about” - Recommend medication or treatment changes - Replace clinician review ## Privacy and Storage All health data is stored locally only under: `~/.openclaw/workspace/memory/health` No external APIs should be used for health data storage. No third-party transmission. User controls retention and deletion. ## Core Files - `~/.openclaw/workspace/memory/health/medications.json` - `~/.openclaw/workspace/memory/health/symptoms.json` - `~/.openclaw/workspace/memory/health/history.json` - `~/.openclaw/workspace/memory/health/vitals.json` ## Core Workflows ### 1. Add a medication Example: `I was prescribed Lisinopril 10mg daily` Use: - `scripts/add_medication.py` - `scripts/list_medications.py` - `scripts/check_interactions.py` when relevant ### 2. Log a symptom Example: `I have a headache, 6 out of 10, worse in the morning` Use: - `scripts/add_symptom.py` Track: - What happened - Severity - When it started - Triggers or context - Notes for future doctor visits ### 3. Log a vital sign Example: `My blood pressure this morning was 130/85` Use: - `scripts/add_vital.py` - `scripts/get_vital_trends.py` ### 4. Add medical history Example: `Add penicillin allergy` `Add appendectomy from 2015` `Add my primary care doctor` Use: - `scripts/add_history_record.py` Store structured records for: - Personal info - Conditions - Surgeries - Hospitalizations - Allergies - Immunizations - Physicians - Emergency contacts ### 5. Generate emergency health summary Example: `Generate my emergency health card` Use: - `scripts/generate_emergency_card.py` Use this for: - Phone lock screen - Wallet printout - Quick access in emergencies ### 6. Prepare a doctor-visit summary When the user wants a concise summary for a doctor visit: - Read medications - Read symptoms - Read vitals - Read history - Summarize what changed, what is ongoing, and what to ask Do not diagnose. Do not interpret symptoms as conditions. Do not recommend treatment changes. ## Scripts Currently Included - `scripts/add_medication.py` - `scripts/list_medications.py` - `scripts/check_interactions.py` - `scripts/add_symptom.py` - `scripts/add_vital.py` - `scripts/get_vital_trends.py` - `scripts/add_history_record.py` - `scripts/generate_emergency_card.py` ## Output Style Prefer concise, structured, doctor-friendly output: - Medication list - Symptom timeline summary - Vital trend summary - Relevant history - Questions to ask a clinician ## Product Definition Medical is a local-first personal health record system with strict privacy and safety boundaries. Its job is to help the user organize: - What happened - What they take - What changed - What they may want to bring to a doctor Its job is not to diagnose, prescribe, or replace medical care. ## Disclaimer This skill is for personal health record management only. It is not a medical professional, not a diagnostic system, and not a substitute for a doctor, pharmacist, or emergency services.

path: references/emergency-card.md
content: # Emergency Health Summary

## Purpose

One-page summary of critical health information for emergency situations. Designed to be:
- Screenshot and saved to phone lock screen
- Printed and kept in wallet
- Accessible to paramedics and emergency room staff

## Data Included

```json
{
  "emergency_card": {
    "full_name": "John Michael Doe",
    "date_of_birth": "1985-06-15",
    "age": 38,
    "blood_type": "O+",
    "organ_donor": true,
    "critical_allergies": [
      {"allergen": "Penicillin", "reaction": "Anaphylaxis"},
      {"allergen": "Sulfa drugs", "reaction": "Severe rash"}
    ],
    "medical_conditions": [
      "Hypertension",
      "Type 2 Diabetes"
    ],
    "current_medications": [
      {"name": "Lisinopril", "dose": "10mg daily"},
      {"name": "Metformin", "dose": "500mg twice daily"}
    ],
    "emergency_contacts": [
      {"name": "Jane Doe", "relationship": "spouse", "phone": "555-0123"}
    ],
    "primary_physician": {
      "name": "Dr. Sarah Smith",
      "phone": "555-0100"
    },
    "insurance": {
      "provider": "Blue Cross",
      "policy_number": "XXX123456",
      "group_number": "GRP789"
    }
  }
}
```

## Generating Emergency Card

### Script
```bash
python scripts/generate_emergency_card.py
# Options:
#   --format text      # Plain text (for printing)
#   --format phone     # Optimized for phone lock screen
#   --include-insurance # Add insurance info
```

## Output Formats

### Phone Lock Screen Format
```
╔════════════════════════════════════════╗
║  ⚠️ EMERGENCY HEALTH INFO ⚠️           ║
╠════════════════════════════════════════╣
║  John Doe  •  DOB: 6/15/1985           ║
║  Blood Type: O+  •  Organ Donor: Y     ║
╠════════════════════════════════════════╣
║  🚨 ALLERGIES: Penicillin = Anaphylaxis║
║                Sulfa = Severe rash     ║
╠════════════════════════════════════════╣
║  CONDITIONS: Hypertension, Diabetes    ║
╠════════════════════════════════════════╣
║  MEDICATIONS:                          ║
║  • Lisinopril 10mg daily               ║
║  • Metformin 500mg 2x daily            ║
╠════════════════════════════════════════╣
║  ICE: Jane Doe (spouse) 555-0123       ║
║  Dr: Sarah Smith 555-0100              ║
╚════════════════════════════════════════╝
```

### Wallet Card Format (Business Card Size)
```
┌──────────────────────────────────────┐
│ EMERGENCY INFO                       │
│ John Doe • 6/15/1985 • O+            │
│                                      │
│ ALLERGIES: Penicillin (anaphylaxis)  │
│            Sulfa (severe)            │
│                                      │
│ CONDITIONS: HTN, Diabetes            │
│                                      │
│ MEDS: Lisinopril 10mg, Metformin     │
│       500mg BID                      │
│                                      │
│ ICE: Jane 555-0123                   │
│ Dr: Smith 555-0100                   │
└──────────────────────────────────────┘
```

## Updating Emergency Card

Emergency card should be regenerated when:
- New medication added
- New allergy discovered
- Change in medical conditions
- Emergency contact changes
- Insurance changes

```
User: "I have a new allergy to latex"
→ Add to allergies
→ Prompt: "Update emergency card? (Y/n)"
→ If yes: regenerate and remind to replace saved/printed copies
```

## Security Considerations

### Information Balance
Include enough to save your life, not enough for identity theft:

**Include:**
- Name, DOB, blood type
- Critical allergies (can be life-saving)
- Current medications
- Major conditions
- Emergency contacts

**Exclude from public card:**
- Full insurance policy numbers
- Social security number
- Full address
- Detailed medical history

### Optional Password Protection
For sensitive medications (psychiatric, HIV, etc.):
```bash
python scripts/generate_emergency_card.py \
  --sensitive-redacted \
  --password-protected

# Creates two versions:
# 1. Public: Allergies, conditions, non-sensitive meds
# 2. Protected: Full medication list with password
```

## Emergency Protocol for Agent

If user asks for emergency card during apparent emergency:
1. **Generate card immediately**
2. **Simultaneously ask**: "Are you experiencing a medical emergency right now?"
3. If yes emergency: "Please call 911. I'm generating your health info for first responders."
4. Present card in most accessible format

## Usage Reminders

When generating card, remind user:
- Save screenshot to phone lock screen
- Print wallet-sized version
- Review and update every 6 months or when health changes
- Share with close family members
- Keep one copy easily accessible at home


path: references/medical-history.md
content: # Personal Medical History

## Data Structure

```json
{
  "medical_history": {
    "personal_info": {
      "full_name": "",
      "date_of_birth": "",
      "blood_type": "",
      "organ_donor": false
    },
    "conditions": [
      {
        "condition": "Hypertension",
        "diagnosed_date": "2020-03-15",
        "status": "managed",
        "treating_physician": "Dr. Smith",
        "notes": "Well controlled with medication"
      }
    ],
    "surgeries": [
      {
        "procedure": "Appendectomy",
        "date": "2015-06-10",
        "surgeon": "Dr. Johnson",
        "hospital": "General Hospital",
        "outcome": "uneventful recovery",
        "complications": null
      }
    ],
    "hospitalizations": [
      {
        "reason": "Pneumonia",
        "date": "2018-11-20",
        "duration_days": 5,
        "hospital": "City Medical Center"
      }
    ],
    "allergies": {
      "medications": [
        {"allergen": "Penicillin", "reaction": "Rash, hives", "severity": "moderate"}
      ],
      "foods": [],
      "environmental": []
    },
    "immunizations": [
      {"vaccine": "Tetanus", "date": "2020-05-10", "next_due": "2030-05-10"}
    ],
    "family_history": {
      "heart_disease": ["father", "paternal grandfather"],
      "diabetes": ["mother"],
      "cancer": []
    },
    "physicians": [
      {
        "name": "Dr. Smith",
        "specialty": "Internal Medicine",
        "phone": "555-0100",
        "address": "123 Medical Plaza"
      }
    ]
  }
}
```

## Adding History Records

### Script Usage
```bash
# Add condition
python scripts/add_history_record.py \
  --type condition \
  --name "Type 2 Diabetes" \
  --date "2019-08-15" \
  --physician "Dr. Garcia" \
  --notes "Managed with metformin"

# Add surgery
python scripts/add_history_record.py \
  --type surgery \
  --name "Knee arthroscopy" \
  --date "2021-03-10" \
  --surgeon "Dr. Lee"

# Add allergy
python scripts/add_history_record.py \
  --type allergy \
  --allergen "Sulfa drugs" \
  --reaction "Severe rash" \
  --severity "severe"

# Add immunization
python scripts/add_history_record.py \
  --type immunization \
  --vaccine "COVID-19" \
  --date "2023-09-15" \
  --next-due "2024-09-15"
```

## Retrieving Medical History

### Complete History
```bash
python scripts/get_medical_history.py
# Options:
#   --format summary   # One-page summary
#   --format detailed  # Full details
#   --format json      # Raw JSON
```

### Filtered Views
```bash
# Get only conditions
python scripts/get_medical_history.py --filter conditions

# Get only allergies
python scripts/get_medical_history.py --filter allergies

# Get surgeries only
python scripts/get_medical_history.py --filter surgeries
```

## Use Cases

### 1. Filling Out Medical Forms
When user needs to complete intake forms:
```
"I need to fill out a new patient form"
→ Retrieve medical history
→ Present in form-friendly format
→ Highlight allergies and current medications
```

### 2. New Doctor Consultation
```
"I'm seeing a new cardiologist"
→ Filter history for cardiac-related items
→ Include family history of heart disease
→ List all current medications
```

### 3. Emergency Situations
Quick access to critical information:
- Allergies (especially medication allergies)
- Current conditions
- Blood type (if known)
- Emergency contacts

## History Summary Format

### For New Patient Forms
```
MEDICAL HISTORY SUMMARY
Generated: [Date]

CHRONIC CONDITIONS:
• [Condition] - diagnosed [Date], status: [managed/active/etc]

PREVIOUS SURGERIES:
• [Procedure] - [Date], [Surgeon/Hospital]

HOSPITALIZATIONS:
• [Reason] - [Date], [Hospital], [Duration]

ALLERGIES:
Medications: [List with reactions]
Foods: [List]
Environmental: [List]

CURRENT MEDICATIONS:
[Separate medication list]

FAMILY HISTORY:
[Relevant family conditions]

IMMUNIZATIONS (Recent):
[List with dates]
```


path: references/medication-manager.md
content: # Medication Manager

## Adding New Medication

### Required Information
1. **Medication name** (generic or brand)
2. **Dosage** (e.g., "10mg", "1 tablet")
3. **Frequency** (e.g., "once daily", "twice daily", "every 8 hours")

### Optional Information
- Prescribing doctor
- Start date
- End date (for short-term medications)
- Instructions (with food, empty stomach, etc.)
- Refill information
- Purpose/condition being treated

### Data Structure
```json
{
  "medications": [
    {
      "id": "uuid",
      "name": "Lisinopril",
      "dosage": "10mg",
      "frequency": "once daily",
      "time_of_day": ["morning"],
      "with_food": true,
      "prescribing_doctor": "Dr. Smith",
      "start_date": "2024-03-01",
      "end_date": null,
      "ongoing": true,
      "purpose": "hypertension",
      "refill_date": "2024-04-01",
      "quantity_remaining": 30,
      "notes": "Take with breakfast"
    }
  ]
}
```

### Script Usage
```bash
python scripts/add_medication.py \
  --name "Lisinopril" \
  --dosage "10mg" \
  --frequency "once daily" \
  --time "morning" \
  --with-food \
  --purpose "hypertension"
```

## Medication List Retrieval

### Script
```bash
python scripts/list_medications.py
# Options:
#   --current-only    # Only show active medications
#   --format table    # Table format
#   --format json     # JSON format
```

### Output Example
```
Current Medications (3):
┌────────────────┬─────────┬──────────────┬─────────────┐
│ Medication     │ Dosage  │ Frequency    │ Time        │
├────────────────┼─────────┼──────────────┼─────────────┤
│ Lisinopril     │ 10mg    │ Once daily   │ Morning     │
│ Metformin      │ 500mg   │ Twice daily  │ With meals  │
│ Atorvastatin   │ 20mg    │ Once daily   │ Evening     │
└────────────────┴─────────┴──────────────┴─────────────┘
```

## Interaction Checking

### Important Note
Interaction checking is for **information only**. Always verify with doctor or pharmacist.

### Script
```bash
python scripts/check_interactions.py --new "Medication Name"
# Or check specific pair:
python scripts/check_interactions.py --drug1 "Warfarin" --drug2 "Aspirin"
```

### Common Interaction Categories
- **Blood thinners** + NSAIDs (increased bleeding risk)
- **Statins** + Grapefruit (increased side effects)
- **MAOIs** + Tyramine-rich foods (hypertensive crisis)
- **Warfarin** + Many drugs (affected INR)

### Output Format
```
Interaction Check: [New Medication]

Current Medications Flagged:
• [Medication 1] - [Interaction level: minor/moderate/major]
  [Brief explanation]
  Action: Consult doctor/pharmacist

• [Medication 2] - [Interaction level]
  [Brief explanation]
  Action: [Specific recommendation]

⚠️  ALWAYS verify with your doctor or pharmacist before making changes.
```

## Reminder System

### How It Works
- Store medication schedule in JSON
- Agent reads schedule during daily check-ins
- Suggest reminders based on user's timezone and schedule

### Reminder Types
1. **Daily medication reminders** - At specified times
2. **Refill alerts** - 7 days before estimated run-out
3. **End-of-course alerts** - For antibiotics, prednisone tapers, etc.

### Example Reminder Logic
```python
# Check if medication due
def check_medication_due(medication, current_time):
    if medication['time_of_day'] == 'morning' and current_time.hour == 8:
        return f"Reminder: Take {medication['name']} {medication['dosage']}"
    # ... other times
```

## Safety Boundaries

### NEVER
- Suggest stopping a prescribed medication
- Suggest changing dosage without doctor approval
- Interpret side effects as "normal" or "not serious"
- Recommend OTC medications without checking interactions

### ALWAYS
- Recommend consulting doctor for side effects
- Flag when user mentions stopping medication
- Remind about refill dates
- Suggest pharmacist consultation for interaction questions


path: references/symptom-tracker.md
content: # Symptom Tracker & Appointment Preparation

## Symptom Logging Workflow

### When to Use
User mentions symptoms: "I have headache", "My knee hurts", "I've been feeling dizzy"

### Data Structure
```json
{
  "symptoms": [
    {
      "id": "uuid",
      "description": "headache",
      "severity": 6,
      "severity_scale": "1-10",
      "location": "forehead",
      "quality": "throbbing",
      "triggers": ["stress", "lack of sleep"],
      "relief_factors": ["rest", "dark room"],
      "start_date": "2024-03-01",
      "end_date": null,
      "ongoing": true,
      "notes": "Worse in mornings"
    }
  ]
}
```

### Required Information
1. **What** - Symptom description
2. **Severity** - 1-10 scale (ask if not provided)
3. **When** - Start date/time
4. **Context** - Triggers, what makes it better/worse

### Optional Information
- Location (for localized symptoms)
- Quality (throbbing, sharp, dull, etc.)
- Associated symptoms
- Impact on daily activities

### Script Usage
```bash
python scripts/add_symptom.py \
  --description "headache" \
  --severity 6 \
  --location "forehead" \
  --triggers "stress,lack_of_sleep" \
  --notes "Worse in mornings"
```

## Appointment Preparation Workflow

### Trigger Phrases
- "Prep me for my appointment"
- "I'm seeing the doctor tomorrow"
- "What should I tell my cardiologist?"

### Preparation Checklist
1. **Symptom Timeline** (last 30 days)
   - Current symptoms with severity
   - Duration of each symptom
   - Changes over time

2. **Medication Review**
   - Current medications and dosages
   - Recent changes to medications
   - Side effects experienced

3. **Medical History Relevant to Visit**
   - Conditions related to specialty
   - Previous procedures
   - Family history if relevant

4. **Questions to Ask**
   - Suggest 3-5 questions based on symptoms
   - User can add their own

5. **Recording Space**
   - Prepare template for doctor's recommendations
   - Follow-up instructions
   - New prescriptions

### Output Format
```
Appointment Brief for [Doctor/Specialty] on [Date]

Current Symptoms (Last 30 Days):
• [Symptom] - [Severity]/10, started [Date]
• [Symptom] - [Severity]/10, started [Date]

Current Medications:
• [Medication] [Dosage] - [Frequency]

Relevant Medical History:
• [Condition] - diagnosed [Date]
• [Procedure] - [Date]

Questions to Ask:
1. [Generated question based on symptoms]
2. [Generated question about medication]
3. [User-added question]

Notes from Appointment:
[Space for recording doctor's recommendations]

Follow-up:
[Space for next steps]
```

## Safety Check

Before logging symptoms or prepping appointments, check for emergency red flags:
- Chest pain or pressure
- Difficulty breathing
- Severe bleeding
- Sudden severe headache ("worst ever")
- Loss of consciousness
- Suicidal thoughts

**If ANY present**: Immediately direct to emergency services, do not proceed with tracking.


path: references/vital-signs.md
content: # Vital Signs & Chronic Condition Monitoring

## Supported Vital Signs

| Vital Sign | Units | Normal Range* | Frequency |
|------------|-------|---------------|-----------|
| Blood Pressure | mmHg | <120/80 | Daily or per doctor |
| Heart Rate | bpm | 60-100 | As needed |
| Blood Glucose | mg/dL | 70-140 (fasting) | Per diabetic protocol |
| Weight | lbs/kg | - | Weekly |
| Temperature | °F/°C | 97-99°F | When ill |
| Oxygen Saturation | % | 95-100% | As prescribed |
| Sleep | hours | 7-9 | Daily |
| Pain Level | 0-10 | 0 | As experienced |

*Normal ranges vary by individual. Follow your doctor's targets.

## Data Structure

```json
{
  "vitals": {
    "blood_pressure": [
      {
        "date": "2024-03-01T08:00:00",
        "systolic": 128,
        "diastolic": 82,
        "position": "sitting",
        "arm": "left",
        "notes": "Morning reading"
      }
    ],
    "blood_glucose": [
      {
        "date": "2024-03-01T07:30:00",
        "value": 105,
        "context": "fasting",
        "notes": "Before breakfast"
      }
    ],
    "weight": [
      {
        "date": "2024-03-01",
        "value": 165,
        "unit": "lbs"
      }
    ],
    "heart_rate": [
      {
        "date": "2024-03-01T08:00:00",
        "value": 72,
        "context": "resting"
      }
    ],
    "pain": [
      {
        "date": "2024-03-01T14:00:00",
        "level": 4,
        "location": "lower back",
        "quality": "aching"
      }
    ]
  },
  "targets": {
    "blood_pressure": {"systolic_max": 130, "diastolic_max": 85},
    "blood_glucose": {"fasting_max": 130, "post_meal_max": 180},
    "weight": {"target": 160, "unit": "lbs"}
  }
}
```

## Logging Vitals

### Script Usage
```bash
# Blood pressure
python scripts/add_vital.py \
  --type bp \
  --systolic 128 \
  --diastolic 82 \
  --notes "Morning, before meds"

# Blood glucose
python scripts/add_vital.py \
  --type glucose \
  --value 105 \
  --context "fasting"

# Weight
python scripts/add_vital.py \
  --type weight \
  --value 165 \
  --unit lbs

# Pain
python scripts/add_vital.py \
  --type pain \
  --level 4 \
  --location "lower back"
```

## Trend Analysis

### Weekly Averages
```bash
python scripts/get_vital_trends.py \
  --type bp \
  --period week

# Output:
# Week of Mar 1-7:
#   Average: 126/80 mmHg
#   Readings: 7
#   Above target: 2 days
```

### Monthly Trends
```bash
python scripts/get_vital_trends.py \
  --type weight \
  --period month \
  --chart
```

### Trend Report Format
```
VITAL SIGNS TREND REPORT
Period: [Start] to [End]

BLOOD PRESSURE:
• Average: [XXX/XX] mmHg ([N] readings)
• Range: [min/max]
• Trend: [improving/stable/worsening]
• Days above target: [N]

BLOOD GLUCOSE:
• Average fasting: [XXX] mg/dL
• Average post-meal: [XXX] mg/dL
• Trend: [improving/stable/worsening]

WEIGHT:
• Start: [XXX] lbs
• End: [XXX] lbs
• Change: [+/-X.X] lbs
• Trend: [gaining/losing/stable]
```

## Alert System

### Setting Targets
```bash
python scripts/set_vital_targets.py \
  --type bp \
  --systolic-max 130 \
  --diastolic-max 85
```

### Alert Triggers
When vital is logged outside target range:
1. Note the deviation
2. Track frequency of deviations
3. Suggest discussing with doctor if pattern emerges
4. Never suggest medication changes

### Example Alert
```
Blood pressure logged: 145/92 mmHg
Your target: <130/85 mmHg

This reading is above your target range.

If this is:
• A single reading - monitor and recheck later
• Multiple readings this week - consider checking with your doctor
• Accompanied by symptoms (headache, dizziness) - contact doctor today

Track: When did you take this reading? Any factors (stress, missed medication, etc.)?
```

## Chronic Condition Protocols

### Hypertension Monitoring
- Daily BP at same time
- Track medication adherence
- Note salt intake if relevant
- Weekly averages for doctor visits

### Diabetes Monitoring
- Per doctor's protocol (fasting, pre/post meal)
- Track medication/insulin timing
- Note carbohydrate intake if helpful
- A1C tracking (every 3 months)

### Weight Management
- Weekly weigh-ins, same day/time
- Track diet/exercise alongside
- Focus on trends, not single readings
- Celebrate consistency over perfection

### Chronic Pain
- Pain level (0-10) when experienced
- Location and quality
- Triggers and relief measures
- Impact on activities
- Medication effectiveness tracking


path: scripts/add_history_record.py
content: #!/usr/bin/env python3
"""Add record to medical history."""
import json
import os
import uuid
import argparse
from datetime import datetime

HEALTH_DIR = os.path.expanduser("~/.openclaw/workspace/memory/health")
HISTORY_FILE = os.path.join(HEALTH_DIR, "history.json")

def ensure_dir():
    os.makedirs(HEALTH_DIR, exist_ok=True)

def load_history():
    if os.path.exists(HISTORY_FILE):
        with open(HISTORY_FILE, 'r') as f:
            return json.load(f)
    return {
        "personal_info": {},
        "conditions": [],
        "surgeries": [],
        "hospitalizations": [],
        "allergies": {"medications": [], "foods": [], "environmental": []},
        "immunizations": [],
        "family_history": {},
        "physicians": [],
        "emergency_contacts": []
    }

def save_history(data):
    ensure_dir()
    with open(HISTORY_FILE, 'w') as f:
        json.dump(data, f, indent=2)

def main():
    parser = argparse.ArgumentParser(description='Add to medical history')
    parser.add_argument('--type', required=True,
                        choices=['personal-info', 'condition', 'surgery', 
                                'hospitalization', 'allergy', 'immunization',
                                'physician', 'emergency-contact'],
                        help='Type of record')
    
    # Common fields
    parser.add_argument('--name', help='Name (medication, condition, etc)')
    parser.add_argument('--date', help='Date (YYYY-MM-DD)')
    parser.add_argument('--notes', default='', help='Additional notes')
    
    # Specific fields
    parser.add_argument('--allergen', help='Allergen name')
    parser.add_argument('--reaction', help='Allergic reaction')
    parser.add_argument('--severity', choices=['mild', 'moderate', 'severe'],
                        help='Allergy severity')
    parser.add_argument('--category', choices=['medications', 'foods', 'environmental'],
                        default='medications', help='Allergy category')
    parser.add_argument('--vaccine', help='Vaccine name')
    parser.add_argument('--next-due', help='Next due date for vaccine')
    parser.add_argument('--physician', help='Doctor name')
    parser.add_argument('--specialty', help='Medical specialty')
    parser.add_argument('--phone', help='Phone number')
    parser.add_argument('--relationship', help='Relationship (for emergency contacts)')
    parser.add_argument('--dob', help='Date of birth (for personal info)')
    parser.add_argument('--blood-type', help='Blood type')
    
    args = parser.parse_args()
    
    data = load_history()
    record_id = str(uuid.uuid4())[:8]
    
    if args.type == 'personal-info':
        if args.name:
            data['personal_info']['full_name'] = args.name
        if args.dob:
            data['personal_info']['date_of_birth'] = args.dob
        if args.blood_type:
            data['personal_info']['blood_type'] = args.blood_type
        print(f"✓ Updated personal info")
    
    elif args.type == 'condition':
        if not args.name:
            print("Error: Condition requires --name")
            return
        record = {
            "id": record_id,
            "condition": args.name,
            "diagnosed_date": args.date or datetime.now().strftime('%Y-%m-%d'),
            "status": "active",
            "notes": args.notes
        }
        data['conditions'].append(record)
        print(f"✓ Added condition: {args.name}")
    
    elif args.type == 'surgery':
        if not args.name:
            print("Error: Surgery requires --name")
            return
        record = {
            "id": record_id,
            "procedure": args.name,
            "date": args.date,
            "notes": args.notes
        }
        data['surgeries'].append(record)
        print(f"✓ Added surgery: {args.name}")
    
    elif args.type == 'allergy':
        if not args.allergen:
            print("Error: Allergy requires --allergen")
            return
        record = {
            "allergen": args.allergen,
            "reaction": args.reaction or 'Unknown',
            "severity": args.severity or 'moderate'
        }
        if 'allergies' not in data:
            data['allergies'] = {"medications": [], "foods": [], "environmental": []}
        if args.category not in data['allergies']:
            data['allergies'][args.category] = []
        data['allergies'][args.category].append(record)
        print(f"✓ Added allergy: {args.allergen} ({args.category})")
        print("⚠️  Remember to update your emergency card!")
    
    elif args.type == 'immunization':
        if not args.vaccine:
            print("Error: Immunization requires --vaccine")
            return
        record = {
            "vaccine": args.vaccine,
            "date": args.date or datetime.now().strftime('%Y-%m-%d'),
            "next_due": args.next_due
        }
        data['immunizations'].append(record)
        print(f"✓ Added immunization: {args.vaccine}")
    
    elif args.type == 'physician':
        if not args.name:
            print("Error: Physician requires --name")
            return
        record = {
            "name": args.name,
            "specialty": args.specialty or 'Primary Care',
            "phone": args.phone or ''
        }
        data['physicians'].append(record)
        print(f"✓ Added physician: {args.name}")
    
    elif args.type == 'emergency-contact':
        if not args.name:
            print("Error: Emergency contact requires --name")
            return
        record = {
            "name": args.name,
            "relationship": args.relationship or '',
            "phone": args.phone or ''
        }
        data['emergency_contacts'].append(record)
        print(f"✓ Added emergency contact: {args.name}")
    
    save_history(data)
    print(f"\nStored in: {HISTORY_FILE}")

if __name__ == '__main__':
    main()


path: scripts/add_medication.py
content: #!/usr/bin/env python3
"""Add a medication to the health records."""
import json
import os
import sys
import uuid
import argparse
from datetime import datetime

HEALTH_DIR = os.path.expanduser("~/.openclaw/workspace/memory/health")
MEDS_FILE = os.path.join(HEALTH_DIR, "medications.json")

def ensure_dir():
    os.makedirs(HEALTH_DIR, exist_ok=True)

def load_meds():
    if os.path.exists(MEDS_FILE):
        with open(MEDS_FILE, 'r') as f:
            return json.load(f)
    return {"medications": []}

def save_meds(data):
    ensure_dir()
    with open(MEDS_FILE, 'w') as f:
        json.dump(data, f, indent=2)

def check_interaction(new_med, existing_meds):
    """Basic interaction checking - informational only."""
    warnings = []
    new_lower = new_med.lower()
    
    # Common interaction pairs (simplified)
    interactions = {
        "warfarin": ["aspirin", "ibuprofen", "naproxen"],
        "lisinopril": ["potassium supplements", "spironolactone"],
        "metformin": ["contrast dye"],
        "simvastatin": ["gemfibrozil", "clarithromycin"],
    }
    
    for med, interacts_with in interactions.items():
        if med in new_lower:
            for existing in existing_meds:
                existing_lower = existing['name'].lower()
                for interact in interacts_with:
                    if interact in existing_lower:
                        warnings.append(f"{new_med} may interact with {existing['name']}")
        
        # Check reverse
        for existing in existing_meds:
            existing_lower = existing['name'].lower()
            if med in existing_lower:
                for interact in interacts_with:
                    if interact in new_lower:
                        warnings.append(f"{existing['name']} may interact with {new_med}")
    
    return warnings

def main():
    parser = argparse.ArgumentParser(description='Add a medication')
    parser.add_argument('--name', required=True, help='Medication name')
    parser.add_argument('--dosage', required=True, help='Dosage (e.g., 10mg)')
    parser.add_argument('--frequency', required=True, help='Frequency (e.g., once daily)')
    parser.add_argument('--time', default='', help='Time of day (morning/evening/with meals)')
    parser.add_argument('--with-food', action='store_true', help='Take with food')
    parser.add_argument('--purpose', default='', help='What it treats')
    parser.add_argument('--doctor', default='', help='Prescribing doctor')
    parser.add_argument('--start-date', default=datetime.now().strftime('%Y-%m-%d'), 
                        help='Start date (YYYY-MM-DD)')
    
    args = parser.parse_args()
    
    data = load_meds()
    
    # Check for interactions
    warnings = check_interaction(args.name, data['medications'])
    
    med = {
        "id": str(uuid.uuid4())[:8],
        "name": args.name,
        "dosage": args.dosage,
        "frequency": args.frequency,
        "time_of_day": args.time,
        "with_food": args.with_food,
        "purpose": args.purpose,
        "prescribing_doctor": args.doctor,
        "start_date": args.start_date,
        "end_date": None,
        "ongoing": True,
        "added_at": datetime.now().isoformat()
    }
    
    data['medications'].append(med)
    save_meds(data)
    
    print(f"✓ Added: {args.name} {args.dosage} - {args.frequency}")
    if warnings:
        print("\n⚠️  Interaction warnings (consult doctor/pharmacist):")
        for w in warnings:
            print(f"   • {w}")
    print(f"\nStored in: {MEDS_FILE}")

if __name__ == '__main__':
    main()


path: scripts/add_symptom.py
content: #!/usr/bin/env python3
"""Add a symptom to the tracker."""
import json
import os
import uuid
import argparse
from datetime import datetime

HEALTH_DIR = os.path.expanduser("~/.openclaw/workspace/memory/health")
SYMPTOMS_FILE = os.path.join(HEALTH_DIR, "symptoms.json")

def ensure_dir():
    os.makedirs(HEALTH_DIR, exist_ok=True)

def load_symptoms():
    if os.path.exists(SYMPTOMS_FILE):
        with open(SYMPTOMS_FILE, 'r') as f:
            return json.load(f)
    return {"symptoms": []}

def save_symptoms(data):
    ensure_dir()
    with open(SYMPTOMS_FILE, 'w') as f:
        json.dump(data, f, indent=2)

def check_emergency_red_flags(description):
    """Check for symptoms that suggest emergency."""
    red_flags = [
        "chest pain", "can't breathe", "difficulty breathing", 
        "severe bleeding", "unconscious", "suicidal",
        "worst headache", "stroke", "heart attack"
    ]
    desc_lower = description.lower()
    for flag in red_flags:
        if flag in desc_lower:
            return True
    return False

def main():
    parser = argparse.ArgumentParser(description='Add a symptom')
    parser.add_argument('--description', required=True, help='Symptom description')
    parser.add_argument('--severity', type=int, required=True, 
                        help='Severity 1-10', choices=range(1, 11))
    parser.add_argument('--location', default='', help='Body location')
    parser.add_argument('--triggers', default='', help='Triggers (comma-separated)')
    parser.add_argument('--notes', default='', help='Additional notes')
    
    args = parser.parse_args()
    
    # Check for emergency red flags
    if check_emergency_red_flags(args.description):
        print("🚨 EMERGENCY WARNING 🚨")
        print("Your symptom description may indicate a medical emergency.")
        print("If you are experiencing chest pain, difficulty breathing, severe bleeding,")
        print("or thoughts of self-harm, call 911 or your local emergency number immediately.")
        print("\nDo not wait - seek emergency care now.")
        sys.exit(1)
    
    data = load_symptoms()
    
    symptom = {
        "id": str(uuid.uuid4())[:8],
        "description": args.description,
        "severity": args.severity,
        "location": args.location,
        "triggers": [t.strip() for t in args.triggers.split(',') if t.strip()],
        "notes": args.notes,
        "timestamp": datetime.now().isoformat(),
        "ongoing": True
    }
    
    data['symptoms'].append(symptom)
    save_symptoms(data)
    
    print(f"✓ Logged: {args.description}")
    print(f"  Severity: {args.severity}/10")
    print(f"  Time: {datetime.now().strftime('%Y-%m-%d %H:%M')}")
    if args.location:
        print(f"  Location: {args.location}")
    print(f"\nStored in: {SYMPTOMS_FILE}")

if __name__ == '__main__':
    main()


path: scripts/add_vital.py
content: #!/usr/bin/env python3
"""Add a vital sign reading."""
import json
import os
import uuid
import argparse
from datetime import datetime

HEALTH_DIR = os.path.expanduser("~/.openclaw/workspace/memory/health")
VITALS_FILE = os.path.join(HEALTH_DIR, "vitals.json")

def ensure_dir():
    os.makedirs(HEALTH_DIR, exist_ok=True)

def load_vitals():
    if os.path.exists(VITALS_FILE):
        with open(VITALS_FILE, 'r') as f:
            return json.load(f)
    return {"vitals": {}, "targets": {}}

def save_vitals(data):
    ensure_dir()
    with open(VITALS_FILE, 'w') as f:
        json.dump(data, f, indent=2)

def main():
    parser = argparse.ArgumentParser(description='Add vital sign reading')
    parser.add_argument('--type', required=True, 
                        choices=['bp', 'glucose', 'weight', 'hr', 'temp', 'pain', 'o2'],
                        help='Type of vital sign')
    parser.add_argument('--systolic', type=int, help='BP systolic')
    parser.add_argument('--diastolic', type=int, help='BP diastolic')
    parser.add_argument('--value', help='Value (for glucose, weight, etc)')
    parser.add_argument('--unit', default='', help='Unit (mg/dL, lbs, etc)')
    parser.add_argument('--context', default='', help='Context (fasting, resting, etc)')
    parser.add_argument('--location', default='', help='Pain location')
    parser.add_argument('--level', type=int, choices=range(0, 11), help='Pain level 0-10')
    parser.add_argument('--notes', default='', help='Additional notes')
    
    args = parser.parse_args()
    
    data = load_vitals()
    timestamp = datetime.now().isoformat()
    
    reading = {
        "id": str(uuid.uuid4())[:8],
        "timestamp": timestamp,
        "notes": args.notes
    }
    
    vital_type = args.type
    
    if vital_type == 'bp':
        if not args.systolic or not args.diastolic:
            print("Error: BP requires --systolic and --diastolic")
            sys.exit(1)
        reading['systolic'] = args.systolic
        reading['diastolic'] = args.diastolic
        display = f"{args.systolic}/{args.diastolic} mmHg"
        
        # Check against target
        target = data.get('targets', {}).get('bp', {})
        if target:
            sys_max = target.get('systolic_max', 130)
            dia_max = target.get('diastolic_max', 85)
            if args.systolic > sys_max or args.diastolic > dia_max:
                print(f"⚠️  Above target: <{sys_max}/{dia_max}")
    
    elif vital_type == 'glucose':
        if not args.value:
            print("Error: Glucose requires --value")
            sys.exit(1)
        reading['value'] = float(args.value)
        reading['unit'] = args.unit or 'mg/dL'
        reading['context'] = args.context
        display = f"{args.value} {reading['unit']}"
        if args.context:
            display += f" ({args.context})"
    
    elif vital_type == 'weight':
        if not args.value:
            print("Error: Weight requires --value")
            sys.exit(1)
        reading['value'] = float(args.value)
        reading['unit'] = args.unit or 'lbs'
        display = f"{args.value} {reading['unit']}"
    
    elif vital_type == 'hr':
        if not args.value:
            print("Error: Heart rate requires --value")
            sys.exit(1)
        reading['value'] = int(args.value)
        reading['unit'] = 'bpm'
        reading['context'] = args.context or 'resting'
        display = f"{args.value} bpm ({reading['context']})"
    
    elif vital_type == 'pain':
        if args.level is None:
            print("Error: Pain requires --level (0-10)")
            sys.exit(1)
        reading['level'] = args.level
        reading['location'] = args.location
        display = f"Level {args.level}/10"
        if args.location:
            display += f" - {args.location}"
    
    else:
        reading['value'] = args.value
        reading['unit'] = args.unit
        display = f"{args.value} {args.unit}"
    
    if vital_type not in data['vitals']:
        data['vitals'][vital_type] = []
    
    data['vitals'][vital_type].append(reading)
    save_vitals(data)
    
    print(f"✓ Logged: {display}")
    print(f"  Time: {datetime.now().strftime('%Y-%m-%d %H:%M')}")
    print(f"\nStored in: {VITALS_FILE}")

if __name__ == '__main__':
    import sys
    main()


path: scripts/check_interactions.py
content: #!/usr/bin/env python3
"""Check for drug interactions."""
import json
import os
import argparse

HEALTH_DIR = os.path.expanduser("~/.openclaw/workspace/memory/health")
MEDS_FILE = os.path.join(HEALTH_DIR, "medications.json")

# Simplified interaction database - for informational use only
INTERACTIONS = {
    "warfarin": {
        "interacts_with": ["aspirin", "ibuprofen", "naproxen", "amiodarone", "metronidazole"],
        "category": "Major",
        "effect": "Increased bleeding risk"
    },
    "lisinopril": {
        "interacts_with": ["potassium supplements", "spironolactone", "losartan"],
        "category": "Moderate",
        "effect": "Increased potassium levels (hyperkalemia)"
    },
    "metformin": {
        "interacts_with": ["contrast dye", "cimetidine", "furosemide"],
        "category": "Moderate",
        "effect": "Increased side effects or kidney concerns"
    },
    "atorvastatin": {
        "interacts_with": ["gemfibrozil", "clarithromycin", "itraconazole", "cyclosporine"],
        "category": "Major",
        "effect": "Increased muscle damage risk (rhabdomyolysis)"
    },
    "simvastatin": {
        "interacts_with": ["gemfibrozil", "clarithromycin", "amiodarone", "verapamil"],
        "category": "Major",
        "effect": "Increased muscle damage risk"
    },
    "digoxin": {
        "interacts_with": ["amiodarone", "verapamil", "quinidine"],
        "category": "Major",
        "effect": "Increased digoxin toxicity"
    }
}

def load_meds():
    if not os.path.exists(MEDS_FILE):
        return {"medications": []}
    with open(MEDS_FILE, 'r') as f:
        return json.load(f)

def check_interactions(med_name, existing_meds):
    """Check a medication against interaction database."""
    warnings = []
    med_lower = med_name.lower()
    
    # Check if new med is in interaction database
    for drug, info in INTERACTIONS.items():
        if drug in med_lower:
            for existing in existing_meds:
                existing_lower = existing['name'].lower()
                for interact in info['interacts_with']:
                    if interact in existing_lower:
                        warnings.append({
                            'drug1': med_name,
                            'drug2': existing['name'],
                            'category': info['category'],
                            'effect': info['effect']
                        })
        
        # Check reverse - existing med in database, new med in interacts_with
        for existing in existing_meds:
            existing_lower = existing['name'].lower()
            if drug in existing_lower:
                for interact in info['interacts_with']:
                    if interact in med_lower:
                        warnings.append({
                            'drug1': existing['name'],
                            'drug2': med_name,
                            'category': info['category'],
                            'effect': info['effect']
                        })
    
    return warnings

def main():
    parser = argparse.ArgumentParser(description='Check drug interactions')
    parser.add_argument('--new', help='New medication to check')
    parser.add_argument('--drug1', help='First drug to compare')
    parser.add_argument('--drug2', help='Second drug to compare')
    
    args = parser.parse_args()
    
    print("=" * 60)
    print("DRUG INTERACTION CHECK")
    print("⚠️  For informational purposes only - consult pharmacist/doctor")
    print("=" * 60)
    
    if args.drug1 and args.drug2:
        # Direct comparison
        warnings = check_interactions(args.drug1, [{'name': args.drug2}])
        if warnings:
            for w in warnings:
                print(f"\n🔴 {w['category'].upper()} INTERACTION")
                print(f"   {w['drug1']} + {w['drug2']}")
                print(f"   Potential effect: {w['effect']}")
        else:
            print(f"\n✓ No known major interactions between {args.drug1} and {args.drug2}")
            print("  (Limited database - always verify with pharmacist)")
    
    elif args.new:
        # Check against current medications
        data = load_meds()
        current_meds = [m for m in data.get('medications', []) if m.get('ongoing', True)]
        
        if not current_meds:
            print(f"\nNo current medications on file.")
            print(f"Would check interactions between {args.new} and your medication list.")
            return
        
        print(f"\nChecking {args.new} against {len(current_meds)} current medications...")
        
        warnings = check_interactions(args.new, current_meds)
        
        if warnings:
            print(f"\n⚠️  Found {len(warnings)} potential interaction(s):\n")
            for w in warnings:
                print(f"🔴 {w['category'].upper()}")
                print(f"   {w['drug1']} + {w['drug2']}")
                print(f"   Effect: {w['effect']}")
                print()
        else:
            print(f"\n✓ No major interactions detected with {args.new}")
            print("  (Limited database - always verify with pharmacist)")
        
        print("\nCurrent medications:")
        for m in current_meds:
            print(f"  • {m['name']} {m['dosage']}")
    
    else:
        print("\nUsage:")
        print("  Check new med: python check_interactions.py --new 'Medication Name'")
        print("  Compare two:   python check_interactions.py --drug1 'A' --drug2 'B'")
    
    print("\n" + "=" * 60)
    print("IMPORTANT: This check uses a limited database.")
    print("Always consult your doctor or pharmacist before starting,")
    print("stopping, or changing any medication.")
    print("=" * 60)

if __name__ == '__main__':
    main()


path: scripts/generate_emergency_card.py
content: #!/usr/bin/env python3
"""Generate emergency health card."""
import json
import os
import argparse
from datetime import datetime

HEALTH_DIR = os.path.expanduser("~/.openclaw/workspace/memory/health")

def load_json(filename):
    filepath = os.path.join(HEALTH_DIR, filename)
    if os.path.exists(filepath):
        with open(filepath, 'r') as f:
            return json.load(f)
    return {}

def get_emergency_data():
    """Collect all emergency-relevant data."""
    history = load_json("history.json")
    meds = load_json("medications.json")
    
    data = {
        "name": history.get('personal_info', {}).get('full_name', ''),
        "dob": history.get('personal_info', {}).get('date_of_birth', ''),
        "blood_type": history.get('personal_info', {}).get('blood_type', 'Unknown'),
        "organ_donor": history.get('personal_info', {}).get('organ_donor', False),
        "allergies": history.get('allergies', {}),
        "conditions": [c.get('condition') for c in history.get('conditions', [])],
        "medications": [],
        "emergency_contacts": history.get('emergency_contacts', []),
        "primary_physician": history.get('physicians', [{}])[0] if history.get('physicians') else {}
    }
    
    # Get current medications
    for med in meds.get('medications', []):
        if med.get('ongoing', True):
            data['medications'].append({
                'name': med['name'],
                'dose': f"{med['dosage']} {med['frequency']}"
            })
    
    return data

def generate_phone_format(data):
    """Generate phone lock screen optimized format."""
    donor = "Y" if data['organ_donor'] else "N"
    
    output = []
    output.append("╔" + "═" * 46 + "╗")
    output.append("║" + " ⚠️  EMERGENCY HEALTH INFO  ⚠️ ".center(46) + "║")
    output.append("╠" + "═" * 46 + "╣")
    
    name_line = f" {data['name'][:25]} • DOB: {data['dob']}".ljust(46) + "║"
    output.append("║" + name_line)
    output.append(f"║  Blood Type: {data['blood_type']} • Organ Donor: {donor}".ljust(47) + "║")
    
    # Allergies
    allergies = data['allergies'].get('medications', [])
    if allergies:
        output.append("╠" + "═" * 46 + "╣")
        output.append("║" + " 🚨 ALLERGIES:".ljust(47) + "║")
        for allergy in allergies[:3]:  # Limit to 3
            reaction = allergy.get('reaction', '')[:15]
            line = f"   • {allergy['allergen'][:20]} = {reaction}".ljust(46) + "║"
            output.append("║" + line)
    
    # Conditions
    if data['conditions']:
        output.append("╠" + "═" * 46 + "╣")
        conds = ", ".join(data['conditions'][:4])
        output.append("║" + f" CONDITIONS: {conds[:40]}".ljust(47) + "║")
    
    # Medications
    if data['medications']:
        output.append("╠" + "═" * 46 + "╣")
        output.append("║" + " MEDICATIONS:".ljust(47) + "║")
        for med in data['medications'][:5]:
            line = f"   • {med['name'][:15]} {med['dose'][:20]}".ljust(46) + "║"
            output.append("║" + line)
    
    # Emergency contact
    if data['emergency_contacts']:
        output.append("╠" + "═" * 46 + "╣")
        contact = data['emergency_contacts'][0]
        line = f" ICE: {contact.get('name', '')} {contact.get('phone', '')}".ljust(46) + "║"
        output.append("║" + line)
    
    if data['primary_physician']:
        doc = data['primary_physician']
        line = f" Dr: {doc.get('name', '')[:15]} {doc.get('phone', '')}".ljust(46) + "║"
        output.append("║" + line)
    
    output.append("╚" + "═" * 46 + "╝")
    
    return "\n".join(output)

def generate_wallet_format(data):
    """Generate wallet card format."""
    lines = []
    lines.append("=" * 48)
    lines.append("EMERGENCY HEALTH INFORMATION")
    lines.append("-" * 48)
    lines.append(f"{data['name'][:30]} • DOB: {data['dob']}")
    lines.append(f"Blood Type: {data['blood_type']} • Organ Donor: {'Yes' if data['organ_donor'] else 'No'}")
    lines.append("-" * 48)
    
    allergies = data['allergies'].get('medications', [])
    if allergies:
        lines.append("ALLERGIES:")
        for a in allergies[:3]:
            lines.append(f"  • {a['allergen']}: {a.get('reaction', 'Unknown')}")
    
    if data['conditions']:
        lines.append("CONDITIONS: " + ", ".join(data['conditions'][:5]))
    
    if data['medications']:
        lines.append("MEDICATIONS:")
        for m in data['medications'][:4]:
            lines.append(f"  • {m['name']} {m['dose']}")
    
    if data['emergency_contacts']:
        c = data['emergency_contacts'][0]
        lines.append(f"EMERGENCY: {c.get('name', '')} {c.get('phone', '')}")
    
    lines.append("=" * 48)
    
    return "\n".join(lines)

def main():
    parser = argparse.ArgumentParser(description='Generate emergency health card')
    parser.add_argument('--format', choices=['phone', 'wallet', 'json'], 
                        default='phone', help='Output format')
    parser.add_argument('--output', help='Save to file')
    
    args = parser.parse_args()
    
    data = get_emergency_data()
    
    if not data['name']:
        print("⚠️  No personal info found.")
        print("Add your details to history.json first:")
        print('  scripts/add_history_record.py --type personal-info ...')
        return
    
    if args.format == 'phone':
        output = generate_phone_format(data)
    elif args.format == 'wallet':
        output = generate_wallet_format(data)
    else:
        output = json.dumps(data, indent=2)
    
    if args.output:
        with open(args.output, 'w') as f:
            f.write(output)
        print(f"✓ Emergency card saved to: {args.output}")
    else:
        print(output)
    
    print("\n💡 Tips:")
    print("  • Screenshot the phone format for your lock screen")
    print("  • Print the wallet format to keep in your wallet")
    print("  • Update whenever medications or allergies change")

if __name__ == '__main__':
    main()


path: scripts/get_vital_trends.py
content: #!/usr/bin/env python3
"""Get vital signs trends and averages."""
import json
import os
import argparse
from datetime import datetime, timedelta
from collections import defaultdict

HEALTH_DIR = os.path.expanduser("~/.openclaw/workspace/memory/health")
VITALS_FILE = os.path.join(HEALTH_DIR, "vitals.json")

def load_vitals():
    if not os.path.exists(VITALS_FILE):
        return {"vitals": {}, "targets": {}}
    with open(VITALS_FILE, 'r') as f:
        return json.load(f)

def get_readings_in_period(readings, days=7):
    """Get readings from last N days."""
    cutoff = datetime.now() - timedelta(days=days)
    return [r for r in readings if datetime.fromisoformat(r['timestamp']) > cutoff]

def analyze_bp(readings):
    """Analyze blood pressure readings."""
    if not readings:
        return None
    
    systolics = [r['systolic'] for r in readings]
    diastolics = [r['diastolic'] for r in readings]
    
    return {
        'avg_systolic': round(sum(systolics) / len(systolics)),
        'avg_diastolic': round(sum(diastolics) / len(diastolics)),
        'min_sys': min(systolics),
        'max_sys': max(systolics),
        'min_dia': min(diastolics),
        'max_dia': max(diastolics),
        'count': len(readings)
    }

def analyze_glucose(readings):
    """Analyze glucose readings."""
    if not readings:
        return None
    
    values = [r['value'] for r in readings]
    fasting = [r['value'] for r in readings if r.get('context') == 'fasting']
    
    result = {
        'avg': round(sum(values) / len(values), 1),
        'min': min(values),
        'max': max(values),
        'count': len(readings)
    }
    
    if fasting:
        result['avg_fasting'] = round(sum(fasting) / len(fasting), 1)
    
    return result

def analyze_weight(readings):
    """Analyze weight readings."""
    if not readings:
        return None
    
    values = [r['value'] for r in readings]
    
    return {
        'latest': values[-1],
        'start': values[0],
        'change': round(values[-1] - values[0], 1),
        'avg': round(sum(values) / len(values), 1),
        'count': len(readings)
    }

def main():
    parser = argparse.ArgumentParser(description='Get vital signs trends')
    parser.add_argument('--type', choices=['bp', 'glucose', 'weight', 'all'],
                        default='all', help='Vital type to analyze')
    parser.add_argument('--period', choices=['week', 'month'],
                        default='week', help='Time period')
    parser.add_argument('--chart', action='store_true',
                        help='Show simple ASCII chart')
    
    args = parser.parse_args()
    
    days = 7 if args.period == 'week' else 30
    
    data = load_vitals()
    vitals = data.get('vitals', {})
    targets = data.get('targets', {})
    
    print(f"\nVITAL SIGNS TREND REPORT")
    print(f"Period: Last {days} days")
    print("=" * 50)
    
    if args.type in ['bp', 'all']:
        bp_readings = get_readings_in_period(vitals.get('bp', []), days)
        if bp_readings:
            analysis = analyze_bp(bp_readings)
            print(f"\n📊 BLOOD PRESSURE")
            print(f"   Average: {analysis['avg_systolic']}/{analysis['avg_diastolic']} mmHg")
            print(f"   Range: {analysis['min_sys']}-{analysis['max_sys']}/{analysis['min_dia']}-{analysis['max_dia']}")
            print(f"   Readings: {analysis['count']}")
            
            bp_target = targets.get('bp', {})
            if bp_target:
                sys_max = bp_target.get('systolic_max', 130)
                dia_max = bp_target.get('diastolic_max', 85)
                above = sum(1 for r in bp_readings 
                          if r['systolic'] > sys_max or r['diastolic'] > dia_max)
                print(f"   Above target (<{sys_max}/{dia_max}): {above} readings")
        else:
            print(f"\n📊 BLOOD PRESSURE: No readings in last {days} days")
    
    if args.type in ['glucose', 'all']:
        glucose_readings = get_readings_in_period(vitals.get('glucose', []), days)
        if glucose_readings:
            analysis = analyze_glucose(glucose_readings)
            print(f"\n📊 BLOOD GLUCOSE")
            print(f"   Average: {analysis['avg']} mg/dL")
            if 'avg_fasting' in analysis:
                print(f"   Avg fasting: {analysis['avg_fasting']} mg/dL")
            print(f"   Range: {analysis['min']}-{analysis['max']}")
            print(f"   Readings: {analysis['count']}")
        else:
            print(f"\n📊 BLOOD GLUCOSE: No readings in last {days} days")
    
    if args.type in ['weight', 'all']:
        weight_readings = get_readings_in_period(vitals.get('weight', []), days)
        if weight_readings:
            analysis = analyze_weight(weight_readings)
            unit = weight_readings[0].get('unit', 'lbs')
            print(f"\n📊 WEIGHT")
            print(f"   Latest: {analysis['latest']} {unit}")
            print(f"   Start of period: {analysis['start']} {unit}")
            change_str = f"+{analysis['change']}" if analysis['change'] > 0 else str(analysis['change'])
            print(f"   Change: {change_str} {unit}")
            print(f"   Readings: {analysis['count']}")
        else:
            print(f"\n📊 WEIGHT: No readings in last {days} days")
    
    print("\n" + "=" * 50)
    print("💡 Discuss trends with your doctor at your next appointment.")

if __name__ == '__main__':
    main()


path: scripts/list_medications.py
content: #!/usr/bin/env python3
"""List current medications."""
import json
import os
import argparse

HEALTH_DIR = os.path.expanduser("~/.openclaw/workspace/memory/health")
MEDS_FILE = os.path.join(HEALTH_DIR, "medications.json")

def load_meds():
    if not os.path.exists(MEDS_FILE):
        return {"medications": []}
    with open(MEDS_FILE, 'r') as f:
        return json.load(f)

def main():
    parser = argparse.ArgumentParser(description='List medications')
    parser.add_argument('--current-only', action='store_true', 
                        help='Show only active medications')
    parser.add_argument('--format', choices=['table', 'json'], default='table',
                        help='Output format')
    
    args = parser.parse_args()
    
    data = load_meds()
    meds = data.get('medications', [])
    
    if args.current_only:
        meds = [m for m in meds if m.get('ongoing', True)]
    
    if not meds:
        print("No medications recorded.")
        return
    
    if args.format == 'json':
        print(json.dumps(meds, indent=2))
        return
    
    # Table format
    print(f"\n{'Medication':<20} {'Dosage':<12} {'Frequency':<15} {'Notes':<20}")
    print("-" * 70)
    
    for med in meds:
        status = "[STOPPED]" if not med.get('ongoing', True) else ""
        notes = []
        if med.get('with_food'):
            notes.append("with food")
        if med.get('time_of_day'):
            notes.append(med['time_of_day'])
        note_str = ", ".join(notes)
        
        print(f"{med['name']:<20} {med['dosage']:<12} {med['frequency']:<15} {note_str:<15} {status}")
    
    print(f"\nTotal: {len(meds)} medications")
    if args.current_only:
        print("(Showing active medications only)")

if __name__ == '__main__':
    main()


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (CRITICAL)