diff --git a/src/unified-dashboard.ts b/src/unified-dashboard.ts index d45685d..8f9b3cd 100644 --- a/src/unified-dashboard.ts +++ b/src/unified-dashboard.ts @@ -808,6 +808,10 @@ export async function startUnifiedDashboard( const isRenderer = opts.serviceAgentType === 'claude-code'; const statusJid = `dc:${opts.statusChannelId}`; + // The first render after a (re)start should show the status message + // immediately: edit the stored message if possible, but if that edit fails, + // repost right away instead of waiting through the steady-state retry cycle. + let firstStatusRender = true; if (isRenderer) { statusMessageId = readDashboardStatusMessageId(opts.statusChannelId); } @@ -869,9 +873,12 @@ export async function startUnifiedDashboard( // times with a delay first; only give up (and repost) if all fail. const editId = statusMessageId; const editMessage = channel.editMessage; + // First render after start: 0 retries → repost immediately if the edit + // fails. Steady state: retry twice at 15s before reposting. + const maxRetries = firstStatusRender ? 0 : STATUS_EDIT_MAX_RETRIES; const edited = await editStatusMessageWithRetry({ editOnce: () => editMessage(statusJid, editId, content), - maxRetries: STATUS_EDIT_MAX_RETRIES, + maxRetries, retryDelayMs: STATUS_EDIT_RETRY_DELAY_MS, onAttemptFailed: (attempt, willRetry, err) => logger.warn( @@ -879,7 +886,7 @@ export async function startUnifiedDashboard( err, messageId: editId, attempt, - maxAttempts: STATUS_EDIT_MAX_RETRIES + 1, + maxAttempts: maxRetries + 1, willRetry, }, willRetry @@ -901,6 +908,9 @@ export async function startUnifiedDashboard( writeDashboardStatusMessageId(opts.statusChannelId, id); } } + // A render (edit or repost) happened this tick; subsequent ticks use the + // steady-state retry policy. + firstStatusRender = false; if (statusMessageId) { await cleanupDashboardDuplicateMessages(opts, statusMessageId); }