Skip to main content

haircut-log

Log haircuts with before/after photos, dates, barber, style notes. Track haircut history over time.

الانتقال إلى التثبيت

معلومات المصدر

المستودع
rishijatia/Hakan
آخر نشاط في المصدر
١٣ مايو ٢٠٢٦ في ٠٣:١٥
لغة SKILL.md المكتشفة
الإنجليزية
النجوم
٠
التفرعات
٠

خيارات التثبيت

يُحدَّد Prompt الذي يراجع المصدر أولًا بشكل افتراضي. يمكنك التبديل إلى أمر مباشر أو تنزيل نسخة محلية.

مراجعة ملفات المصدر

اقرأ SKILL.md وأي ملفات مرافقة يعرضها SkillsMP قبل أن تقرر التثبيت.

مستكشف الملفات
2 ملفات

عرض SKILL.md

SKILL.md
تعليمات المصدر · معاينة للقراءة فقط
name
haircut-log
version
0.1.0
description
Log haircuts with before/after photos, dates, barber, style notes. Track haircut history over time.
triggers
["haircut","barber","hair style","before after","haircut log","haircut history"]
metadata
{"hermes":{"tags":["lifestyle","photos","personal","grooming"],"related_skills":[]}}
# Haircut Log Track haircuts with photos, dates, barber details, style notes, and optional ratings. ## Storage - **Log file:** `/opt/data/haircuts/log.json` — structured JSON with `schema_version` and `entries` array - **Photos:** `/opt/data/haircuts/photos/` — named `{id}_{kind}.{ext}` (e.g., `20260511-01_before.jpg`) ## Schema (v1) ```json { "schema_version": 1, "entries": [ { "id": "20260511-01", "date": "2026-05-11", "created_at": "2026-05-11T10:30:00Z", "updated_at": "2026-05-11T18:00:00Z", "barber": "Name or shop", "style": "Description of cut", "tags": ["fade", "short"], "cost": null, "notes": "Any extra notes", "photos": [ {"kind": "before", "path": "photos/20260511-01_before.jpg"}, {"kind": "after", "path": "photos/20260511-01_after.jpg"} ], "rating": null } ] } ``` ### Fields - `id` — `YYYYMMDD-NN` (date + sequence number for same-day duplicates). Required. - `date` — Haircut date, `YYYY-MM-DD`. Required. - `created_at` — ISO 8601 timestamp when entry was created. Required. - `updated_at` — ISO 8601 timestamp of last modification. Updated on rating, photo additions, etc. - `barber` — Name of barber or shop. Optional. - `style` — Description of the haircut/style requested. Optional. - `tags` — Array of searchable tags: `["fade", "beard-trim", "short", "long"]`. Optional. - `cost` — Price in dollars (number). Optional. - `notes` — Freeform notes. Optional. - `photos` — Array of `{kind, path}` objects. `kind` is `"before"`, `"after"`, `"mid"`, or `"other"`. Optional. - `rating` — 1-5 rating, can be added later. Optional (stored as `null` until rated). ## Usage ### Logging a New Haircut When user mentions getting a haircut or sends a haircut photo: 1. **Photo processing with vision model:** - Use `vision_analyze(image_url=..., question="Describe this photo — is it a before or after haircut photo? Describe the haircut/style.")` to process the image - `vision_analyze` auto-falls back to a vision-capable model when the current model doesn't support vision - This lets you "see" the photo even on non-vision models 2. **Save the photo** to `/opt/data/haircuts/photos/{id}_{kind}.{ext}` - If the image is a URL, download it: `curl -o /opt/data/haircuts/photos/{id}_{kind}.{ext} "<url>"` - If the image is a local file path, copy it: `cp <path> /opt/data/haircuts/photos/{id}_{kind}.{ext}` 3. **Create entry** with today's date and a new `id` (check existing entries for same-day collisions — increment `NN`) 4. **Ask minimally** — if user just sends a photo, log it. Don't interrogate about barber/style/notes unless they volunteer. ### Adding a Photo Later If user sends another photo for the same day: - Process with `vision_analyze` to identify if it's before/after/mid/other - Find existing entry for today (or most recent entry if sent same day) - Add photo to the entry's `photos` array with appropriate `kind` - Update `updated_at` ### Rating Later When user says "rate my last haircut" or "4 out of 5": - Find the most recent entry with `rating: null` (or the one they're referring to) - Set `rating`, update `updated_at` ### Updating an Entry If user corrects barber, style, or notes: - Find entry by date or "last one" - Update the field(s), set `updated_at` ### Queries - **"Show last haircut"** → Read last entry, use `vision_analyze` to show/describe the photo - **"How often do I get haircuts?"** → Compute average days between entries - **"Show all by Tony"** → Filter entries by barber field - **"Show all fades"** → Filter by tags containing "fade" ## Atomic Write Rule **Always** write atomically to prevent corruption: ```python import json, os, tempfile fd, tmp = tempfile.mkstemp(dir="/opt/data/haircuts", suffix=".tmp") try: with os.fdopen(fd, "w") as f: json.dump(data, f, indent=2) os.replace(tmp, "/opt/data/haircuts/log.json") except: os.unlink(tmp) raise ``` ## Backup Rule Before writing, copy `log.json` to `log.json.bak` if it exists. ## Setup Create directories on first use: ```bash mkdir -p /opt/data/haircuts/photos ``` If `log.json` doesn't exist, create it as `{"schema_version": 1, "entries": []}`. ### Vision Setup (required for photo analysis) `vision_analyze` needs an explicitly configured vision provider. `provider: auto` silently fails. Edit `/opt/data/config.yaml`: ```yaml auxiliary: vision: provider: openrouter model: google/gemini-2.0-flash-001 base_url: https://openrouter.ai/api/v1 api_key: '' # empty = uses main provider's key timeout: 120 ``` After editing, **restart the gateway** for changes to take effect: ```bash fly apps restart hermes-agent ``` The config change must also be synced to GitHub (`flyio/config.yaml` in the Hakan repo). See [references/vision-setup.md](references/vision-setup.md) for alternatives and troubleshooting. ## Pitfalls 1. **EXIF leaks location** — Always strip EXIF from photos before saving. Telegram re-encodes photos (usually strips EXIF), but direct file uploads may retain it. If Pillow is available: `python3 -c "from PIL import Image; Image.open(f).save(f, exif=b'')"`. If not, note it as a known limitation. 2. **Vision model for photos** — `vision_analyze` requires a vision provider **explicitly** configured in `config.yaml`. The `provider: auto` setting silently fails even when API keys are present. You must set all three: `provider`, `model`, and `base_url`. See [references/vision-setup.md](references/vision-setup.md) for the exact config. Without this, photos can still be saved but cannot be analyzed/described. 3. **Same-day collisions** — Use `YYYYMMDD-NN` IDs so two haircuts on the same day don't overwrite each other. 3. **Photo extension varies** — Telegram sends WEBP, iPhone sends HEIC, screenshots are PNG. Don't hardcode `.jpg`; use the actual extension. 4. **Atomic writes** — Never write directly to `log.json`. Always write to a temp file then `os.replace()`. 5. **Don't ask too many questions** — If user sends a photo, log it. Barber/style/notes are optional; rating can come later. 6. **Date is haircut date, not log date** — If user backfills ("I got a haircut last Tuesday"), use last Tuesday's date. 7. **Backup before write** — Copy to `log.json.bak` before any modification. 8. **Timezone** — Use the user's timezone for "today" determination. Rishi is in ET (America/New_York).
عرض على GitHub