Install
openclaw skills install @yannxinn/piano-score-fingeringVerify score facts, then generate and review two-hand fingering
openclaw skills install @yannxinn/piano-score-fingeringComplete the workflow when the host can read files, inspect score pages, run Python, and write output files. Use only the bundled scripts and capabilities already present in the host. Do not require the user to install software, Python packages, browser extensions, or online recognition services.
Never generate fingering from unverified score facts merely to produce an output. Always create inspectable artifacts. Deliver one of these outcomes:
Block fingering whenever pitch, clef, accidental, rhythm, hand, chord membership, tie, voice, or notehead identity is unresolved. On failure, still deliver the recognition plan, anchor audit, and error report. Historical outputs may reveal prior error types, but must never become recognition truth or a fingering target for a new task.
Load references only when needed: use references/professional-fingering-rules.md for musical review, references/fingering-plan-schema.md when creating or repairing a visual recognition plan, and references/common-fingering-errors.md when a validator or user identifies a matching error. Keep NOTICE.txt with every redistributed copy.
measure_scope, then create one measure_region for every page + measure + hand, including rest-only measures.notes and rests in rests; never treat stems, beams, barlines, dots, text, or rectangular rest marks as notes.origin=direct_visual_notehead. Locate every member of a touching chord separately and set chord_member_verified=true. Never infer a missing member from spacing or a repeated accompaniment pattern.pdf_point coordinates with a bottom-left origin for PDFs and pixel_top_left with a top-left origin for images. Write standard MusicXML as the semantic source and a unified fingering-plan.json for identities and coordinates.The second pass verifies measure/hand note counts, accidentals, same-position neighbors, ties, rests, and chord members; it does not regenerate the whole draft. Build a review manifest:
python3 scripts/build_measure_review_manifest.py build fingering-plan.json -o measure-review.json
python3 scripts/build_measure_review_manifest.py apply fingering-plan.json measure-review.json -o review-plan.json
Inspect each evidence_crop before filling expected_noteheads, expected_rests, and duration_verified. Do not derive expected counts from current plan entries. Verified notes require recognition_passes=2, symbol_class=notehead, and notehead_shape_verified=true. Record rests separately with their type, duration, and rest_shape_verified=true.
Maintain one traceable source of truth:
draft -> review -> verified -> locked
Create a compact exception queue, review at most two local rounds, and leave unresolved items open rather than looping over the full score:
python3 scripts/manage_recognition.py queue fingering-plan.json -o review-queue.json --plan-output review-plan.json
python3 scripts/manage_recognition.py freeze review-plan.json -o locked-plan.json
python3 scripts/manage_recognition.py status locked-plan.json
The lock stores a SHA-256 digest of score facts. Fingering, color, type size, and label position may change after locking; pitch, rhythm, voice, chords, ties, staff geometry, and notehead coordinates may not. Every generator run recomputes the digest and blocks silent changes.
When a later recognition error is found, patch only the affected page, measure, and hand:
python3 scripts/manage_recognition.py patch locked-plan.json correction.json -o review-plan.json
python3 scripts/manage_recognition.py confirm review-plan.json --gates pitch_geometry rhythm chords anchors -o verified-plan.json
python3 scripts/manage_recognition.py freeze verified-plan.json -o locked-plan-v2.json
Never edit a locked plan and simply recalculate its digest.
--ignore-existing.For every system, record five staff_line_y values, its clef, and stable system_id. Bind every note through staff_geometry_id. Every scoped measure/hand needs exactly one measure_symbol_check, including rest-only measures with zero noteheads. Verify scope, staff geometry, pitch geometry, accidentals, rhythm, ties, chord membership, and anchors before setting the corresponding gate to true.
Run before any fingering calculation:
python3 scripts/validate_recognition.py fingering-plan.json
The validator derives the natural pitch from clef and staff geometry, then checks spelling, MIDI, ties, geometry, review state, and the fact lock. --allow-review is diagnostic only and never authorizes generation. An anchor is valid only when its center crosses a real oval notehead, not a rest block, stem, or beam.
Do not redraw a supplied PDF/image or replace it with image generation. Overlay vector finger numbers on the original page.
python3 scripts/create_plan_from_musicxml.py input.musicxml -o fingering-plan.json
MXL is supported directly. If MusicXML has no layout coordinates, always deliver fingered MusicXML and add PDF only when the host can render a verifiable score page. Do not claim that this Skill contains a full MusicXML engraving engine or require MuseScore. Read .mscx as XML and convert its semantics; read .mscz only when the host can unpack it, otherwise ask for MusicXML export.
Use a single plan throughout. Every note must have a stable note_id and separate:
keyboard_x_cm: physical key-center position used by the fingering algorithm;page_x/page_y: original notehead center used by the overlay;part + measure_index + staff + voice + onset + pitch_midi + chord_row.For PDF/image delivery run:
python3 scripts/validate_fingering_plan.py fingering-plan.json --require-coordinates
python3 scripts/validate_fingering_plan.py fingered-plan.json --require-verified-anchors
Derive keyboard_x_cm only from pitch_midi with the bundled keypos_midi; never estimate it from page position or note-name text. Physical key positions must increase strictly with MIDI pitch, and enharmonic spellings must map to the same key.
python3 scripts/generate_fingering_plan.py fingering-plan.json -o fingered-plan.json
For a local correction:
python3 scripts/generate_fingering_plan.py locked-plan.json -o fingered-plan-v2.json --measure-range 49-52 --context-measures 1
python3 scripts/generate_fingering_plan.py patched-fingered-plan.json -o fingered-plan-v2.json --changed-only --context-measures 1
Context measures are read-only; preserve all fingerings and manual corrections outside the target. Use hand size XXS, XS, S, M, L, XL, or XXL; default to M. With lookahead=0, select 3–8 events automatically. Use --max-auto-depth 9 only for a deliberately slow final search. Use --ignore-existing only when the user explicitly requests it, and at most once per task.
The adapted PianoPlayer core scores key distance, duration, finger strength, black-key tendencies, span, chord ordering, lookahead, and existing fingering anchors. It also penalizes skipped adjacent fingers in scalar motion, excessive 2->1 crossings, and premature use of finger 5 while a melody continues in the same direction. The output is an executable draft, not final musical truth.
Apply references/professional-fingering-rules.md in priority order. Remove hard violations first, then review full phrases and cross-measure transitions:
repeated_note or substitution exception exists;locked=true fingerings and review handoffs, simultaneities, and collisions.For manual corrections set source=reviewed, write transition_type and exception_reason, add the applicable rule_id, and set exception_verified=true only after note-by-note review. Recognition or structural errors must be fixed; musical preference warnings may remain as review items.
python3 scripts/apply_fingerings.py input.musicxml fingered-plan.json -o fingered.musicxml
python3 scripts/render_fingering_pdf.py fingered-plan.json --source input.pdf -o fingered-score.pdf
Place right-hand labels above noteheads in dark blue and left-hand labels below their own staff in dark red; never let left-hand labels enter the next system. Keep labels visibly clear of notes and notation. Use label_x, label_offset, and font_size only where ownership remains unambiguous.
For chords use chord_label_layout="stacked", one shared chord_label_x, and vertical order matching chord_row. Never scatter one chord's finger numbers diagonally, which can imply sequential attacks. Also deliver a PNG preview for image/PDF input.
For anchor inspection, render source pages to images, store them in pages[].image, then run:
python3 scripts/audit_overlay_anchors.py fingered-plan.json -o anchor-audit
python3 scripts/verify_output.py fingered-plan.json fingered-score.pdf
Render the final PDF to images and compare every page with the source. Confirm correct note/chord ownership, no missing or duplicate labels, no crop or page-order change, no collision with noteheads/accidentals/stems/beams/ties, natural cross-measure fingering, and a reopenable PDF with the correct page count.
Require evidence for all five states: recognition_verified, pitch_geometry_verified, ties_verified, fingering_rules_verified, and placement_verified. Fix only dirty measures/pages, run local checks, then perform one final whole-score pass. Limit automatic collision repair to two rounds and never create free alternating vertical offsets within one continuous group.
Create the report:
python3 scripts/create_delivery_report.py fingered-plan.json -o result-report.md --pdf fingered-score.pdf --preview fingered-score.png
Report delivery level, scope, recognized and fingered note counts, coverage, low-confidence notes, collisions, and remaining review measures. A complete result requires 100% scoped coverage and zero collisions. Deliver available files even when the result is review-required or partial, and add short practice guidance for crossings, shifts, and leaps.