make-midi-episode11-demo.sh bash
119 lines 3.8 KB
Raw
sha256:41074b7f9893918b26fe292dddb55c83bec08ae17aeb2acfd73d9fcc00587585 Add Episode 11 script (Muse Understands Music) and MIDI dem… Sonnet 5 patch 11 hours ago
1 #!/usr/bin/env bash
2 # Builds midi-episode11/ — a disposable MIDI-domain repo for Episode 11
3 # ("Muse Understands Music"). Re-run to regenerate; never hand-edit the
4 # repo directory itself.
5 set -euo pipefail
6
7 HERE="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8 REPO="$HERE/midi-episode11"
9
10 rm -rf "$REPO"
11 mkdir -p "$REPO"
12 cd "$REPO"
13
14 export MUSE_ENABLE_MIDI=1
15
16 python3 - <<'PY'
17 import mido
18 from pathlib import Path
19
20 TPB = 480
21
22 def build(path, bpm, notes):
23 mid = mido.MidiFile(type=0, ticks_per_beat=TPB)
24 track = mido.MidiTrack()
25 mid.tracks.append(track)
26 events = [(0, mido.MetaMessage("set_tempo", tempo=mido.bpm2tempo(bpm), time=0))]
27 for start, pitch, velocity, duration in notes:
28 events.append((start, mido.Message("note_on", channel=0, note=pitch, velocity=velocity, time=0)))
29 events.append((start + duration, mido.Message("note_off", channel=0, note=pitch, velocity=0, time=0)))
30 order = {"set_tempo": 0, "note_off": 1, "note_on": 2}
31 events.sort(key=lambda item: (item[0], order.get(item[1].type, 9)))
32 previous = 0
33 for tick, msg in events:
34 track.append(msg.copy(time=tick - previous))
35 previous = tick
36 track.append(mido.MetaMessage("end_of_track", time=0))
37 mid.save(path)
38
39 # C - E - G - C', quarter notes at 120bpm
40 BASE = [
41 (0, 60, 80, 480),
42 (480, 64, 80, 480),
43 (960, 67, 80, 480),
44 (1440, 72, 80, 480),
45 ]
46 build(Path("phrase.mid"), 120, BASE)
47 PY
48
49 muse init --domain midi --json | python3 -m json.tool
50
51 # NOTE: non-code domains have no staging concept — files are tracked the
52 # moment they're on disk (muse status already shows "added": ["phrase.mid"]
53 # before any `add` step). `muse code add` is code-domain only and errors here.
54 muse commit -m "Add four-note phrase (C-E-G-C')" \
55 --agent-id claude-code --model-id claude-sonnet-5 --sign
56
57 echo "--- domain-info (midi vs code contrast) ---"
58 muse domain-info --json | python3 -m json.tool
59
60 # Branch 1: change the third's pitch (E -> F)
61 muse checkout -b feat/raise-third --intent "raise the third from E to F" --resumable
62 python3 - <<'PY'
63 import mido
64 mid = mido.MidiFile("phrase.mid")
65 for track in mid.tracks:
66 for msg in track:
67 if msg.type in ("note_on", "note_off") and msg.note == 64:
68 msg.note = 65
69 mid.save("phrase.mid")
70 PY
71 muse commit -m "Raise the third from E to F" \
72 --agent-id claude-code --model-id claude-sonnet-5 --sign
73
74 # Back to main, branch 2: raise velocity on every note
75 muse switch main
76 muse checkout -b feat/louder-melody --intent "raise velocity on the melody notes" --resumable
77 python3 - <<'PY'
78 import mido
79 mid = mido.MidiFile("phrase.mid")
80 for track in mid.tracks:
81 for msg in track:
82 if msg.type == "note_on":
83 msg.velocity = 110
84 mid.save("phrase.mid")
85 PY
86 muse commit -m "Increase melody velocity to 110" \
87 --agent-id claude-code --model-id claude-sonnet-5 --sign
88
89 # Fast-forward merge #1 (no conflict — only one side touched the file)
90 muse switch main
91 muse merge feat/raise-third
92
93 # Merge #2 — genuine conflict: same note, different attribute changed on
94 # each side (pitch on one branch, velocity on the other)
95 muse merge feat/louder-melody --json | python3 -m json.tool || true
96 echo "--- conflicts ---"
97 muse conflicts --json | python3 -m json.tool
98
99 # Manual resolution: incorporate BOTH sides' intent (F pitch + velocity 110)
100 python3 - <<'PY'
101 import mido
102 mid = mido.MidiFile("phrase.mid")
103 for track in mid.tracks:
104 for msg in track:
105 if msg.type == "note_on":
106 msg.velocity = 110
107 mid.save("phrase.mid")
108 PY
109 muse resolve phrase.mid
110 muse commit -m "Merge feat/louder-melody: F pitch + velocity 110 on all notes" \
111 --agent-id claude-code --model-id claude-sonnet-5 --sign
112
113 muse branch -d feat/raise-third
114 muse branch -d feat/louder-melody
115
116 echo "--- final log ---"
117 muse log --json | python3 -m json.tool
118
119 echo "Demo repo built at $REPO"
File History 1 commit
sha256:41074b7f9893918b26fe292dddb55c83bec08ae17aeb2acfd73d9fcc00587585 Add Episode 11 script (Muse Understands Music) and MIDI dem… Sonnet 5 patch 11 hours ago