Adds the per-track end-action model designed in docs/track-format.md §3, end to
end across both engines, both firmwares, and the editors.
Grammar (parsed + serialized by engine.js and both app.py):
rep=<n> cycles before the end-action fires (default 1)
end=stop stop after rep cycles
end=next advance one track (sugar for end=+1)
end=<±N> relative goto after rep cycles (e.g. end=-2 = D.S.)
(absent) loop forever — the metronome default
Firmware runtime (pico-cp + pico-explorer): _on_new_bar now consults a per-track
_end_plan() and fires stop / gapless-advance / relative-goto at the right bar.
A cycle = b<bars>, else one master bar; fire bar = rep * cycle. Explicit end=
governs; with no end, the global Continue toggle stays a default (=end=next, still
needs b<bars>) so existing set-lists and the CONT UI are unchanged. _prepare_next
takes a target index; the seam machinery, _do_advance and live-sync all carry rep/end.
Editors (editor.html + editor-beta.html): state.rep/state.end thread through
applySetup / currentSetup / currentPatch so load -> edit -> save preserves the
flow; authoring is via the program-string field (no graphical control yet).
Tests: the 3 playback-flow vectors now pass on both engines (39 pass / 3 known).
Runtime decision logic (_end_plan / _goto_target) unit-tested for stop, rep,
relative goto clamp/wrap, and legacy-Continue precedence. Codec round-trip
verified idempotent. Both firmwares compile + mpy-cross clean.
Also: untrack stale __pycache__/*.pyc build artifacts and gitignore them.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
MicroPython sim that runs on https://wokwi.com/pi-pico: KY-040 encoder stands in
for the thumb-roller (rotate=tempo, press=start/stop, hold+rotate=track), an
SSD1306 OLED for the display, and a piezo buzzer for the click. Files:
diagram.json, main.py, ssd1306.py + README with the (manual) setup steps.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>