Skip to content

[pull] main from microsoft:main#1271

Merged
pull[bot] merged 16 commits into
code:mainfrom
microsoft:main
May 19, 2026
Merged

[pull] main from microsoft:main#1271
pull[bot] merged 16 commits into
code:mainfrom
microsoft:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 19, 2026

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

Copilot AI and others added 16 commits May 18, 2026 21:28
Co-authored-by: mjbvz <12821956+mjbvz@users.noreply.github.com>
Co-authored-by: mjbvz <12821956+mjbvz@users.noreply.github.com>
…-image

mermaid: allow data URI images in chat/preview CSP
…-zoom-buttons

Mermaid preview: consume zoom-control click/dblclick to prevent edit-mode toggles
) (#315284)

* fix: guard setDimensions against disposed ptyProcessReady (fixes #315282)

When a terminal process manager is disposed, ptyProcessReady is set to
undefined. If setDimensions is called after disposal (e.g., during a
resize triggered by a configuration change event that fires during the
dispose sequence), calling .then() on undefined throws a TypeError.

Add a guard clause to return early when ptyProcessReady is undefined,
preventing the crash without masking the error from telemetry.

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

* fix: dispose resize debouncer before process manager to prevent race

Dispose _resizeDebouncer before _processManager.dispose() so that no
resize callbacks can fire after ptyProcessReady has been nulled. This
addresses the root cause (disposal ordering) rather than just guarding
against the symptom, as suggested by @bryanchen-d.

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

* refine guard: silence post-dispose, throw on pre-init

Make the setDimensions guard conditional on _store.isDisposed so it
only silences the legitimate teardown race (#315282). Calls against a
live but uninitialized manager now throw an explicit error instead of
being silently dropped, preserving our ability to surface real caller
ordering bugs.

---------

Co-authored-by: vs-code-engineering[bot] <122617954+vs-code-engineering[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Bryan Chen <brchen@microsoft.com>
…317220)

Co-authored-by: vs-code-engineering[bot] <vs-code-engineering[bot]@users.noreply.github.com>
* Claude: resume cross-window sessions from disk on first send

Repro: open a Claude session in window A, then in window B (or after
an agent-host restart) send a message to that session.

Before: sendMessage hit the 'session not in _sessions and not
provisional' branch and threw 'Cannot send to unknown session: <id>',
because materialize was only ever reachable via the createSession
provisional path.

After: that branch routes through new _resumeSession(sessionId, uri),
which mirrors CopilotAgent._resumeSession — reads workingDirectory
from sdkService.getSessionInfo, model + permissionMode from the
metadata overlay, synthesises an IClaudeMaterializeProvisional, and
calls materializer.materialize(..., 'resume') so the SDK reloads the
existing transcript instead of minting a fresh sessionId.

ClaudeMaterializer.materialize gains an optional startMode parameter
('fresh' | 'resume', default 'fresh') that selects Options.sessionId
vs Options.resume in _buildOptions. The existing fresh-startup call
sites are unchanged.

Tests: existing 'disposing a provisional session never calls SDK
startup' assertion still passes — the new error wording 'Cannot
resume unknown session' still matches /unknown session/i, and
_resumeSession throws before startup when the fake SDK has no
session record.

* Test: cross-window Claude session resume + missing-SDK-record

Two unit tests for the _resumeSession path added in the previous
commit:

1. Disk-only happy path: stage an entry in sdk.sessionList that was
   never createSession'd on this agent, call sendMessage on its URI,
   and pin that the SDK is started with Options.resume = sessionId
   (not Options.sessionId), the materialize event fires with the
   right cwd, and the session lands in _sessions.

2. Failure path: sdk.sessionList is empty, sendMessage on an unknown
   URI throws /unknown session/i and does NOT spawn the SDK
   subprocess (startupCallCount stays 0).

* Claude resume: resolve git project from cwd, mirror createSession

_resumeSession was passing project: undefined into both the
provisional record and the materialize event. The fresh-session path
in createSession resolves project metadata from the workingDirectory
via projectFromCopilotContext + IAgentHostGitService; resume should
do the same so the materialize event consumers see the same project
shape regardless of which window opened the session.

Best-effort: a resolution failure (no repo, git CLI missing) downgrades
to undefined rather than blocking the resume.

* Claude: don't clobber resumed permissionMode on turn 2

Copilot PR review on cross-window resume PR caught a real regression:
the materialized-session branch in sendMessage was unconditionally
calling:

  session.setPermissionMode(_readSessionPermissionMode(uri) ?? 'default')

before yielding every non-first turn. For a session resurfaced via
_resumeSession, AgentService never registers the per-session schema
(that side-effect only fires for createSession-spawned sessions), so
_readSessionPermissionMode returns undefined and the fallback
silently downgrades a plan-mode session to default mid-conversation.

Fix: only forward setPermissionMode when the live config carries a
defined value. The session's seeded bijective state (set via
seedBijectiveState at resume time) stays authoritative when there is
no live override.

Test: stage the per-session DB with claude.permissionMode='plan',
resume, send two turns, assert no 'default' ever lands at the SDK
(recordedModes stays ['plan']). createTestContext gains an optional
{ database } override so the test can pre-populate the overlay
without rebuilding the service collection inline.
Comments out the registration of WorktreeCreatedTaskDispatcher and removes its import to
work around a bug. This is a stopgap until the underlying issue can be investigated and
fixed.

- Comments out the registerWorkbenchContribution2 call for WorktreeCreatedTaskDispatcher
- Removes the now-unused import

(Commit message generated by Copilot)
fix: focus input on widget click outside textarea and action bar
* fix: enhance request validation for CopilotCLI session type

* Potential fix for pull request finding

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

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
* provideChatSessionCustomizations for sessionResource

* Potential fix for pull request finding

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

* Potential fix for pull request finding

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

* update

* update

* fix fixtures

* update

* update

* AgentCustomizationItemProvider: remember _sessionCustomizations per session

* update

* update

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
@pull pull Bot locked and limited conversation to collaborators May 19, 2026
@pull pull Bot added the ⤵️ pull label May 19, 2026
@pull pull Bot merged commit 4704237 into code:main May 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants