Years ago, I wrote something similar but simpler and non-programmable using Pith (JS with Python-like syntax).
https://gabrielsroka.github.io/webpages/pith.html
cancel = false
editor.style.display = 'none'
debug.hide()
btn = button('Stop', 'cancel=true id=stopBtn')
bar.html(btn)
beep = new Audio('beep.mp3')
lock = await navigator.wakeLock.request('screen')
stopBtn.style.fontSize = runProgram.style.fontSize = results.style.fontSize = '72px'
wus = 'roll shoulders,arm circles,arm hugs,knee raises,rotate torso,rotate hips'
wus = wus.split(',')
sets = 'march in place,squat,push up,standing bicycle crunch,stand and box,split squat,push up,plank,jumping jacks,wall sit,push up,standing side crunch'
sets = sets.split(',')
cools = 'walk,hands up,hands forward,hands back,right leg,left leg,right hams,left hams,balance'
cools = cools.split(',')
await countdown('check volume.', 5, true)
for wu in wus
await countdown(wu, 12)
await countdown('first up ' + sets[0])
for set in range(sets.length)
msg = (set + 1) + '. ' + sets[set]
await countdown(msg, 30, true)
if set < sets.length - 1
await countdown('next up: ' + sets[set + 1])
for cool in cools
await countdown(cool, 15)
results.html('done')
lock.release()
editor.style.display = ''
async def countdown(msg, secs=5, play)
for s in range(secs)
results.html(msg + '<br>' + (secs - s))
if play && secs - s <= 3
beep.play()
if cancel
break
await sleep(1000)