* fix(terminal): correct error/cancel block status in logs panel
Three bugs in the workflow editor's terminal/logs panel where block
status diverged from the engine's truth on error paths:
1. **Errored block shown as "canceled"** — when the SSE 'add' mode
produced a duplicate entry on block error and `cancelRunningEntries`
then swept the original placeholder.
2. **Upstream blocks stuck on "Running"** — terminal events arrived
before the engine's last block events under reconnect/timeout, so
the live panel never received the per-block terminal state.
3. **Phantom "Run Error" pseudo-row** — the failing block rendered as
"canceled" while a synthetic row carried the real error text.
Fixes:
- **Fix B** (`addConsoleErrorEntry`): when a running placeholder exists
for `(blockId, executionId)`, route through `updateConsoleErrorEntry`
instead of creating a second entry. Aligns 'add' mode with the
existing 'update' mode behavior.
- **Fix C** (`reconcileFinalBlockLogs`): terminal SSE events now carry
`finalBlockLogs` (server-authoritative snapshot). On
execution:error / execution:cancelled, reconcile any still-running
entries with their server-side terminal state. Recovers correctness
on network drop, server timeout/abort, and reconnect-resume paths
where individual block:* events may not have reached the client.
- **Fix D** (`addExecutionErrorConsoleEntry`): cross-check
`useTerminalConsoleStore` for entries with `error` set scoped to the
executionId before emitting the synthetic "Run Error" row. Suppresses
the phantom row when the failing block already carries the message.
- **Signature refactor**: `handleExecutionErrorConsole` /
`handleExecutionCancelledConsole` now take a typed
`ExecutionConsoleDeps` object instead of stacking positional deps —
matches the existing `createBlockEventHandlers(config, deps)`
precedent in the same file.
Tests:
- 12 tests in `workflow-execution-utils.test.ts` covering Fix B/C/D and
the deps-object signature refactor.
- Centralized terminal-console store mock in `@sim/testing` so future
tests can stub the store without per-file boilerplate.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(terminal): wire copilot cancellation to finalBlockLogs reconciliation
Address Greptile review:
- `executeWorkflowWithFullLogging`'s `onExecutionCancelled` was `() => {}`
and silently dropped the `finalBlockLogs` payload, so Bug 2's "upstream
blocks stuck on Running" fix did not fire on copilot-initiated
cancellations. Wire it through `handleExecutionCancelledConsole` to
match the SSE-route `onExecutionCancelled` path.
- Test for the `blockType !== 'error'` filter used a different
`executionId` than the seeded entry, so the executionId scope rejected
the entry before the blockType predicate ran. Align executionIds so
the test actually exercises the filter.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(terminal): pass durationMs in reconnect cancellation handler
Reconnect-resume `onExecutionCancelled` was forwarding `finalBlockLogs`
but not `data?.duration`, so the "Run Cancelled" entry rendered with a
0ms duration. Match the other two `handleExecutionCancelledConsole`
callsites.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>