## Summary of the Pull Request
Fixes a couple of minor issues in the settings schema which can result
in erroneous settings validation failures.
## References and Relevant Issues
None
## Detailed Description of the Pull Request / Additional comments
- `answerbackMessage`
Permit `null` type (corresponds to the default value).
- `compatibility.input.forceVT`
Add missing setting (previously was `experimental.input.forceVT`).
- `rendering.graphicsAPI`
Add missing `automatic` enumeration value.
- Mark several settings as deprecated using the same format and direct
the user to the updated settings to use.
## Validation Steps Performed
Tested updated schema against configuration with above settings present.
## PR Checklist
- [X] Schema updated (if necessary)
---------
Co-authored-by: Carlos Zamora <carlos.zamora@microsoft.com>
(cherry picked from commit fc2d1078971348a3a3cf3d1eb666e97e99e058c0)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgirMyU
Service-Version: 1.24
It fails inside app containers (!) such as the one used by LocalTests.
(cherry picked from commit 91c9a14a710af7048d7d8c3d74b1d2bc2744bc97)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgirMr8
Service-Version: 1.24
This commit also ups the number of render failures that are permissible
to 6 (one try plus 5 retries), and moves us to use an exponential
backoff rather than a simple geometric one.
It also suppresses the dialog box in case of present failures for Stable
users. I feel like the warning dialog should be used for something that
the user can actually do something about...
Closes#15601Closes#18198
(cherry picked from commit 45c5370271c02247a2a5bc31e8514006506f2222)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgiXh2E
Service-Version: 1.24
When run from SYSTEM account TSF seems to be unavailable. The only
missing step to handle that is check during initialization.
Not sure if fail after partial success in `Implementation::Initialize`
should also be gracefully handled.
Closes#19634
(cherry picked from commit 8bb831f628d3b8ddaf614c0a4d6f9b0b0533b5f0)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgiXm14
Service-Version: 1.24
Fragments are not allowed to declare web-source icons; this is equally
true for UNC paths in the local network (or WebDAV paths!)
(cherry picked from commit 7a7cdec91fd48c09294f19f39c5300dd0c7c29d5)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgiGQDM
Service-Version: 1.24
Support for DECRQCRA Request Checksum of Rectangular Area was added in
#14989, but left disabled at build time because it could be considered a
security risk.
In #17895, we unconditionally added a toggle for it to Terminal's
settings UI and settings schema (`compatibility.allowDECRQCRA`). For
users on Stable and Preview, it didn't actually enable anything. Whoops.
Since we have a way to turn it off (and in so doing, mitigate the risk)
in Terminal, it's high time for us to remove the feature gating.
Conhost doesn't support turning it off for now and so conhost can still
have it compiled out, as a treat.
(cherry picked from commit 3e29d2a316c5f2380ffc2b97939e58c9859fadc8)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgiA9JY
Service-Version: 1.24
This fixes the sign extension from 16 to 32 bit by casting
from the unsigned to the signed type first.
Closes#19391Closes#19484
(cherry picked from commit fb75fb56c0e83e6bb5a4f40b8b171b0a4ab51f8b)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzghttY4
Service-Version: 1.24
As explained in detail in the diff.
Closes#19562
(cherry picked from commit 1ca0c76bc74012fdd1ff6211b5c8f389a4efd9b4)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzghp8js
Service-Version: 1.24
## Summary of the Pull Request
This PR fixes a bug where programmatic scrolling would get stuck. The
fix makes the "snap-on-input" feature conditional, activating it only
for modern applications that use Virtual Terminal (VT) processing. This
restores correct scrolling behavior for legacy applications without
removing the feature for new ones.
## References and Relevant Issues
Fixes#19390: OpenConsole: Cursor visibility prevents programmatic
scrolling
## Detailed Description of the Pull Request / Additional comments
The "snap-on-input" feature introduced in a previous PR caused an
unintended side effect for older console programs that use the
SetConsoleWindowInfo API to manage their own viewport. When such a
program tried to scroll using a key press, the snap feature would
immediately pull the view back to the cursor's position, causing the
screen to flicker and get stuck.
This fix makes the snap-on-input feature smarter by checking the
application's mode first.
## Validation Steps Performed
Compiled the minimal C++ reproduction case from issue #19390.
Ran the test executable inside the newly built OpenConsole.exe.
Confirmed that scrolling with the Up/Down arrow keys now works
correctly, even with a visible cursor. The view no longer flickers or
gets stuck when the cursor moves outside the viewport.
Closes#19390
(cherry picked from commit c28610d016852aef5b8f8e0c0b193f721832c280)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgfZNLg
Service-Version: 1.24
It said the equivalent of "Nickname" rather than "aliased".
Co-authored-by: Console Service Bot <consvc@microsoft.com>
(cherry picked from commit 965a121a3814fe8addc8843bd20c834de4da6110)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzghDyBA
Service-Version: 1.24
Whoops. Closes#18652
<DHowett> I chatted with Leonard to figure out why I kept
misunderstanding this PR. The key is that **this function should not
always return an existing window.** It's supposed to find an existing
window on the current virtual desktop, not literally any window
anywhere.
(cherry picked from commit 5ae95d7df0ee3050ad36b98cd8f3f8d55005f0d2)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgf7tqY
Service-Version: 1.24
OCWildcardResource requires the inclusion of a magic MSBuild target that
we wrote. We forgot to include it here. Oops.
Closes#19444
(cherry picked from commit 0e3d136dad1263e36b136b66adbc7e7d4789d56e)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgf7udM
Service-Version: 1.24
## Summary of the Pull Request
Update the WinGet CNF package search to match that of the updated
PowerShell WinGet CNF module. Now, we'll only search for matching
commands instead of by name and moniker.
## References and Relevant Issues
https://github.com/microsoft/winget-command-not-found/pull/29
## Validation Steps Performed
✅ In CMD, type "vim" and vim packages are suggested
(cherry picked from commit 819987c90e17dbf6301c777d2ec553a7d115db75)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgfuACY
Service-Version: 1.24
## Summary of the Pull Request
Turns out that the `"TabViewItemHeaderBackground"` resource should be
set to the _selected_ color instead of the _deselected_ color.
In 1.22, (pre-#18109) we actually didn't set this resource. But we do
actually need it for high contrast mode! (verified)
## Validation Steps Performed
✅ High contrast mode looks right
✅ "Snazzy" theme from bug report looks right
## PR Checklist
Closes#19343
(cherry picked from commit b62cad640b6871be1daf8b3e80f8db848ae0800e)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgfrGvI
Service-Version: 1.24
Apparently, `GetModuleFileNameW` returns exactly the path (or prefix, in
case of a DLL) passed to `CreateProcess` casing and all. Since we were
using it to generate the uniquing hash for Portable and Unpackaged
instances, this meant that `C:\Terminal\wt` and `C:\TeRmInAl\wt` were
considered different instances. Whoops.
Using `QueryFullProcessImageNameW` instead results in canonicalization.
Maybe the kernel does it. I don't know. What I do know is that it works
more correctly.
(`Query...` goes through the kernel, while `GetModule...` goes through
the loader. Interesting!)
Closes#19253
(cherry picked from commit 9d7ea77cc8ecbfcf213f6a38fbeb611c71040a34)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgfkTuo
Service-Version: 1.24
## Summary of the Pull Request
When we introduced action IDs, we separated "commands" from
"keybindings", and introduced fixup logic to rewrite the legacy-style
command blocks into the new version. However we don't do any ID logic
for nested and iterable commands, so make sure we don't inform the
loader for fixups in those cases.
## Validation Steps Performed
We no longer repeatedly attempt to fixup the settings file when we see a
`"keys"` entry in a nested/iterable command block
## PR Checklist
- [x] Closes#18736
(cherry picked from commit 04676bd31a598ccede4517367cbb070c38964f8e)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgfjzjQ
Service-Version: 1.24
If the progress state hasn't been set for more than 200ms, we shouldn't
even bother flickering the old state.
This prevents applications from making the tab (and the taskbar icon)
flicker.
We were reviewing #19394 and decided that the _original_ behavior before
Leonard's throttling fix was somewhat unfortunate as well. An
application that sets an indeterminate state for 10ms and then clears it
shouldn't be able to make any part of the application flicker, fast _or_
slow.
Removing the leading fire time from the throttled function ensures that
it will only fire once every 200ms, and only with the state most
recently set. It will not debounce (so setting the progress every 150ms
will not prevent it from updating.)
Closes#19394
(cherry picked from commit 998ab586e1cccf11a965cab9dc2dcdb7da8eaa6c)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgfZOsU PVTI_lADOAF3p4s4BBcTlzgfb1NE
Service-Version: 1.24
The previous fix in #19296 moved the _destruction_ of AppHost into the
tail end after we manipulate the `_windows` vector; however, it kept the
part which calls into XAML (`Close`) before the `erase`. I suspect that
we still had some reentrancy issues, where we cached an iterator before
the list was modified by another window close event.
That is:
```mermaid
sequenceDiagram
Emperor->>Emperor: Close Window
Emperor->>+AppHost: Close (a)
AppHost->>XAML: Close
XAML-->>Emperor: pump loop
Emperor->>Emperor: Close Window
Emperor->>+AppHost: Close (b)
AppHost->>XAML: Close
XAML-->>Emperor: pump loop
AppHost->>-Emperor: Closed
Emperor->>Emperor: erase(b)
AppHost->>-Emperor: Closed
Emperor->>Emperor: erase(a)
```
Moving the `Close()` to after the `erase` ensures that there are no
cached iterators that survive beyond XAML pumping the message loop.
Fixes 8d41ace3
(cherry picked from commit 5976de16000b3e49f3f010c42b23f6a42f6a6405)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgfScpM
Service-Version: 1.24
This will allow us to publish vpacks without making the build fail
waiting for us to *merge* those vpacks into Windows. It also gives us
better control over when and where the vpack update gets merged.
(cherry picked from commit 6b428577b95835b95479306d88db8bc74232bea7)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgfLAks
Service-Version: 1.24
Some of the other settings fixups require there to be a valid
NewTabMenu, rather than just a temporary object. Since the resolving all
the menu entries after loading already forces the user to have a
`newTabMenu`, let's just codify it as a real fixup.
I've moved the SSH folder fixup after the settings fixup because it
relies on there being a NTM.
I decided not to make this fixup write back to the user's settings.
There are a couple reasons for this, all of which are flimsy.
- There are a number of tests that test fixup behavior, especially those
around actions, which would need to be updated for this new mandatory
key. I did not think it proper to add `newTabMenu` to ten unrelated
tests that only contain actions (for example.)
- We actually don't currently have mandatory keys. But this one was
always being added anyway, in a later phase...
- It's consistent with the existing behavior.
Closes#19356
(cherry picked from commit e80aadd98ba2a461cc5063dac1895b5f535dcff2)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzge0HjU
Service-Version: 1.24
You can't return a `string_view` to a temporary. It's a miracle this
ever worked.
Broken since inception in a5f9c85c39
Closes#19355
(cherry picked from commit 46b9572e60a972f4eeef790bff9adb5a9e87829e)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzge0HmE
Service-Version: 1.24
This adds support for horizontal mouse wheel events (`WM_MOUSEHWHEEL`).
With this change, applications running in the terminal can now receive
and respond to horizontal scroll inputs from the mouse/trackpad.
Closes#19245Closes#10329
(cherry picked from commit 814f78ed2ccc0aa0dd0f48d0d4417bd7a35da03b)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgep1sM
Service-Version: 1.24
Fixes the terminal profile jsonschema to allow for null in the id. This
is to match the current implementation when disabling a built in default
keybind.
(cherry picked from commit eb16eb26ab5d0c3f36a1a2084edcceacdf2a99f9)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgemwL0
Service-Version: 1.24
Fixes the crash and also makes `SnapOnOutput` a bit nicer.
Closes#19325
## Validation Steps Performed
* Launch vim in WSL
* Exit
* No crash ✅
(cherry picked from commit 384932183fcb14067b5d8d50338a03378b57eb9e)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgegVZ8
Service-Version: 1.24
I do not like this.
## Validation Steps Performed
* Enable close buttons on tabs
* Open a tab
* Close the tab with middle click
* Open a tab
* Right click the tab
* Tab doesn't close, Menu opens ✅
(cherry picked from commit 4a34a765048ae07e42fa15b33e94fa1674c8a77e)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgeAlgM
Service-Version: 1.24
- Add Selection BG color
- Make Bright white brighter
## Summary of the Pull Request
Final tune for Dimidium color scheme before its release.
## References and Relevant Issues
#18563
## Detailed Description of the Pull Request / Additional comments
I made little change to Dimidium color scheme.
<img width="640" height="174" alt="cmp-lightness1c"
src="https://github.com/user-attachments/assets/2e4aa6ca-5864-4901-b323-2e2bb2bf00e8"
/>

<img width="584" height="207" alt="image"
src="https://github.com/user-attachments/assets/b70b0759-7961-4f8f-aaa7-762fc48e425b"
/>
- Adjusted "Bright white" slightly brighter, hoping it can be
distinguished better from "White".
- Defined "Selection Background" color.
This will be the final tune for Dimidum color scheme.
(cherry picked from commit 8011f3e28cd1c58f415be33a88cef7b9ce38ea09)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgeMuoQ
Service-Version: 1.24
tl;dr: ~Apphost() may pump the message loop.
That's no bueno. See comments in the diff.
Additionally, this PR enables `_assertIsMainThread` in
release to trace down mysterious crashes in those builds.
(cherry picked from commit 8d41ace320216f4c22b0aa7fb4cd42f362096e9c)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgeJeYA
Service-Version: 1.24
As per: https://github.com/microsoft/terminal/discussions/19280#discussioncomment-14237148
## Validation Steps Performed
* Launch wtd via handoff (spawn cmd, etc.)
* Shift+Click the tab bar + button to create a new window
* Close the initial window
* UI doesn't lock up ✅
(cherry picked from commit 7849b00cbddfb4d7f532472bc41fd8d8579bd72e)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgeLN9s
Service-Version: 1.24
tl;dr: Open/CloseClipboard are surprisingly not thread-safe.
## Validation Steps Performed
* Copy a large amount of text (>1MB)
* Run `edit.exe`
* Press and hold Ctrl+Shift+V
* Doesn't crash ✅
(cherry picked from commit 589934323726f02e84465b973881f36d63b67f1f)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgeLIjw
Service-Version: 1.24
I legitimately cannot figure out how I forgot this. Bell should support
all the same validation as other media resources! Technically this means
you can set `bellSound` to `desktopWallpaper`, but... we'll pretend that
makes sense.
I reworked the viewmodel to be a little more sensible. It no longer
requires somebody else to check that its files exist. The settings UI
now also displays `File not found` in the _preview_ for the bell if it
is a single file which failed validation!
(cherry picked from commit 4272151adc0b3b4c35077ee690899149d649c5ad)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgeF9qU
Service-Version: 1.24
> _I am altering the deal. Pray I do not alter it further._
> -the AERO team, maybe
(cherry picked from commit bd14f6908026a1d868b6719774ee685433df4fbf)
Service-Card-Id: PVTI_lADOAF3p4s4BBcTlzgeF9fQ
Service-Version: 1.24
Reflect inbox changes to `onecore/windows/core/console/open`.
* eed3a6fa5 Merged PR 13076689: Update managed TAEF tests that exist in
GE branches to use the new publishing locations of TAEF's managed
reference binaries.
* 718d7d02d Merged PR 12483430: build console* with clang
Somebody internal is trying to build the console with Clang (which is
cool).
---------
Co-authored-by: Dragos Sambotin <dragoss@microsoft.com>
Co-authored-by: Phil Deets <pdeets@microsoft.com>
Interesting changes in this update:
- better support for `REFIID,IUnknown**` in `capture`
- `LOAD_LIBRARY_SEARCH_DEFAULT_DIRS` for all SxS DLL loading
- `get_self` reading from classic COM interfaces (rather than WinRT
ones)
- better incremental builds by ignoring stale winmd files (see
microsoft/cppwinrt#1404)
- some ability to mix c++17 and c++20 static libraries
- better codegen for `consume` methods
This version of C++/WinRT is better about propagating `protected`
fields from the metadata into the C++ projections. This required
us to switch to the `I...Protected` interfaces for some things
we are _technically_ not allowed access to. We also had some
`overridable` (protected!) members of our own that needed undec-
oration.
The unfocused appearance section in the settings UI looks a little off.
Specifically, the header was too large (larger than the breadcrumbs!)
and the button was weirdly aligned.
This PR reduces the size of the header and creates a style in
CommonResources that manages it. This is the only place it's used, for
now. A vertical alignment was added to the "create appearance" and
"delete appearance" buttons to make them look better. The top margin of
the "Text" header was also removed so that there isn't an awkward gap in
the unfocused appearance section (the 32 that was there was moved to the
bottom of the control preview so that that area remains unaffected.)
Follow-up from #19001
## Summary of the Pull Request
Adds a telemetry provider to the Terminal.Settings.Editor project as
well as new telemetry events to track traffic through the settings UI.
Specifically, the following events were added:
- `NavigatedToPage`: Event emitted when the user navigates to a page in
the settings UI
- Has a `PageId` parameter that includes the identifier of the page that
was navigated to
- (conditionally added when PageId = `page.editColorScheme`)
`SchemeName` parameter tracks the name of the color scheme that's being
edited
- conditionally added when PageId = `page.extensions`:
- `ExtensionPackageCount`: The number of extension packages displayed
- `ProfilesModifiedCount`: The number of profiles modified by enabled
extensions
- `ProfilesAddedCount`: The number of profiles added by enabled
extensions
- `ColorSchemesAddedCount`: The number of color schemes added by enabled
extensions
- conditionally added when PageId = `page.extensions.extensionView`:
- `FragmentSource`: The source of the fragment included in this
extension package
- `FragmentCount`: The number of fragments included in this extension
package
- `Enabled`: The enabled status of the extension
- (conditionally added when PageID = `page.newTabMenu`) if the page is
representing a folder view
- conditionally added when PageID = `page.profile.*`:
- `IsProfileDefaults`: if the modified profile is the profile.defaults
object
- `ProfileGuid`: the guid of the profile that was navigated to
- `ProfileSource`: the source of the profile that was navigated to
- conditionally added when PageID = `page.profile` (aka the base profile
page):
- `Orphaned`: tracks if the profile was orphaned
- `Hidden`: tracks if the profile is hidden
- (conditionally added when PageID = `page.profile.appearance`)
`HasBackgroundImage`: `if the profile has a background image defined`
- (conditionally added when PageID = `page.profile.appearance`)
`HasUnfocusedAppearance`: `if the profile has an unfocused appearance
defined`
- `AddNewProfile`: Event emitted when the user adds a new profile
`IsExtensionView` parameter tracks if the page is representing a view of
an extension
- Has a `Type` parameter that represents the type of the creation method
(i.e. empty profile, duplicate)
- `ResetApplicationState`: Event emitted when the user resets their
application state (via the UI)
- `ResetToDefaultSettings`: Event emitted when the user resets their
settings to their default value (via the UI)
- `OpenJson`: Event emitted when the user clicks the Open JSON button in
the settings UI
- Has a `SettingsTarget` parameter that represents the target settings
file (i.e. settings.json vs defaults.json)
- `CreateUnfocusedAppearance`: Event emitted when the user creates an
unfocused appearance for a profile
- `IsProfileDefaults`: if the modified profile is the profile.defaults
object
- `ProfileGuid`: the guid of the profile that was navigated to
- `ProfileSource`: the source of the profile that was navigated to
- `DeleteProfile`: Event emitted when the user deletes a profile
- also includes `ProfileGuid`, `ProfileSource`, `Orphaned` from the
`NavigatedToPage` section above
The page ids can be reused later as a serialized reference to the page.
We already use the one for the extensions page for the "new" badge.
The Name, Source, and Commandline profile settings should not be allowed
to be set on the Profiles.Defaults object. This just enforces that by
clearing them (as is done with Guid).
These profile settings are omitted from the settings UI's profile
defaults page.
Closes#19202
You know how much I hate squirreling away information on objects we have
to pass halfway across the universe just to get back.
In this case, `StartingTitle` will always be the name of the profile. We
only used ProfileName in places where we _needed a Title_, so this makes
it much more obvious what we're doing.
## Summary of the Pull Request
Fixes a bug where copying and coloring selected text would be off by
one. This was introduced in #18106 when selection was updated to be
stored as an exclusive range. `Selection::_RegenerateSelectionSpans()`
was updated then, but copying text and coloring selection didn't rely on
selection spans.
Copying text relies on `GetSelectionAnchors()`. This function has now
been updated to increment the bottom-right point of the selection. This
way, `GetTextSpans()` operates on the expected _exclusive_ range.
Coloring selection relies on `TextBuffer::SearchText()`,
`TextBuffer::GetTextRects` and `GetSelectionSpans()`. Both
`Selection::ColorSelection()` were updated to use `rect` over
`inclusive_rect` to emphasize that they are exclusive ranges. Converting
between the two improves clarity and fixes the bug.
## References and Relevant Issues
Introduced in #18106
## Validation Steps Performed
Copying text works in the following scenarios:
✅ single line, left-to-right and right-to-left
✅ multi-line, diagonal directions
✅ block selection
Coloring text works in the following scenarios:
✅ctrl+# --> color instance
✅ctrl+shift+# --> color all instances
Closes#19053
Fixes a few issues with some telemetry events:
- The macro is organized as such: `TraceLoggingX(value, argName,
[argDescription])`. A few args had a description set on the spot where
the name should be. I added a name for a few of these.
- `TraceLoggingBool` --> `TraceLoggingInt32` for `themeChoice` (we
shouldn't be casting the evaluated int as a bool; it loses some of the
data we care about)
- improves the description for `themeChoice` to include information
about the legacy values
Checked through all our telemetry events and all of the args have a
proper name set. We tend to use `TraceLoggingValue` too which
automatically figures out the type that's being used, so that's also
handled.
`IsOn` is the blinker on/off state, which `IsVisible`
is the actual cursor visibility on/off state.
## Validation Steps Performed
* Run bash/zsh in WSL
* (Repeatedly) Quickly scroll right and press A-Z
* Scrolls to the left ✅
Automatically generates an "SSH" folder in the new tab menu that
contains all profiles generated by the SSH profile generator. This
folder is created if the SSH generator created some profiles and the
folder hasn't been created before. Detecting if the folder was generated
is done via the new `bool ApplicationState::SSHFolderGenerated`. The
logic is similar to `SettingsLoader::DisableDeletedProfiles()`.
Found a bug on new tab menu's folder inlining feature where we were
counting the number of raw entries to determine whether to inline or
not. Since the folder only contained the match profiles entry, this bug
made it so that the profile entries would always be inlined. The fix was
very simple: count the number of _resolved_ entries instead of the raw
entries. This can be pulled into its own PR and serviced, if desired.
## References and Relevant Issues
#18814#14042
## Validation Steps Performed
✅ Existing users get an SSH folder if profiles were generated
## PR Checklist
Closes#19043