Files
hemx/examples/workout/templates/workout.heml
T
slhx agent c146e9b932 feat(workout): recover common session failures
Make the workout exemplar recover cleanly from invalid edits, accidental double-advance, replay parse failures, and denied or timed-out host export results while keeping local events as truth.

req: examples/001

req: local/001

req: local/003

req: local/004

req: host/002

req: host/005
2026-06-11 23:25:21 +02:00

59 lines
3.1 KiB
Plaintext

<main data-hemx-root="workout" class="workout-app">
<section class="command-slate" aria-labelledby="next-action-heading">
<p class="eyebrow">Now-first Workout Copilot</p>
<p class="progress-pill" data-hemx-slot="progress">{+ self.progress +}</p>
<h1 id="next-action-heading" data-hemx-slot="next_action">{+ self.next_action +}</h1>
<p class="session-status" data-hemx-slot="status">{+ self.status +}</p>
</section>
<section class="action-rail" aria-label="Current workout action">
<button class="primary-action" type="button" data-hemx-handle="complete_set">
<span data-hemx-slot="primary_action">{+ self.primary_action +}</span>
</button>
<p class="recovery-status" data-hemx-slot="recovery_status">{+ self.recovery_status +}</p>
<div class="secondary-actions">
<button class="quiet-action" type="button" data-hemx-handle="undo_last_action">Undo last action</button>
<button class="quiet-action" type="button" data-hemx-handle="skip_exercise">Skip exercise</button>
</div>
<form class="micro-form" data-hemx-handle="change_weight" method="post">
<label>Adjust weight <input name="kg" value="52.5" inputmode="decimal" aria-label="Weight in kilograms"></label>
<button type="submit">Save</button>
</form>
<form class="voice-strip" data-hemx-handle="record_note" method="post">
<label>Session note <input name="text" value="left shoulder felt tight"></label>
<button type="submit">Record</button>
</form>
</section>
<section class="finish-card" aria-labelledby="finish-heading">
<div>
<p class="eyebrow">Finish & recover</p>
<h2 id="finish-heading">Your session is a replayable local log.</h2>
</div>
<p data-hemx-slot="host_status">{+ self.host_status +}</p>
<button class="share-action" type="button" data-hemx-handle="export_log">Share export</button>
<details class="host-proof">
<summary>Host proof panel</summary>
<p>Development-only host results return through app code before UI effects.</p>
<div class="host-actions">
<button type="button" data-hemx-handle="record_share_result">Mark share completed</button>
<button type="button" data-hemx-handle="record_share_denied">Simulate share denied</button>
<button type="button" data-hemx-handle="record_host_timeout">Simulate host timeout</button>
<button type="button" data-hemx-handle="replay_broken_export">Simulate replay failure</button>
<button type="button" data-hemx-handle="request_native_haptic">Request native haptic</button>
<button type="button" data-hemx-handle="record_native_haptic_ack">Mark haptic acknowledged</button>
</div>
</details>
</section>
<section class="ledger" aria-labelledby="event-log-heading">
<div class="section-heading">
<h2 id="event-log-heading">Private event log</h2>
<button type="button" data-hemx-handle="replay_export">Replay export</button>
</div>
<pre data-hemx-slot="event_log">{+ self.event_log +}</pre>
<h3>Export payload</h3>
<pre data-hemx-slot="export_payload">{+ self.export_payload +}</pre>
</section>
</main>