Commit Graph

155321 Commits

Author SHA1 Message Date
Matt Bierner c95b5661ac Merge branch 'main' into dev/mjbvz/wonderful-piranha 2026-04-21 08:11:12 -07:00
Matt Bierner 8dfc15d189 Merge pull request #311495 from mjbvz/dev/mjbvz/smooth-swordtail
Defer EditorMouseEvent position computation
2026-04-21 08:08:57 -07:00
Ulugbek Abdullaev 3170842edd Fix steer/queue keybinding labels in picker dropdown (#310961)
* Fix steer/queue keybinding labels in picker dropdown

The queue/steer picker dropdown was showing inverted keybinding labels:
e.g. Steer showed 'Alt+Enter' but Enter actually steered.

Root cause: ActionWidgetDropdown looked up keybindings via the global
IKeybindingService context. The queue/steer keybindings' when-clauses
require inChatInput and requestInProgress, which are scoped context keys
not visible globally. lookupPrimaryKeybinding fell back to the last
registered binding for each  the opposite of what was active.command

Fix:
- Add optional keybinding field to IActionWidgetDropdownAction so callers
  can override the global lookup with a pre-resolved keybinding.
- In ChatQueuePickerActionItem, resolve Enter / Alt+Enter directly and
  assign them to queue/steer based on the user's configured default,
  so labels always match what is actually bound.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Use scoped context for keybinding lookup

Address PR review: resolve queue/steer dropdown keybinding labels via the
scoped contextKeyService instead of hard-coding Enter/Alt+Enter. This
respects user customizations and scoped overrides (e.g. editingRequestType
when editing a queued/steer request).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Add chatInputHasText to lookup overlay; add unit test

The keybinding when clauses also require chatInputHasText. Without
including it in the overlay used to look up display labels, the picker
silently fell back to no label. Add it (the picker is only shown when
there is text to send) and add a unit test that asserts the resolved
keybinding for both default=steer and default=queue.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-21 08:07:34 -07:00
Lee Murray 0f7e0b9166 Agents: Add experimental gradient styling for chat send button (#311685)
* Agents - add experimental gradient styling for chat send button

* Agents - enhance chat send button focus and hover styles for gradient feature

* Agents - adjust scale transformation for chat animation effect

* style: add gradient animations for chat send button

* feat: add experimental gradient styling for chat send button

Co-authored-by: Copilot <copilot@github.com>

* fix: update experimental gradient setting for chat send button and refine hover styles

* fix: update class name for experimental send button gradient in chat styles

---------

Co-authored-by: mrleemurray <mrleemurray@users.noreply.github.com>
Co-authored-by: Copilot <copilot@github.com>
2026-04-21 17:02:12 +02:00
Ladislau Szomoru d4e3ed3296 Agents - add layout actions to open in modal editor (#311680)
* Agents - add action to open editor in modal editor group

* Add the other action

* Simplify action

* Update src/vs/sessions/browser/parts/media/editorPart.css

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Pull request feedback

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-21 17:01:59 +02:00
Johannes Rieken 7d8f4acc24 refactor: consolidate debug service registrations into a new contribution file (#311678)
Co-authored-by: Copilot <copilot@github.com>
2026-04-21 17:01:25 +02:00
Megan Rogge c4634a7e5f add expand action for question part (#311439)
fixes
#310886
2026-04-21 14:47:34 +00:00
Ladislau Szomoru e19e28776c Agents - get agent feedback working in the multi-file diff editor (#311686) 2026-04-21 14:46:49 +00:00
Don Jayamanne 4e26289a06 fix: update @github/copilot to version 1.0.34 and integrate AutoModeSessionManager in session services (#311650)
chore: update @github/copilot to version 1.0.34 and integrate AutoModeSessionManager in session services
2026-04-21 05:03:45 -07:00
Ladislau Szomoru fa123b8220 Agents - rework open changes action (#311665) 2026-04-21 05:03:22 -07:00
Lee Murray df028283c5 Agents: Refine animated chat input working border (#311653)
* Refine animated chat input working border

- Refactor animated ring to a ::before pseudo-element with mask trick so it
  can fade in/out via opacity when the .working class toggles
- Slow the spin from 1.2s to 3s for a calmer cadence
- Replace the static pulsing box-shadow with a 3-step keyframed glow that
  cycles through the same three theme colors as the conic ring, in sync
  with the spin (so the halo appears to emanate from the gradient)
- Drop the now-unused --chat-input-working-fill override in sessions and
  the matching entry in the stylelint allowlist

* feat(chat): add working border colors for chat input in light and dark themes

* feat(chat): update working border colors for chat input

* Update src/vs/workbench/contrib/chat/browser/widget/media/chat.css

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* feat(chat): add transition effect to chat input container

---------

Co-authored-by: mrleemurray <mrleemurray@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-21 11:11:17 +00:00
Don Jayamanne 232ae44e92 Implement plan review feedback functionality with UI enhancements (#311632)
* feat(chat): add plan review feedback functionality with editor integration

Co-authored-by: Copilot <copilot@github.com>

* feat(chat): implement plan review feedback functionality with editor actions and UI enhancements

Co-authored-by: Copilot <copilot@github.com>

* Udpates

* Fixes

* feat(chat): enhance plan review feedback registration logic to allow feedback only when applicable

Co-authored-by: Copilot <copilot@github.com>

* Updates

---------

Co-authored-by: Copilot <copilot@github.com>
2026-04-21 21:10:23 +10:00
Lee Murray d9b89caadf Merge pull request #311637 from microsoft/mrleemurray/agent-chat-placeholders
Add randomized placeholders for new-session chat input
2026-04-21 11:54:56 +01:00
Johannes Rieken fd7069083e Merge pull request #311350 from microsoft/joh/inline-chat-reasoning-effort
inline chat: add experiment-controlled reasoning effort and thinking settings
2026-04-21 12:48:26 +02:00
Ladislau Szomoru 38df135823 Agents - add open file/open changes actions (#311648) 2026-04-21 10:36:33 +00:00
Ladislau Szomoru 16e7e398e8 Agents - disable git commands in the editor title (#311645) 2026-04-21 10:32:41 +00:00
Ladislau Szomoru 1f3b864525 Agents - fix resource order in the multi-file diff editor (#311639) 2026-04-21 12:10:05 +02:00
vs-code-engineering[bot] 083af3b3af [cherry-pick] Remove ReviewPlanTool from BuiltinToolsContribution (#311638)
Co-authored-by: vs-code-engineering[bot] <vs-code-engineering[bot]@users.noreply.github.com>
2026-04-21 09:35:31 +00:00
mrleemurray 15d4bf6c4d feat(chat): refine chat input placeholders by removing ellipses for clarity 2026-04-21 10:21:47 +01:00
Don Jayamanne 018a47f3df feat(copilotcli): add WorktreeSessionIndex for managing chat session entries with JSONL persistence (#311609)
* feat(copilotcli): add WorktreeSessionIndex for managing chat session entries with JSONL persistence

* Udpates

Co-authored-by: Copilot <copilot@github.com>

* Updates

* Update extensions/copilot/src/extension/chatSessions/vscode-node/chatSessionMetadataStoreImpl.ts

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* Fixes

Co-authored-by: Copilot <copilot@github.com>

---------

Co-authored-by: Copilot <copilot@github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
2026-04-21 11:11:44 +02:00
mrleemurray 0c740b2c73 feat(chat): enhance chat input with randomized placeholders to improve user experience
Co-authored-by: Copilot <copilot@github.com>
2026-04-21 10:07:19 +01:00
mrleemurray e186b4cc5d feat(chat): add randomized placeholders for new-session chat input 2026-04-21 10:03:49 +01:00
Peng Lyu d844c09829 handle tap and click properly (#311604)
* handle tap and click properly

Co-authored-by: Copilot <copilot@github.com>

* 💄 type

Co-authored-by: Copilot <copilot@github.com>

---------

Co-authored-by: Copilot <copilot@github.com>
2026-04-21 01:12:06 -07:00
Lee Murray 8574f4ff40 Merge pull request #311357 from microsoft/mrleemurray/new-session-polish
Refactor chat UI for improved layout and consistency
2026-04-21 09:08:45 +01:00
Justin Chen 938f78a972 add better padding for thinking + persistant progress (#311603) 2026-04-21 07:52:18 +02:00
Maruthan G 2f92697690 fix(chat): enable scrollbar for height-capped code blocks in tool confirmations (#283242) (#310975)
* fix(chat): enable scrollbar for height-capped code blocks in tool confirmations (#283242)

* fix(chat): use chat scrollbar width for capped code blocks

(Written by Copilot)

---------

Co-authored-by: Rob Lourens <roblourens@gmail.com>
2026-04-21 05:08:08 +00:00
Justin Chen 1a39bedfe8 show animation around chat input while working (#311125)
* developer joy animation around input box

* add back removed stuff

* don't show border while stuff is working

* better css

* add color components and cleanup

* progress border
2026-04-21 07:07:40 +02:00
Anthony Kim e8a7c6d6df Stop copying node-pty into Copilot CLI SDK (#310925)
* Stop copying node-pty into Copilot CLI SDK

* reanem

Co-authored-by: Copilot <copilot@github.com>

* resovle copilot comment

* recognize other sdk prebuilds NOT node-pty

Co-authored-by: Copilot <copilot@github.com>

---------

Co-authored-by: Copilot <copilot@github.com>
2026-04-20 21:25:55 -07:00
Robo a1d3ff15f4 feat: enable shared safestorage on windows (#311418)
* feat: enable shared safestorage on windows

* chore: bump distro
2026-04-20 20:42:50 -07:00
Rob Lourens b2d3ae7751 Spawn agent host immediately when chat.agentHost.enabled flips on (#311531)
* Spawn agent host immediately when chat.agentHost.enabled flips on

Previously, toggling chat.agentHost.enabled at runtime required an app
restart before the local agent host process actually spawned and the
chat/sessions integrations registered. The setting was checked exactly
once at construction time in four places, all of which early-returned if
disabled.

Each site now also registers a one-shot onDidChangeConfiguration listener
 true flip triggers setup without a restart:

- src/vs/code/electron-main/app.ts: wraps the
  ElectronAgentHostStarter + AgentHostProcessManager construction.
- src/vs/platform/agentHost/electron-browser/agentHostService.ts:
  AgentHostServiceClient calls _connect() on flip.
- src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/
  agentHostChatContribution.ts: extracted constructor body into _enable().
- src/vs/sessions/contrib/agentHost/browser/localAgentHost.contribution.ts:
  same one-shot pattern.

Disable still requires a restart (no teardown of the singleton renderer
service or utility process).

Adds 5 unit tests in agentHostChatContribution.test.ts covering the
gating behavior and the one-shot semantics.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Prompt restart when chat.agentHost.enabled changes

Replace the previous approach (one-shot config listeners in 4 files) with a
single entry in SettingsChangeRelauncher.SETTINGS. Toggling the setting now
shows the standard 'restart required' dialog, which is simpler and avoids
races between renderer and main process setup.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-21 02:51:24 +00:00
Paul 5c0572d0cd Fix incremental renderer in paragraph buffer mode (#311573) 2026-04-21 01:39:47 +00:00
Yogeshwaran C a4d117dc0e Show detail field for all debug console completion items (#310379)
Fixes #278113

Co-authored-by: Rob Lourens <roblourens@gmail.com>
2026-04-21 01:31:30 +00:00
Tyler James Leonhardt 8f796b4d8f Initial framework of Claude sessions in the Agents app (#311532)
* Initial framework of Claude sessions in the Agents app

This is barely functional, but it _is_ possible to chat with Claude through it.

Bugs:

First sent message from the welcome chat behavior is VERY strange. The chat is shown completely blank. Then I see the chat under "Unknown" section in the sessions list. I click it, it disappears after a second and reappears in the "Unknown" section. I click it again, it re-appears in the correct place... then I can start chatting with it.

Secondly, no dropdowns show in the existing chat so you can't change the permission mode once you start.

I put all of this behind a setting since it's not really ready yet.. but I wanted to get more eyes on these bugs.

Co-authored-by: Copilot <copilot@github.com>

* feedback

Co-authored-by: Copilot <copilot@github.com>

---------

Co-authored-by: Copilot <copilot@github.com>
2026-04-20 18:10:10 -07:00
Connor Peet cf0709667e agentHost: fix broken state leading to misrouted messages (#311572) 2026-04-21 00:57:38 +00:00
Connor Peet 00f882a16c Merge pull request #311301 from microsoft/roblou/agents/remote-agent-session-routing-fix
Align local & remote agent host sessionType IDs
2026-04-20 17:14:21 -07:00
Osvaldo Ortega 8ca93cdbac Improve tunnel connection reliability: malformed-frame hardening, auth short-circuit, host-online resume (#311518)
* Improve tunnel connection reliability: malformed-frame hardening, auth short-circuit, host-online resume, session cleanup

Transport layer:
- Add malformed-frame detection across all three transports (WebSocketClientTransport,
  TunnelConnectionTransport, TunnelRelayTransport): warn log first 5 per connection,
  force-close transport after >10 to trigger reconnect loop instead of silently
  dropping corrupt data. Shared constants in new transportConstants.ts.

Reconnect logic (tunnelAgentHost.contribution.ts):
- Auth-error short-circuit: authExpired/auth errors immediately pause reconnects
  instead of burning 10 retry slots, resume driven by onDidChangeSessions.
- Host-online auto-resume: _silentStatusCheck detects when a host-offline-paused
  tunnel comes back online and auto-resumes without needing a wake/visibility event.
- Session-removal cleanup: react to github session removal by tearing down matching
  tunnel state and best-effort disconnect.
- Richer _categorizeError: distinguish authExpired (401/403/token expired) from
  generic auth, add ECONN/ENOTFOUND/ETIMEDOUT to network category.

Telemetry:
- Add authExpired to TunnelConnectErrorCategory and TunnelConnectFailureReason types.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix review findings: token regex over-match, auto-cached authProvider

- _categorizeError: remove \btoken\b from auth regex to avoid matching
  'connection token' protocol errors. Use 'auth.*(fail|error|invalid)'
  instead, which catches real auth failures without over-matching.
- _silentStatusCheck: pass 'github' authProvider to cacheTunnel() so
  auto-discovered tunnels are properly matched by _handleSessionsChange
  for teardown on session removal.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address PR review comments

- Pass actual errorCategory ('auth'|'authExpired') to _pauseReconnect
  instead of always using 'authExpired'. Add 'auth' to
  TunnelConnectFailureReason type.
- Update telemetry classification comments to list all current enum
  members (authExpired for errorCategory, auth/authExpired for
  failureReason).
- Log actual data type (ArrayBuffer/Blob) and byte length for non-string
  WebSocket frames instead of coercing to empty string.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 17:13:52 -07:00
Osvaldo Ortega ebb2ebc260 feat: enhance authentication handling for web sessions and account initialization (#311538) 2026-04-20 17:13:29 -07:00
Matt Bierner 7efcd94838 Merge pull request #311537 from mjbvz/dev/mjbvz/wee-parrot
Apply class pascal cases eslint rule to all ts files
2026-04-20 16:54:00 -07:00
Matt Bierner a13c4de255 Merge pull request #311536 from mjbvz/dev/mjbvz/eerie-raven
Remove old tfidf worker code
2026-04-20 16:39:20 -07:00
Matt Bierner 0295564b79 Apply class pascal cases eslint rule to all ts files
No reason to keep this just to core
2026-04-20 16:32:18 -07:00
Rob Lourens 4e3f7dcbe2 Hide 'View Extension' hover action for core chat agents (#311526)
* Hide 'View Extension' hover action for core chat agents

Core agents (e.g. the agent host) register with a placeholder
extension id and have no real extension to view. Skip adding the
'View Extension' hover action when the agent has isCore: true.

Fixes #311510

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Fix TDZ in getChatAgentHoverOptions, defer agent lookup

Some callers construct the hover options before the surrounding
template variable is initialized, so resolving the agent eagerly
hits a TDZ. Make 'actions' a lazy getter so the agent is only
read when the hover is actually shown.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 16:30:49 -07:00
Rob Lourens e0c3dafcdb Reuse PermissionPickerActionItem for agent host auto-approve picker (#311263)
* Reuse PermissionPickerActionItem for agent host auto-approve picker

Previously the agent host had its own custom auto-approve picker that
duplicated most of the workbench PermissionPickerActionItem widget. This
refactor reuses the workbench widget when the active session's
autoApprove session-config property uses the well-known schema (string
type, enum subset of {default, autoApprove, autopilot} containing
'default'). Sessions that match get the workbench widget; non-conforming
agents fall back to the existing generic per-property picker.

- Adds AgentHostPermissionPickerDelegate and a thin
  AgentHostPermissionPickerActionItem subclass that toggles its
  visibility reactively as the active session changes.
- Generalizes the warning/info color rules in chat.css so they live
  with the widget rather than being scoped to .chat-secondary-toolbar.
- Groups all agent-host-only files under
  src/vs/sessions/contrib/chat/browser/agentHost/.
- Fixes a regression where the picker would stay hidden after
  navigating back to the new-chat view; the IActionViewItemService
  factory only runs once per render, so visibility must be reactive
  rather than gated at construction.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Refactor: agent host reuses PermissionPicker (sessions) instead of PermissionPickerActionItem (workbench)

Both pickers now render in the same context (new-chat-page action bar), so
the previously-needed CSS specificity overrides (icon/font sizing,
padding, color rule un-scoping in chat.css) all go away.

Changes:
- Add IPermissionPickerDelegate to permissionPicker.ts: optional
  currentLevel observable, optional isApplicable observable, setLevel.
- Refactor PermissionPicker to take a delegate. When currentLevel is
  provided, the picker label tracks it reactively. When isApplicable is
  provided, the picker hides itself when false.
- Add CopilotPermissionPickerDelegate (writes through to the active
  CopilotChatSessionsProvider session). Preserves today's behavior.
- Move AgentHostPermissionPickerDelegate to its own file under
  agentHost/, retargeted at the new interface (currentLevel,
  isApplicable, setLevel).
- agentHostSessionConfigPicker.ts now constructs PermissionPicker with
  the agent host delegate and wraps in PickerActionViewItem.
- Delete agentHostPermissionPickerActionItem.ts (the workbench widget
  subclass) and its CSS overrides.
- Revert chat.css warning/info color un-scoping (no longer needed since
  agent host doesn't use the workbench widget anymore).
- Rename the test file to match the new product file. Tests cover the
  delegate's permission-level mapping, isApplicable reactivity, and
  isWellKnownAutoApproveSchema.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Use PermissionPickerActionItem for ChatInputSecondary, PermissionPicker for NewSessionControl

Restore the contextual split: agent host now uses each widget where it's
expected to render. The new-chat page (NewSessionControl) keeps the
sessions PermissionPicker (matches surrounding sessions pickers); the
running chat widget (ChatInputSecondary) uses the workbench
PermissionPickerActionItem (matches the rest of the chat-input
secondary toolbar that the extension-host CLI already uses).

Both share AgentHostPermissionPickerDelegate. To make the same delegate
satisfy both consumers, rename its members to
currentPermissionLevel/setPermissionLevel (matching the workbench's
IPermissionPickerDelegate).

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Consolidate duplicate AUTO_APPROVE_PROPERTY constant

Both `agentHostPermissionPickerDelegate.ts` and
`agentHostSessionConfigPicker.ts` had identical `'autoApprove'` string
constants (one called `AUTO_APPROVE_SESSION_CONFIG_PROPERTY`, the other
`AUTO_APPROVE_PROPERTY`). Standardize on the shorter name and import it
in the picker. Also drops a now-unused `KNOWN_AUTO_APPROVE_VALUES` set
that was left behind in the picker file. (Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Address Copilot review comments

- Dispose `onDidChangeProviders` Emitter in delegate test setup so the
  suite-level leak detector is happy. Refactor `setup()` to take the
  leak-tracking store and register all created disposables itself, so
  individual tests don't repeat the boilerplate.
- Fix corrupted JSDoc on `CopilotPermissionPickerDelegate` (sentence
  was mangled across an inline-code span). (Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Drop redundant `_slot` field from PermissionPicker

The `slot` local in `render()` is in scope for the `autorun` closures, so
storing it on `this` is unnecessary. Removing the field also drops the
needless null-check inside the visibility autorun. (Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 16:25:00 -07:00
Rob Lourens 25032cf76e Revert "Don't add agent-host worktree as workspace folder (#310888)" (#311525)
* Revert "Don't add agent-host worktree as workspace folder (#310888)"

This reverts commit f97c287567.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

* Remove now-unused AGENT_HOST_SCHEME guard

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 16:24:34 -07:00
Matt Bierner 26e2b58a36 Remove old tfidf worker code 2026-04-20 16:16:39 -07:00
Bhavya U 641cbea24b Fix create_file duplicating content when file deleted but doc in memory (#311500) 2026-04-20 15:26:08 -07:00
Don Jayamanne d52c531dd3 Enhance draft input persistence for remote chat sessions (#311312)
* Enhance draft input persistence for remote chat sessions

* Strip attachments from external session draft input state in metadata

Agent-Logs-Url: https://github.com/microsoft/vscode/sessions/fdcea905-d6d1-42f5-8993-0ead68edb74c

Co-authored-by: DonJayamanne <1948812+DonJayamanne@users.noreply.github.com>

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
2026-04-20 22:11:51 +00:00
ulugbekna bc3fee1c7c update jsdoc
Co-authored-by: Copilot <copilot@github.com>
2026-04-21 03:06:02 +05:00
ulugbekna 7382ed6438 nes: refactor: simplify toInlineSuggestion
Co-authored-by: Copilot <copilot@github.com>
2026-04-21 03:06:02 +05:00
Matt Bierner 4920ebc905 Merge pull request #311501 from mjbvz/dev/mjbvz/plain-llama
Don't expose public mutable properties from actionbar
2026-04-20 15:04:27 -07:00
Rob Lourens 44ce49e049 Address PR review: unexport SessionsManagementService, remove diagnostic logs
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-04-20 15:02:22 -07:00