Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Gaggiuino analytical skill for machine control, shot expression analysis, and high-performance visualization. It interprets shot data through profile intent and generates unified static/animated graphs or synchronized video overlays.
.claude/skills/gaggiuino-local/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-10 | ✗→✓ | ▲ Improved | — | — |
| case-09 | ✗→✓ | ▲ Improved | — | — |
| case-11 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✗→✗ | = Same ✗ | — | — |
| case-18 | ✗→✗ | = Same ✗ | — | — |
Gaggiuino Local is a machine-connected skill for espresso machines running the Gaggiuino mod. It enables live status monitoring, in-depth shot analysis based on profile intent vs. actual expression, profile management, and settings configuration. Additionally, it provides a high-performance rendering engine for generating static graphs, animated trajectory videos, and synchronized overlays for extraction footage.
Its core question is not simply “is this cup good?” It first asks whether the shot became what its profile was trying to make it become. In other words, it asks:
> Did this shot become the kind of coffee it was trying to be?
In Chinese:
> 这杯咖啡有没成为它本来想成为的样子?
Only after that should it move into troubleshooting or dial-in guidance.
All machine interaction goes through scripts/gaggiuino.sh.
Use this skill when the task involves one or more of these:
→ scripts/gaggiuino.sh status
→ scripts/gaggiuino.sh profiles
→ scripts/gaggiuino.sh profiles → resolve id → scripts/gaggiuino.sh select-profile <id>
→ scripts/gaggiuino.sh latest-shot
→ scripts/gaggiuino.sh shot <id>
→ scripts/gaggiuino.sh get-settings <category> first, then scripts/gaggiuino.sh update-settings <category> <json>
→ scripts/render_shot_graph.py & scripts/render_shot_video_overlay.py
http://gaggiuino.localgaggiuino.local is the machine's mDNS hostnamegaggiuino.local first~/.openclaw/workspace/memory/gaggiuino-base-url.jsongaggiuino.local fails, guide the user to check the machine's network connection and find its real LAN IP in router settingsscripts/gaggiuino.sh set-base-url <url-or-host>gaggiuino.local on connection-layer failuregaggiuino.local fail, treat the remembered IP as possibly stale and guide the user to re-check the network or update the saved addressscripts/gaggiuino.sh get-base-url to inspect the remembered address and scripts/gaggiuino.sh clear-base-url to remove itUse these as output-normalization rules, especially when replying in Chinese coffee context. They are meant to prevent literal but unnatural translations.
HyperEx / HyperEx 2.0 profiles.Use the terminology rules above, but for phase-transition replays and control-mode summaries apply the following stricter formatting rules.
When writing phase transition replays or summarizing control modes, strictly avoid exposing raw machine fields or machine-style shorthand such as type: "FLOW", target.end: 3, restriction: 4, stopConditions.pressureAbove: 4, or compressed tuples built from them. Translate them into human-readable descriptions centered on Targets, Limits, and exit conditions.
Critically: Match the output language strictly to the user's query language. Do not mix English and Chinese.
For type: flow:
For type: pressure:
Always decide first whether the task is mainly about:
Then read only the references needed for that path.
For real machine tasks, default to:
Use family as an interpretation layer, not as the first execution verdict. In real-shot analysis, judge the intended named profile first, then use family to explain broader intent, likely expectations, and common misreads.
A shot may fit the broader family yet still fail to express the named profile. A shot may also express the named profile coherently and still be worth changing for taste reasons.
For full machine semantics, read:
For family intent, graph interpretation, and broader next-move reasoning, read:
If the user asks whether the machine is ready, online, hot enough, or what profile is active:
scripts/gaggiuino.sh status immediatelyIf the user wants analysis of the latest shot or a specific shot:
scripts/gaggiuino.sh latest-shot or scripts/gaggiuino.sh shot <id>For latest-shot or historical-shot analysis, do not jump straight to troubleshooting. Always complete the following order before giving recommendations:
profile.phases first, then profile description when neededWhen replying to latest-shot or historical-shot requests, prefer this structure:
<profile name>what phases / handoffs actually ranexpressed / partially expressed / failedonly when it adds value; explain the family-level intent or expected misread without turning it into a second conclusionphase execution / shot condition / mixed / rare profile fragility1–2 concrete actions onlyDo not collapse real shot analysis into a generic coffee answer. Do not let family resemblance outrank a clearer profile-specific execution mismatch. Treat profile.name as the starting point, not the conclusion. If profile.phases clearly indicate a different known variant within the same broader family, use phase structure to refine the resolved variant. Keep intended structure and actual behavior separate: processedShot.profile.phases define the intended program structure; processedShot.datapoints show what the machine actually did over the shot. Do not use execution datapoints to replace a clearer structural signal already present in the profile phase definitions. A shot-analysis answer is incomplete unless it explicitly states whether the named profile expressed / partially expressed / failed to express before giving troubleshooting or dial-in advice. For staged named profiles, do not equate “all expected phases were entered” with “the profile was fully expressed”; judge whether key setup stages actually had enough runtime to perform their intended role.
The skill includes a unified rendering engine for transforming shot data into visual assets. All modes share a deterministic 2400x1080 pixel layout to ensure consistency between static and animated output. Both rendering scripts support absolute or relative paths, including user-home expansion (~) and automatic creation of missing parent directories.
All visual assets generated by the skill are captured in a defined standard directory with automatic naming:
shot<id>_static.pngshot<id>_animated.mp4shot<id>_overlay_landscape.mp4 or shot<id>_overlay_portrait.mp4~/.openclaw/workspace/gaggiuino-output
The --out parameter is optional; if omitted, the scripts will automatically archive the file using this standard location and naming convention.
##### Graph Renderer scripts/render_shot_graph.py
bash# Generate static PNG (shot<id>_static.png) python3 render_shot_graph.py --shot-id <id> --mode png # Generate animated MP4 (shot<id>_animated.mp4) python3 render_shot_graph.py --shot-id <id> --mode mp4
##### Video Overlay Renderer scripts/render_shot_video_overlay.py Synchronization Offset
--offset <seconds>: Align the graph with the video. Landscape (Horizontal) Automatically uses a Vertical Stack (VSTACK) layout. The graph is placed above the video.
bash# Video starts 1.4s before graph (shot<id>_overlay.mp4) python3 render_shot_video_overlay.py --shot-id <id> --video landscape.mp4 --offset 1.4
Portrait (Vertical / Smartphone) Automatically uses a Semi-transparent Overlay. The graph floats over the video.
--alpha <0.1-1.0>: Adjust opacity (1.0 = solid, 0.7 is recommended).--position <top/bottom>: Place the graph at the top or bottom of the frame.bash# Portrait overlay with custom alpha (0.7) at the bottom python3 render_shot_video_overlay.py --shot-id <id> --video portrait.mp4 --alpha 0.7 --position bottom
If the user only describes taste, extraction behavior, or dialing problems:
If the user asks a conceptual causality question such as “does this mean the profile itself is flawed?” but does not provide telemetry or explicit multi-shot evidence:
If the user provides a graph screenshot, machine screen image, or curve description:
<family> (<confidence>)strong / partial / weakthe 2–4 most important observationsmissing intent / weak image / missing profile contextask for intended profile or give 1 tentative adjustmentIf the user asks what profile / 曲线 to use, what a named profile / 曲线 is like, or asks to switch profiles / 曲线:
First distinguish between:
Do not treat a profile question as permission to change the machine.
For conceptual profile advice:
For real machine switching, always follow this order:
scripts/gaggiuino.sh profiles firstscripts/gaggiuino.sh select-profile <id> only after the target id is clearselect-profile <id> as a sent request, not a confirmed switch, unless a follow-up read confirms itFor real profile switching, the minimum valid sequence is:
confirm explicit switch intent → list profiles → resolve concrete id → send switch request → report status precisely
If the user wants machine settings changed:
get-settings <category> firstupdate-settings <category> <json>For settings changes, first distinguish between a read request and a write request. Do not treat a settings question as permission to modify the machine.
For real settings writes, always follow this order:
scripts/gaggiuino.sh get-settings <category> before planning the writescripts/gaggiuino.sh update-settings <category> <json> with a complete payload based on the fetched responseFor settings writes, the minimum valid sequence is:
read current category → modify explicit delta only → write complete payload → report status precisely
When interpreting real Gaggiuino data:
The visualization and rendering features require these system-level tools to be installed on the host:
bash sudo apt install python3-matplotlib ffmpeg
bash brew install ffmpeg python-matplotlib
PYTHONNOUSERSITE=1 is automatically used by the renderers to avoid numpy 2.x ABI conflicts from user-site packages in ~/.local.This is an unofficial, non-commercial interoperability skill for machines running the Gaggiuino mod. It does not include or redistribute Gaggiuino source code. Any Gaggiuino-related materials remain subject to their original terms, including the project’s CC BY-NC 4.0 license where applicable.
Some reference material in this skill was adapted from https://espressoaf.com/guides and https://github.com/Zer0-bit/gaggiuino/tree/community/profiles. The Gaggiuino-specific analysis protocol in this skill is an original local framework built on top of those sources and real machine behavior.
Acknowledgement: Gaggiuino — the greatest coffee project on the planet.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 10 counted toward the lift figure. The other 12 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +14 percentage points is the difference between those two pass rates over the 10 comparable cases. 1 case got worse with the skill loaded, and it is included in that figure.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.