Unify runtime status shown across UIs#13376
Conversation
|
E2E Tests 🚀 |
seeM
left a comment
There was a problem hiding this comment.
Notebook and console runtime status icons look correct but Quarto restart has an additional "Starting" state with a disconnected status.
Screen.Recording.2026-05-07.at.15.59.57.mov
| // update the kernel status to the runtime session state | ||
| this.kernelStatus.set(KernelStatus.Starting, undefined); | ||
| } | ||
| if (newKernel && oldKernel) { |
There was a problem hiding this comment.
There is a regression here. Previously, switching interpreters would show immediate UI feedback via the spinner. Now there's a delay.
Before:
Screen.Recording.2026-05-07.at.16.10.02.mov
After:
Screen.Recording.2026-05-07.at.16.09.35.mov
There was a problem hiding this comment.
ah, thanks for catching!
| return <div data-testid={'state'}>{state ?? 'none'}</div>; | ||
| }; | ||
|
|
||
| describe('useSessionRuntimeState', () => { |
There was a problem hiding this comment.
Nice 👌 I'm curious if you used the Claude skill here, and if so how much you had to intervene manually?
There was a problem hiding this comment.
yep, I used the skill here for all of the tests. It did a pretty decent job with the simpler tsx files. I did have to go and remove some tests that were testing the wrong thing or didn't make a lot of sense to me. It wasn't that much work to fix it though since most of the time its just removing tests.
| it('shows active icon during Restarting (regression: previously showed stale state via PositronConsoleState)', () => { | ||
| const { session, emitter } = makeSession(RuntimeState.Idle); | ||
| rtl.render(<ConsoleSessionStatusIcon positronConsoleInstance={makeInstance(session)} />); | ||
| act(() => emitter.fire(RuntimeState.Restarting)); | ||
| expect(screen.getByTestId('runtime-status-active')).toBeInTheDocument(); | ||
| }); |
There was a problem hiding this comment.
How about writing the test with the preferred behavior and using it.fails?
| const quartoStateToRuntimeStatus: Partial<Record<QuartoKernelState, RuntimeStatus>> = { | ||
| [QuartoKernelState.None]: RuntimeStatus.Disconnected, | ||
| [QuartoKernelState.Starting]: RuntimeStatus.Active, | ||
| [QuartoKernelState.Ready]: RuntimeStatus.Idle, | ||
| [QuartoKernelState.Busy]: RuntimeStatus.Active, | ||
| [QuartoKernelState.Error]: RuntimeStatus.Disconnected, | ||
| [QuartoKernelState.ShuttingDown]: RuntimeStatus.Active, | ||
| }; |
There was a problem hiding this comment.
Nit: I think this would give a more accurate and helpful type - have not tested
| const quartoStateToRuntimeStatus: Partial<Record<QuartoKernelState, RuntimeStatus>> = { | |
| [QuartoKernelState.None]: RuntimeStatus.Disconnected, | |
| [QuartoKernelState.Starting]: RuntimeStatus.Active, | |
| [QuartoKernelState.Ready]: RuntimeStatus.Idle, | |
| [QuartoKernelState.Busy]: RuntimeStatus.Active, | |
| [QuartoKernelState.Error]: RuntimeStatus.Disconnected, | |
| [QuartoKernelState.ShuttingDown]: RuntimeStatus.Active, | |
| }; | |
| const quartoStateToRuntimeStatus = { | |
| [QuartoKernelState.None]: RuntimeStatus.Disconnected, | |
| [QuartoKernelState.Error]: RuntimeStatus.Disconnected, | |
| } satisfies Partial<Record<QuartoKernelState, RuntimeStatus>>; |
The `runOnChange(this.kernel, ...)` block only set Switching when both oldKernel and newKernel were set, so first-time selection left kernelStatus at Unselected and the badge briefly rendered Disconnected with the kernel's runtime name. Make the badge show Active as soon as a kernel is selected, rather than waiting for the session to attach. Replace `useNotebookRuntimeSession` with a `runtimeSession` observable on IPositronNotebookInstance. The hook duplicated session resolution the model already does in `_maybeAttachSession` (initial lookup + onWillStartSession + onDidEndSession). Mirrors the existing `kernel` observable pattern.
Disambiguates the enum name, and replaces the `undefined` sentinel that meant "session is attached" with an explicit `Connected` value so the type is honest. `kernelStatus` is now `IObservable<NotebookKernelStatus>` without the `| undefined` widening.
…tching When a notebook foreground session is deleted during a kernel switch, foregroundSessionDisplayInfo briefly surfaces the deleted session's Exited state, which makes the interpreter picker flash Disconnected before the new session takes foreground. The notebook badge avoids this because it reads session state directly. Document the desired picker behavior with `it.fails` so a future fix can deal with this
The badge prioritized live runtime state over kernelStatus, so when the user picked a new kernel `kernelStatus = Switching` was set but the old session was still Idle and won the display. The spinner only kicked in once the old session started exiting -- a perceptible delay vs. clicking. Add a Switching override at the top of the ladder so user intent shows immediately, regardless of the old session's now-stale state. _maybeAttachSession clears Switching when the new session attaches, after which live runtime state takes over.
seeM
left a comment
There was a problem hiding this comment.
Looks great! I noticed another issue but it's in release builds too so isn't a regression, might already be on your radar. Starting an exited notebook session behaves differently in the notebook kernel status and top interpreter picker
Screen.Recording.2026-05-11.at.13.05.20.mov
Ya, I noticed the same thing and it is on my radar. This has the same issue as switching kernels and the interpreter picker being out of sync with that. |
Based off feedback from @seeM in #13045
Three places show runtime status — the console tab icon, the notebook session badge, and the Quarto session badge. Each had its own mapping chain to get from a runtime session's state to a display icon:
PositronConsoleState->RuntimeStatusRuntimeState->KernelStatus->RuntimeStatusRuntimeState->QuartoKernelState->RuntimeStatusThese mappings can easily drift to show different states and for a notebook user this can be odd/confusing since we show the runtime status icon in multiple places.
One visible fix from this change is in the console which previously would show the wrong state during restart compared to the interpreter picker.
NOTE: the interpreter picker can become out of sync with the notebook kernel badge and notebook console session when a user chooses the "Change Kernel" option. This is also the case for Quarto as well. I didn't attempt to resolve that here and this may be worth tackling instead when we try and unify the quarto/notebook UI.
I think that fix gets us one step closer to unifying the runtime statuses.
Screenshots
BEFORE - notebook restart
before.mov
AFTER - notebook restart
Screen.Recording.2026-05-05.at.6.40.29.PM.mov
BEFORE - console restart
before.console.mov
AFTER - console restart
TBD
Release Notes
New Features
Bug Fixes
Validation Steps
@:console @:positron-notebooks @:quarto @:sessions