Skip to content

Conversation

@juliasilge
Copy link
Contributor

@juliasilge juliasilge commented Nov 18, 2025

Addresses #7747

@:apps
@:viewer

This PR extends the UI comm for previewing a URL to optionally keep track of the "source" of where that URL may be coming from, for example, the terminal that may be running that process. If we have such a process ID, then we show a new button the Viewer pane UI that can be used to stop the process. It's the same button that we use on the console to stop running code there.

Screenshot 2025-11-21 at 4 14 36 PM

I tried a few hacky things that might allow us to show such a button without truly tracking the source, but it did NOT result in good behavior. We can do PRs to the Shiny extension and the Quarto extension so they use this new API and can also show buttons that will stop their processes as well.

We also can extend this to process that come from the language runtimes, but I did not do that here. Do people want two buttons in such a case? The button that would be running in the console and the button in the viewer? A little weird maybe? I say let's wait and see what folks think.

Release Notes

New Features

  • Added new button to interrupt a running app (such as Streamlit or FastAPI) from the Viewer pane

Bug Fixes

  • N/A

QA Notes

If you have an app supported by the builtin positron-run-app extension, when you press the "play" button, you should see a new button pop up on the Viewer pane.

  • If you click the button, it should stop the app from running (similar to if you stopped it from the terminal)
  • Having another terminal focused or active should not interfere with the button behavior; the button should act like it is connected exactly to the process running the app

Be aware that we do not have clearing set up in the Viewer pane, i.e. #6827, #9323, #5344. Adding the button here might make that feel more urgent.

@github-actions
Copy link

github-actions bot commented Nov 18, 2025

E2E Tests 🚀
This PR will run tests tagged with: @:critical @:apps @:viewer

readme  valid tags

Comment on lines +674 to +675
"runtime",
"terminal"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we think of any other source we want to track, other than something running in the terminal and something running in the console?

}

.preview-action-bar .action-bar-button-icon.interrupt::before {
color: var(--vscode-errorForeground);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as the button in the console

// Send Ctrl+C (SIGINT) to the terminal
sourceTerminal.sendText('\x03', false);

// Poll after 3 seconds to check if the process actually stopped
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you use this polling to dismiss the button, it feels quite laggy unfortunately. I think we need to dismiss the button immediately but set up the polling to show an error, in case something goes wrong.

export interface IRuntimeClientEvent {
name: UiFrontendEvent;
data: any;
data: unknown;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is from the 106 merge, with a new (?) no-explicit-any eslint rule.

Comment on lines +476 to +478
// --- Start Positron ---
'src/positron-dts/**',
// --- End Positron ---
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 106 merge added a new (I think) no-explict-any eslint rule, but I don't think we should apply it to our API file, similar to how the VS Code API file is treated.

@juliasilge juliasilge marked this pull request as ready for review November 21, 2025 23:50
@juliasilge
Copy link
Contributor Author

I'm having a fair amount of trouble with the tests on this branch, but it looks unrelated to me.

@midleman can you take a look and also review the test I added in 4d50df8?

@juliasilge juliasilge changed the title WIP: Add a button to stop a terminal process from the Viewer pane Add a button to stop a terminal process from the Viewer pane Nov 21, 2025
@midleman
Copy link
Contributor

I'm having a fair amount of trouble with the tests on this branch, but it looks unrelated to me.

@midleman can you take a look and also review the test I added in 4d50df8?

The test failures seem to be related to very slow app start up... 🤔 I noticed some new useEffects hooks in the code. Code that possibly be related and/or running on startup? I'll take a closer look at your new test on Monday! Figuring out the app lag is higher priority. 🫠

Also, I'd update your branch with main. I think Jon fixed the shiny app test failure. Let's see how the run goes after that!

jmcphers
jmcphers previously approved these changes Nov 22, 2025
Copy link
Collaborator

@jmcphers jmcphers left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nicely done, this will be very helpful! I was worried that the interrupt wouldn't work on Windows, but it actually works great. I do wonder if we should clear the Viewer pane after successfully interrupting as otherwise the app seems to get a little confused about what just happened.
image

@juliasilge
Copy link
Contributor Author

juliasilge commented Nov 22, 2025

I did merge from main. I still see the same failures, which are the same as on #10731:

  • e2e tests failing with:

Fixture "app" timeout of 60000ms exceeded during setup.

  • integration tests failing with:

Uncaught Error: spawn /home/runner/work/positron/positron/extensions/positron-python/python-env-tools/bin/pet ENOENT

So seems like those failures are not related to my changes here.

@juliasilge
Copy link
Contributor Author

I do wonder if we should clear the Viewer pane after successfully interrupting as otherwise the app seems to get a little confused about what just happened.

Yeah, that worked out pretty well in 3c36ebb, adding the same thing that would happen if you clicked the button that says "Clear the current URL". I do want to highlight that there is a bit of messiness right now around how many previews there can be, but if you are using the preview pane (where this button is), every time a new URL or HTML preview is opened, it clears all previous previews first anyway. I think this is a good option for now!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test looks great! One small suggestion, instead of creating a separate test, I would suggest adding the interrupt-button checks to the end of the existing streamlit app test. That way we get the coverage without the extra setup/teardown cost.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

HA, I tried to do this and then remember why I had it in a separate test from before! 😆

  • The first test runs the Streamlit app in the viewer, then pops it to the editor to run there
  • My new test runs the Streamlit app in the viewer, then stops it with the new button

We do in fact need two separate tests here.

@midleman
Copy link
Contributor

I did merge from main. I still see the same failures, which are the same as on #10731:

  • e2e tests failing with:

Fixture "app" timeout of 60000ms exceeded during setup.

  • integration tests failing with:

Uncaught Error: spawn /home/runner/work/positron/positron/extensions/positron-python/python-env-tools/bin/pet ENOENT

So seems like those failures are not related to my changes here.

Yep, you are right, these are issues in main at the moment. 😭

@juliasilge
Copy link
Contributor Author

juliasilge commented Nov 24, 2025

All the tests (including my new one) in test/e2e/tests/apps/python-apps.test.ts are passing, along with all the @:apps and @:viewer tests ✅

The failures I see here are the same as on main:

  • e2e tests failing with:

Fixture "app" timeout of 60000ms exceeded during setup.

  • integration tests failing with:

Uncaught Error: spawn /home/runner/work/positron/positron/extensions/positron-python/python-env-tools/bin/pet ENOENT

I'm going to go ahead and merge so we can keep moving forward.

@juliasilge juliasilge merged commit ee9f160 into main Nov 24, 2025
30 of 32 checks passed
@juliasilge juliasilge deleted the feature/viewer-pane-stop-button branch November 24, 2025 19:49
@github-actions github-actions bot locked and limited conversation to collaborators Nov 24, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants