feat(editor): chord inspector — author chord name + fingering (E1)#7
Merged
Conversation
Add a "Chord" section to the arrangement-editor inspector, shown whenever the selection resolves to a chord (>=2 notes sharing a save-time group). It authors the shared chord template: name, displayName, per-string fingering, and an arpeggio toggle — all inline controls (no window.prompt, which is a silent no-op in the bundled Electron). Edits go through a new EditChordTemplateCmd undo command, which finds-or-creates the matching arr.chord_templates entry keyed by the width-L fret pattern. The fret key is resolved from the full save-time group (time.toFixed(4)) exactly as reconstructChords() does, so a partial selection still authors the chord's real key and the metadata survives the save-time rebuild via relinkChordTemplate. displayName/arp now round-trip end to end (E0 deferred them): - relinkChordTemplate carries displayName (fallback to name) and arp. - routes.py wire writer emits templates[].displayName + arp; XML writer emits the chordTemplate displayName attribute. Template-level arp is wire-only — RS-XML arpeggio lives on <handShape>, so it's reconstructed there, not emitted on chordTemplate. - routes.py read side (_song_to_dict + GP import serializers) surfaces displayName/arp off the core ChordTemplate, so reload repopulates the inspector. Core lib/song.py already models display_name/arpeggio, so the round-trip is lossless with no core change. Tests: extend tests/chord_relink.test.js to assert displayName/arp are carried (matching pattern + fallback + blank cases). Note: same-fret chords share one template (first-wins), so renaming one occurrence affects all occurrences of that fret pattern — acceptable for E1; a per-_chordId split is future work. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds a Chord section to the arrangement-editor inspector, shown whenever the selection resolves to a chord (≥2 notes sharing a save-time group). A charter can author the shared chord template inline:
<select>per sounding string (—/open/1–4), width-aware vialanes()so 7/8-string charts workAll controls are inline DOM — no
window.prompt()(it's a silent no-op in the bundled Electron).How
EditChordTemplateCmdundo command (exec/rollback, likeEditAnchorFretWidthCmd). It finds-or-creates the matchingarr.chord_templatesentry keyed by the width-L fret pattern.time.toFixed(4)), exactly asreconstructChords()groups — so a partial selection (e.g. rectangle-selecting 2 of a 3-note chord) still authors the chord's real key and the metadata survives the save-time rebuild viarelinkChordTemplate.displayName/arpnow round-trip end to end (E0 deferred them):relinkChordTemplatecarriesdisplayName(fallback toname) andarp.routes.pywire writer emitstemplates[].displayName+arp; XML writer emits thechordTemplatedisplayNameattribute.routes.pyread side (_song_to_dict+ the two GP import serializers) surfacesdisplayName/arpoff the coreChordTemplate, so reload repopulates the inspector.lib/song.pyalready modelsdisplay_name/arpeggioandarrangement_from_wirealready readsdisplayName/arp, so the round-trip is lossless with no core change.Notes / limitations
arpis wire-only. RS-XMLarpeggiolives on<handShape>, not<chordTemplate>, so templatearppersists/reloads through the sloppak wire but is not emitted as a chordTemplate XML attribute — it's reconstructed from the handshape layer. Bridging templatearp→<handShape>is future work._chordIdsplit is future (E2-adjacent) work.Verify
node --check screen.js— parses.node tests/chord_relink.test.js— 6/6 pass, including newdisplayName/arpcarry + fallback + blank assertions.python -m pytest tests/— 67 pass (the one failure,test_populates_empty_notation_only_arrangement, is pre-existing onmainand unrelated to chord templates;test_xml_export.py/test_arrangement_xml_alignment.py57/57 green).Closes #4. Part of got-feedBack/feedBack#334.
🤖 Generated with Claude Code