{#each approvals as approval (approval.executionId)} {@const p = phase.get(approval.executionId)} {@const e = exec.get(approval.executionId)} {#if p === 'completed'}
Completed{e?.duration_ms ? ` in ${Math.round(e.duration_ms / 1000)}s` : ''} on {approval.target}.
{#if outputText(e)}
{outputText(e)}
{/if}
{:else if p === 'failed'}
Execution failed
{errorText(e)}
{:else if p === 'denied'}
Denied.
{:else if p === 'running' || p === 'deciding'} {@const secs = elapsedSeconds(e)}
{#if p === 'deciding'} Submitting approval… {:else} Running on {approval.target}{secs !== null ? ` — ${fmtDuration(secs)} elapsed` : '…'} {/if}
{#if p === 'running' && approval.command} {approval.command} {/if} {#if p === 'running'} Execution {approval.executionId.slice(0, 8)} — long installs can take several minutes; this will resolve on its own (capped at 10 min) or you can check the Operations page for live output. {/if}
{:else if p === 'stalled'}
No update from the server in over 14 minutes.
The command itself is capped at 10 minutes server-side, so this is unusual — the API may be unreachable. Execution {approval.executionId}. Check the Operations page directly.
{:else if approval.destructive} {@const affected = blastRadius.get(approval.executionId)}
DESTRUCTIVE — {approval.action} on {approval.target}. Type "I confirm" in chat, or use the button.
{#if approval.command} {approval.command} {/if} {#if affected}
Affects {affected.length} downstream: {affected.join(', ')}
{/if}
{:else} {@const affected = blastRadius.get(approval.executionId)}
{approval.action} on {approval.target} requires approval
{#if affected}
Affects {affected.length} downstream: {affected.join(', ')}
{/if}
{/if} {/each}