Skip to content

agentHost: await real signals instead of polling in the local model bridge tests - #343737

Merged
Alexandru Dima (alexdima) merged 1 commit into
mainfrom
agents/no-timeout-polling-local-model-bridge
Oct 23, 2026
Merged

Alexandru Dima (alexdima) merged 1 commit into
mainfrom
agents/no-timeout-polling-local-model-bridge

Conversation

@alexdima

Copy link
Copy Markdown
Member

Follow-up to #342698.

Problem

The local model bridge tests waited with two helpers from fakeLlamaServer.ts. settle(rounds = 5) yielded to setImmediate a fixed number of times. waitFor(predicate, timeoutMs = 10_000) re-checked a predicate after each setImmediate until a real-time deadline. On origin/main eeedb17 there were 105 waitFor and 27 settle calls: 26 and 5 in serverSupervisor.test.ts, 79 and 20 in shimLocalModelProvider.test.ts, and 2 settle calls in servingAccessImpl.test.ts. Four loops were built on settle: the record-and-lock loop of the supervisor's dispose test, the supervisor's driveProbeRetries, and the two polls < 50 health-poll loops in the shim tests. local/code-no-timeout-polling-loop reports none of them, because the polling happens inside the helpers.

How long these waits lasted depended on how many event-loop turns the code under test happened to take. The fixed-turn settle() calls were mostly negative checks, and how strong they were depended on that same timing. Two examples: when user drains were given a timeout, the update test's "after an hour" check still passed (M6). When an Auto session ignored "Use in Auto" being off, the Auto test still passed (M11).

Change

Wait Waited for Now awaits
waitFor on supervisor.state (24, supervisor tests) supervisor state waitForState(supervisor.state, ...)
waitFor on the provider's status (63, shim tests) status, through family() and activeReady() whenStatus(harness, predicate), a waitForState on harness.provider.status
status stopped after provider.stop() (5) the user stop has ended whenStopped(harness): the stop promise of the harness's new RecordingSupervisor, then the status
downloader.requests.length === n (3) a download was requested FakeDownloader.whenRequested(n), deferreds completed by the fake
runtime.listDevicesWaiting (2) a load is held in its device probe FakeRuntime.listDevicesHeld, a deferred completed at the gate
processes[0].hasExited && server === 'stopped' (2) the cancelled load's process exited and the server stopped await process.exited, then waitForState(supervisor.state, ...)
!fs.existsSync(<old version>) (1) the update pruned the old version nothing more (see below)
health-poll loops (2, shim tests) and driveProbeRetries the server's health is polled on the fake clock pollUntil(harness, predicate) and driveProbeRetries race the result with FakeClock.whenTimerDue(<poll interval>), and advance one poll only when one is pending
dispose test: settle() and the loop on the record file and the lock, with a 10 s deadline the supervisor's record deletion and lock release recordWorkDone(supervisor): a no-op queued on the supervisor's _recordIo sequencer, which runs that work; after the exit, await child.exited first
crash during a user drain: settle() the supervisor's exit handler await child.exited
stopOutcome: waitFor(() => outcome !== 'pending', 2_000) the stop settles, with a readable pending otherwise raceTimeout(stop, 2_000)
"after an hour" checks (3): waitFor(() => true) or settle() negative: the drain has no timeout FakeClock.advance now returns how many timers ran; the snapshot asserts timersRun: 0
idle timeout with a hold: settle() negative: no idle unload the server state and telemetry events right after the advance; the idle timer's callback decides and reports idleUnload synchronously
settle() after an Auto session with Use in Auto off, after endTurn, and after a stale or cancelled preparation completes (4) negative: nothing loads pendingLoad(harness), the provider's in-flight _start promise, captured before the gate opens in the two preparation tests
device change test: waitFor(server stopped && family gone) and two settle(20) the swap goes on after its drain; then a start and a direct request pendingSwap(harness) (the swap's settled), and pendingLoad(harness) after the start and after the direct request
settle() after the context size reload negative: exactly one reload pendingSwap(harness)
servingAccessImpl.test.ts (2) ensureStarted has decided clock.whenTimerDue(LOAD_TIMEOUT_MS): waiting for a swap or for a start arms the load deadline
other settle() calls (9) nothing that decides the result removed (see below)

settle() and waitFor() are removed from fakeLlamaServer.ts.

Details worth a look:

  • The provider's stop. The status reads stopped as soon as the supervisor publishes it. The provider still refuses background loads until the supervisor's stop promise settles and its .finally clears _userStopPending. A first draft that waited only for the status made three tests time out, because start() or updateLiveConfig() came too early (M12b). RecordingSupervisor overrides stop() to keep the latest stop promise. Awaiting that promise runs after the provider's .finally.
  • Private state in three helpers. recordWorkDone, pendingLoad and pendingSwap read _recordIo, _start and _swap through element access. None of them has a public completion signal. Each line disables local/code-no-bracket-notation-for-identifiers with a reason, as 17 other test files do.
  • Negative checks. Every timeout here would be a timer on the injected clock, which fires synchronously in advance(), so timersRun: 0 holds deterministically. Under M6 all three "after an hour" tests fail; with the original tests, the update test passes. The idle check asserts the unload decision, not the timer. M7b, which arms the idle timer while the server is held and still refuses the unload, passes. pendingLoad and pendingSwap wait until a load that should not happen has either happened or given up (M9 to M11).
  • Removed settle() calls.
    • Four come after dispose(), where the aborted download rejects in its abort listener and nothing is persisted after disposal.
    • Two come after setContextSize(), which begins the reload swap, or records the pending size, before it returns. The phases autorun sees a new swap synchronously.
    • One comes after a start whose stored replace record is dropped. The operations come from _restoreOperations, which runs synchronously at the end of initialization.
    • One comes after the consent outcome reaches the status. The download count is final by then.
    • One comes after a cancel during the first load. _pauseByUser persists the record synchronously.
  • The prune wait. _completeAcquisition awaits pruneOwnedVersions before _removeOperation. So the preceding wait for "no operation" already implies that the old version directory is gone. versions: ['2'] stays asserted.
  • The update test now waits for the drain itself (phase === 'draining' && !!active.drain). Waiting only for the provider's draining phase resumes before the supervisor's queued _doStop publishes stopping.
  • pollUntil currently never advances in the two shim tests. whenStatus resumes before the spawned server's record write completes, so the tests release the server before its first health check. It still advances whenever a poll is pending, and M5 shows the same mechanism is required in the supervisor probe tests.
  • The remaining setImmediate, in FakeLlamaSpawner.spawn, defers behavior until the supervisor has attached its listeners. It is a one-shot deferral, not a wait.
  • Shared fakes. FakeClock is shared with copilotRequestHandler.test.ts, routeTable.test.ts and an integration test. The whole folder passes: 276 passing, 1 pending, which is a Windows-only test.skip.
  • Assertions. All scenarios and assertions are kept. afterAnHour and whileDraining gain timersRun, and afterIdleTimeout now also lists the telemetry events.
  • Overlap. The hunk of agentHost: Forward client certificates to WSL and local containers #343431 in shimLocalModelProvider.test.ts applies on top of this change with a 23-line offset.

There are no product-code changes. The extended rule (agents/no-timeout-polling-rule-v2) has not landed, and eslint.config.js has no exclude entries for these files.

Validation

The change was rebased onto 53b7b19, the live tip of main. None of the 10 commits since eeedb17 touch these files, the shim product code or the rule. The machine was shared, so load averages (1, 5 and 15 min) are given with each timed run.

  • Baseline on eeedb17, ./scripts/test.sh --run src/vs/platform/agentHost/test/node/localModelBridge/serverSupervisor.test.ts --run src/vs/platform/agentHost/test/node/localModelBridge/shimLocalModelProvider.test.ts --run src/vs/platform/agentHost/test/node/localModelBridge/servingAccessImpl.test.ts: 103 passing, 0 pending, 6 s Mocha time, 19 s wall, load 18.4 rising to 22.6.
  • git grep -n "settle\|waitFor\|setImmediate" -- src/vs/platform/agentHost/test/node/localModelBridge/:
    • Before: 162 lines, with 105 waitFor( calls, 27 settle( calls, the two helper definitions and 3 setImmediate.
    • After: 55 lines, with no settle( or waitFor( calls and 1 setImmediate, the spawn deferral.
    • The other matches are waitForState, and the words "settled" and "settles" in copilotRequestHandler.test.ts, modelCatalog.test.ts and these files.
  • npx eslint --rule '{"local/code-no-timeout-polling-loop": ["warn", {"exclude": []}]}' <the five changed files>: 0 problems before and after, because the current rule cannot see these waits. I also applied the in-progress v2 rule from agents/no-timeout-polling-rule-v2 temporarily. It reports 2 warnings on the original fakeLlamaServer.ts (settle and waitFor) and none on the changed files.
  • 10 runs on cef3bbc, for i in $(seq 10); do ./scripts/test.sh --run <the three files> 2>&1 | grep -E 'passing|failing'; done: 10/10 with 103 passing. Mocha time was 2 to 4 s and wall time 4 to 6 s, at a 1-minute load of 4.6 to 5.5. An earlier batch on the change before its last three edits (the idle check, the serving waits and moving RecordingSupervisor) also passed 10/10, with Mocha time of 3 to 19 s while other sessions raised the 1-minute load from 8 to 35.
  • Under CPU load with 18 yes processes, lockf -t 3600 /tmp/vscode-no-timeout-polling-stress.lock bash -c 'pids=(); for i in $(seq 18); do yes > /dev/null & pids+=($!); done; ./scripts/test.sh --run <the three files> 2>&1 | grep -E "passing|failing"; kill "${pids[@]}"':
    • cef3bbc: 103 passing twice. Mocha time was 27 s and 21 s, wall time 37 s and 35 s, and load rose from 5.4 to 22.3, then from 22.3 to 27.9.
    • For comparison, on the change before its last three edits, at load 32 to 40: the new tests had 103 passing twice (37 s and 16 s Mocha time). The original tests had 103 passing twice (20 s and 16 s Mocha time, 51 s wall each). There was no meaningful difference at this load.
  • Mutation checks. Each was applied by a script and run with --grep on the three files, then restored from a backup, with the diff hash checked after each. They ran before the rebase. The code they touch is the same in cef3bbc, except M7, M7b, M15 and M15b, which ran after the last edits.
    • M1, supervisor state: without the drain wait, "a user stop completes when the last running response ends …" fails with drainedStreams: 0 instead of 1.
    • M2, provider status: without the ready wait after turning Use in Auto on, the Auto test fails with spawns: 1 instead of 2.
    • M3, fake downloader: with whenRequested never completing, "model A keeps serving while B downloads …" hits the Mocha timeout.
    • M4, fake runtime: with listDevicesHeld never completing, both preparation tests hit the Mocha timeout.
    • M5, fake clock: with whenTimerDue never resolving, both supervisor tests that use driveProbeRetries hit the Mocha timeout. The two shim pollUntil tests still pass (see above).
    • M6, negative check in virtual time: with user drains given the system drain timeout, "a user stop drains with no timeout …", "concurrent swap requests share one operation …" and "update: a newer build …" fail with timersRun: 1. With the original tests, the update test passes under this mutation.
    • M7 and M7b, idle unload: with the idle unload ignoring holds (_onUseReleased, _armIdle, its callback and _doStop), the hold test hits the Mocha timeout at its later drain wait. The original test does the same. With only the timer armed while held, and the unload still refused (M7b), the test passes.
    • M8a and M8b, record and lock work: with dispose() deleting the record and releasing the lock at once, the dispose test fails with record: false, lockFree: true. Without the waits after the exit (M8b), it fails with the record present and the lock held.
    • M9, stale load: with a cancelled preparation no longer treated as superseded (the superseded() guard and the plan's signal removed), "cancelling a swap while its load is still being prepared …" fails: example-coder spawns and the server is ready. The original test also fails, with the server starting. "a load still being prepared never overtakes a swap" passes under this mutation, because the active-family check and the supervisor's refusal to replace a server with running responses still hold.
    • M10, swap: with the device check removed from _startActive, the device change test fails with server: 'error' instead of 'stopped'. The original test hits the Mocha timeout.
    • M11, Auto: with Auto sessions ignoring Use in Auto, the Auto test fails with spawns: 2, server: 'ready'. The original test passes.
    • M12 and M12b, provider stop: with lastStop never settling, "with Use in Auto off …", "publishes the load step …" and "a load still being prepared …" hit the Mocha timeout. With whenStopped waiting only for the status (M12b), the same three tests time out, because the provider still refuses the next load.
    • M13, raceTimeout: with a crash no longer ending the drain, the crash test fails after 2 s with outcome: 'pending'.
    • M14: without await child.exited, the crash test still passes. That wait orders the scenario, so that the exit is handled before the clock advances, but it does not decide the result.
    • M15 and M15b, serving access: with ensureStarted deciding one microtask later, both serving tests pass. With the same change and the new wait removed from the load-deadline test (M15b), that test hits the Mocha timeout.
  • lockf -t 3600 /tmp/vscode-no-timeout-polling-typecheck.lock npm run typecheck-client on cef3bbc: no errors in the changed files. It reports 20 errors in untouched files, because the shared node_modules predates two recent pins: 19 fusionTier errors in Copilot SDK consumers, and 1 setParentWindow error in terminalProcess.ts from Parent the ConPTY console window to the VS Code window #342784.
  • npm run eslint -- <the five changed files>: no problems.
  • Self-review with the code-review skill: it moved RecordingSupervisor away from the lines agentHost: Forward client certificates to WSL and local containers #343431 changes, and found no other actionable defects.

…ridge tests

Remove settle() and waitFor() from fakeLlamaServer.ts, which yielded to
setImmediate a fixed number of times or until a predicate held. Status and
supervisor-state waits use waitForState; the fake downloader and runtime
complete deferreds; health-poll loops advance the fake clock only when a poll
is pending; the dispose test awaits the supervisor's record and lock work; and
negative checks await the provider's in-flight load or swap, or assert that
no fake-clock timer ran.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings October 23, 2026 08:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

The test-only replacements align with the relevant completion ordering, with no unresolved correctness issues identified.

No open issues 🎉

What changed in this PR

This test-only follow-up to #342698 replaces polling and fixed event-loop waits in the Agent Host local model bridge tests with explicit completion signals. No product code changes are included.

Changes:

  • Await observable state, operation promises, and fake download or runtime signals.
  • Extend the fake clock with timer notifications and execution counts to make timeout assertions deterministic.
  • Remove obsolete polling helpers while preserving test scenarios and strengthening negative checks.

No actionable findings remain.

File Description
src/​vs/​platform/​agentHost/​test/​node/​localModelBridge/​shimLocalModelProvider.test.ts Synchronizes provider tests with status, download, load, swap, and stop completion.
src/​vs/​platform/​agentHost/​test/​node/​localModelBridge/​servingAccessImpl.test.ts Waits for load deadlines to be armed before continuing.
src/​vs/​platform/​agentHost/​test/​node/​localModelBridge/​serverSupervisor.test.ts Uses state and lifecycle signals; strengthens drain and idle assertions.
src/​vs/​platform/​agentHost/​test/​node/​localModelBridge/​fakeServingAccess.ts Adds pending-timer notifications and counts executed timers.
src/​vs/​platform/​agentHost/​test/​node/​localModelBridge/​fakeLlamaServer.ts Removes the fixed-turn and predicate-polling helpers.

Review effort: Balanced

@alexdima
Alexandru Dima (alexdima) merged commit 9e0b704 into main Oct 23, 2026
60 checks passed
@alexdima
Alexandru Dima (alexdima) deleted the agents/no-timeout-polling-local-model-bridge branch October 23, 2026 13:32
@vs-code-engineering vs-code-engineering Bot added this to the 1.144.0 milestone Oct 23, 2026
Pulkit Jain (pulkitjain26) added a commit to pulkitjain-org/vscode-gemini-cli that referenced this pull request Oct 29, 2026
…ler surface (#126)

* Improve Fusion Display in Model Picker with Recommended Badge (#343782)

Agent Host changes for agents/improve-fusion-display-model-picker

* agentHost: await real signals instead of polling in the local model bridge tests (#343737)

Remove settle() and waitFor() from fakeLlamaServer.ts, which yielded to
setImmediate a fixed number of times or until a predicate held. Status and
supervisor-state waits use waitForState; the fake downloader and runtime
complete deferreds; health-poll loops advance the fake clock only when a poll
is pending; the dispose test awaits the supervisor's record and lock work; and
negative checks await the provider's in-flight load or swap, or assert that
no fake-clock timer ran.

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

* agentHost: await debug-log artifact expiry instead of polling the temp folder (#343723)

The collector's lease timer removed an expired artifact with an fs.rm
that nothing kept or signalled, so "expires an abandoned artifact"
polled readdir every 5 ms, up to 100 times. AgentHostDebugLogsCollector
now fires onDidExpireArtifact once that removal has settled, and the
test awaits it before checking the folder. The test file is removed
from the code-no-timeout-polling-loop exclude list.

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

* sessions: stabilize and toggle the default PR activity action (#343787)

* sessions: stabilize and toggle the PR activity bar action

Avoid repeating opener lookups for presentation-only reference changes and retain confirmed PR support during capability revalidation. Restore side-pane toggling and remove the Issue activity action while preserving its composer pill.

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

* sessions: show the PR activity action without a separate setting

Remove the PR-specific enable setting, command, and context-menu item. Show supported chat PRs automatically alongside other activity actions and update accessibility help and regression coverage.

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

---------

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

* ci: run hygiene and ESLint before the compilation checks (#343788)

* ci: run ESLint before the compilation checks

Linting the changed files takes seconds, so running it right after the dependencies install fails lint errors about a minute into the job instead of after the compilation checks. The job takes as long as before, because ESLint already ran on its own after them.

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

* ci: run hygiene with ESLint before the compilation checks

Checking only the changed files takes seconds, so hygiene now runs with ESLint in a Hygiene & ESLint step right after the dependencies install, instead of inside the compilation checks. They run in parallel with --continue-on-error, so a PR with both kinds of errors sees both.

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

* ci: run Hygiene & ESLint right before Compile

The step now runs after the other setup steps, in the same environment the checks had inside the compilation checks. With cached dependencies it still starts about 45 seconds into the job.

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

---------

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

* tasks: assert terminal status directly instead of polling in tests (#343718)

The two poll() calls in taskTerminalStatus.test.ts waited for state that
is updated synchronously when the task event fires: Emitter.fire delivers
to TaskTerminalStatus, which updates the terminal status list in the same
call. Assert each condition right after triggerStateChange and remove the
unused timer-based poll helper.

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

* agentHost: await real signals instead of hidden polling waits in agent host tests (#343728)

Replace waits for state that the timeout-polling lint rule cannot see:
setImmediate tick loops in claudeAgent.test.ts, a setInterval waiter in
claudeProxyService.test.ts, a read-and-retry loop in agentService.test.ts,
and a setTimeout(0) loop plus two microtask-spinning helpers in
agentHostProtocolClient.test.ts. Each test now awaits the operation it
waited for: the agent's bootstrap model refresh, the models observable,
the fake SDK's recorded calls, deferreds completed by the tests' stubs,
the configuration service's root-config write, or the transport's sends.

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

* Note when to remove the WebM Media Source fallback

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

* Fix focusability of empty chat pills row when no user-hidden pills exist (#343800)

Agent Host changes for agents/focusable-empty-div-issue

* Bound the WebM Media Source fallback's reads

Stream the file instead of reading it at once: stop at the first bytes when it is not WebM, and give up above 200 MB. This only applies after normal playback has already failed, so videos that play natively are unaffected.

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

* Enable automatic retries for failed Electron unit test files (#343798)

Enable failed-file retries for Electron unit tests in PR CI

Rerun failed test files up to twice in fresh renderer processes, retain per-attempt results, and report recovered files as flaky.

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

* sessions: Simplify Remotes management UI (#343810)

Remove the address column and description, omit empty search groups, add section help actions, and reveal right-aligned row actions on hover or keyboard focus. Show offline environments as Offline and use a spinner during refresh. Hide redundant environment entry Manage submenus when the management dialog is available.

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

* Align agent session harness icon (#343803)

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

* sessions: offer Canvas in the Session Activity Bar when the chat has no canvases (#343805)

* sessions: offer Canvas in the Session Activity Bar when the chat has no canvases

Without live canvases, the Session Activity Bar's Canvas entry now lists the same canvases that can be opened or reopened as the empty editor group's Add Tab list, instead of being hidden.

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

* sessions: describe the empty Canvas entry in the Session Activity Bar help

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

---------

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

* automations: refine cloud repository ownership UX (#343789)

* automations: refine cloud repository ownership UX

Clarify repository selection and ownership eligibility, centralize dialog feedback, and keep loading and error states adjacent and accessible.

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

* automations: address repository eligibility review

Keep repository privacy, general authorization, and ownership checks consistent across search, account changes, and dialog accessibility.

* automations: format dialog mobile caption

* automations: address ownership accessibility review

* automations: restore provider specification

Remove dialog-specific behavior from the Copilot Chat provider specification.

* automations: defer repository ownership validation

Let creation report unsupported ownership while preserving existing public targets. Restore list focus before disabled-row hover hides row actions.

* automations: preserve error notification outline

* sessions: Preserve management for hosts missing from Remotes (#343821)

Only suppress per-host Environment picker actions for configured connection types represented in Remotes. Keep WebSocket, Dev Container, and unknown host management available, with regression coverage and accessibility help.

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

* build: retry npm ci in the Release stage (#343661)

The Release stage runs after ApproveRelease, so a transient registry error
in its npm ci fails the release itself. That happened twice in 90 days
(477747 on main and 478020 on release/1.140, npm EPERM fetching zx).

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

* build(deps-dev): bump markdown-it from 14.3.2 to 14.3.3 (#343058)

Bumps [markdown-it](https://github.com/markdown-it/markdown-it) from 14.3.2 to 14.3.3.
- [Changelog](https://github.com/markdown-it/markdown-it/blob/14.3.3/CHANGELOG.md)
- [Commits](https://github.com/markdown-it/markdown-it/compare/14.3.2...14.3.3)

---
updated-dependencies:
- dependency-name: markdown-it
  dependency-version: 14.3.3
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Raymond Zhao <7199958+rzhao271@users.noreply.github.com>

* build(deps): bump markdown-it from 14.3.2 to 14.3.3 in /extensions/extension-editing (#343014)

build(deps): bump markdown-it in /extensions/extension-editing

Bumps [markdown-it](https://github.com/markdown-it/markdown-it) from 14.3.2 to 14.3.3.
- [Changelog](https://github.com/markdown-it/markdown-it/blob/14.3.3/CHANGELOG.md)
- [Commits](https://github.com/markdown-it/markdown-it/compare/14.3.2...14.3.3)

---
updated-dependencies:
- dependency-name: markdown-it
  dependency-version: 14.3.3
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Raymond Zhao <7199958+rzhao271@users.noreply.github.com>

* Engineering - fetch crates without HTTP/2 multiplexing and retry cargo steps (#343397)

* Engineering - fetch crates without HTTP/2 multiplexing and retry cargo steps

The ADO Cargo feed intermittently cancels HTTP/2 streams ("[92] HTTP/2 stream
... CANCEL"), which failed the CLI lint or compile in 487876, 487749, 478647
and 481284 after cargo's own retries. Disable multiplexing and raise cargo's
retries on every cargo step of the CLI and Copilot shim, and retry the step on
top, except the shim tests.

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

* Engineering - pass the cargo network settings as --config flags

sccache hashes every CARGO_* environment variable into its Rust compile
keys, so setting CARGO_HTTP_MULTIPLEXING and CARGO_NET_RETRY on the cargo
steps turned every sccache lookup into a miss (0 Rust hits in build 487885,
against ~225-290 on main). Cargo doesn't pass --config values on to rustc,
so the compile keys stay the same as on main.

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

---------

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

* Agents window: ignore config changes from other sessions in pickers (#343836)

The new-session composer's pickers re-rendered on onDidChangeSessionConfig
for every session of every agent host provider. When a background session
churns its config (for example the sensitiveEditLocations ping-pong in
#341595), the New Worktree, branch, and mode/permissions chips are rebuilt
hundreds of times per second, so a mouse click's mousedown target is
detached before mouseup and Chromium never dispatches click.

Only re-render for the session each picker shows, and only refresh the
repository menu items for visible sessions.

Refs #341595

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

* sessions: fix lightbulb in remote isolation picker (#343840)

Handle the host's workspace isolation value in the shared icon helper so dropdown rows, triggers, and mobile sheets use the same folder icon.

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

* agentHost: Use normal tool approval for set_artifact_automation (#343826)

Turning on artifact automation through the agent no longer asks a separate
in-chat question that tool auto-approval cannot answer. It now follows the
current tool-approval policy like run_artifact_action, so Allow All and
Autopilot apply it directly, and interactive approval shows the artifact and
requested option values.

Removes the now-unused server tool confirmation infrastructure and lets the
agent use the tool when automation serves the user's request.

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

* sessions: show artifact state lists collapsed by default (#343802)

* sessions: show artifact state lists collapsed by default

Artifact details now open with every state list collapsed. Activating a tab expands its list, and activating the expanded tab collapses all lists again, so no tab is active. While collapsed, the tabs are separated by a divider, arrow keys only move focus, and the expanded or collapsed choice is still remembered per artifact.

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

* sessions: focus the reachable tab in the artifact keyboard-focus fixture

With state lists collapsed by default, no tab is selected, so the fixture now focuses the keyboard-reachable tab instead.

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

---------

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

* Improve worktree cleanup progress, preservation, and leftover-folder handling (#343676)

* sessions: inherit editor session harness icon color (#343822)

Inherit editor session harness icon color

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

* sessions: make environment-first selection the default (#343843)

Remove the environment-first ordering setting and always keep Environment before Workspace when the picker is enabled. Remove local isolation choices from Environment while preserving the repository isolation picker.

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

* sessions: enable model comparison by default (#343844)

Enable sessions.chat.compareAgents.enabled starting with VS Code 1.144.0.

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

* chat: hide Add Models while comparing agents

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

* sessions: remove environment picker icon-only setting (#343852)

Keep picker labels as the default and preserve per-profile Collapse to Icon choices from the context menu. Remove the retired experiment trigger and update persistence coverage.

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

* Add proposed GitHub API for profile gist sharing (#343432)

Expose disposable GitHub clients through the extension API and migrate Configuration Editing gist import/export to the shared service. Narrow gist contracts, reuse schema parsing helpers, and document the current service architecture.

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

* Use SDK-owned Copilot marketplace installation records (#343596)

* Use SDK-owned Copilot marketplace installation records

Replace the marketplace provider's client plugin inventory dependency with a typed provider-owned installation inventory. Preserve direct-source identities, catalog associations, session routing, and SDK transaction completion without client discovery waits.

Related to #343342.

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

* Harden SDK marketplace installation records after review

Reject ambiguous and undisambiguated direct uninstall identities, precompute catalog match counts, and validate optional SDK plugin icons as credential-free HTTPS URLs. Add focused regression coverage.

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

---------

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

* chat: track successful /btw submissions (#343856)

Emit a dedicated adoption event for the silent command without collecting prompt or context data. Cover successful submissions in both windows and exclude invalid, failed, and non-command side chats.

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

* Add ellipses to migration action labels (#343860)

Fixes #342655

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

* sessions: align remote environment workspace pickers (#343867)

Use folder icons and a leading Open Folder action for the selected remote environment. Add ellipses to remote connection picker entries and cover label deduplication when the workspace is selected first.

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

* Open migrations from Customizations when needed (#343862)

Open migrations from the Customizations button

When the Agents window signals that customization migrations need attention, route the Customizations entry directly to the migration dashboard. Preserve the regular overview behavior after the migration state clears.

Fixes #341797

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

* Enable automatic retries for failed Node.js unit test files (#343842)

* Enable automatic retries for failed Node.js unit test files

Rerun failed Node.js unit test files up to twice in fresh processes in PR CI, matching the Electron runner. Report recovered files as flaky and reject abnormal process exits even when a passing report was written.

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

* Preserve Loader checks across Node.js test file retries

Forward the initial Loader-check policy to retry processes independently of their --run selection. This prevents a full-suite retry from passing when a file writes to stderr while loading, without changing targeted-run behavior.

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

---------

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

* Show locations for installed plugins in Chat Customizations (#343869)

chat: show locations for installed plugins

Show every installed plugin's location instead of a marketplace description, using the middle-ellipsis path label shared by other customization lists. Installed plugin search also matches locations.

Fixes #341736

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

* Resolve empty agent skill inventories (#343722)

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

* chat: add correlated cloud sandbox lifecycle telemetry (#343708)

* chat: add correlated cloud sandbox lifecycle telemetry

Record content-free client lifecycle observations with environment, task, session, connection and turn correlation. Preserve existing aggregate metrics and distinguish shared context, cancellation, readiness and missing evidence.

Add focused coverage for identity privacy, reconnect attribution, preparation cleanup, diagnostic retention and protocol compatibility.

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

* chat: make sandbox lifecycle failures actionable

Add allowlisted failure locations, bounded credential retry observations and protocol state at failure without uploading rejection text, arbitrary error types or stacks. Distinguish routine credential acquisition from recovery and preserve existing aggregate metrics and network behavior.

Cover privacy validation, recovery decisions, late HTTP failures, current-transport response age and service wiring with focused regressions.

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

* chat: exclude user-local credential lifecycle telemetry

Carry local environment kind through credential minting and refresh paths, suppressing user-local lifecycle observations at serialization without changing aggregate metrics or network behavior.

Validate all lifecycle text categories against runtime allowlists and cover user-local suppression, scope forwarding, payload privacy and preserved request behavior with regression tests.

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

---------

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

* chat: avoid redundant checkouts for pinned plugin clones (#343559)

Check the cloned HEAD before repeating a pinned checkout. Retain commit verification for mismatches and preserve cached-repository checkout behavior.

Follow-up to #343514.

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

* Keep SDK marketplace add progress and errors in quick input (#343509)

* Fix plugin source installs for Copilot Agent Host

Route source installs through the active harness's management provider instead of modifying VS Code plugin locations. Preserve existing behavior for other harnesses and cover SDK routing, source formats, and failures.

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

* Address plugin installation review feedback

Gate native source installation on management API support, resolve the target harness at submission, and keep the input title synchronized with the selected harness. Add capability and harness-switch regression tests.

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

* Keep SDK marketplace add progress and errors in quick input

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

* Add marketplace command and browsing actions

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

---------

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

* agentHost: update bundled Codex SDK to 0.163.0 (#343717)

* agentHost: update bundled Codex SDK to 0.163.0

* agentHost: remove resolved Codex MCP expected failure

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

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
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: Giuseppe Cianci <gcianci@microsoft.com>

* Honor windowsReparentConsoleWindow when terminals relaunch (#343877)

Relaunching a terminal reuses its process manager, which sent the window
handle it saved before the setting changed. Check the setting each time a
process starts, keep tracking the terminal's window while the setting is
off, and forget the saved handle when the window changes.

* Show progress for customization migrations (#343884)

Show one progress notification for each confirmed migration batch and identify the active migration in the dashboard. Apply the same feedback to prompt, user-data, configured-location, MCP server, and plugin marketplace migrations.

Fixes #342542

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

* chat: use MCP authentication notifications in screen reader mode (#343893)

Fixes #343890. Preserve inline hints outside screen reader mode and keep authentication notifications actionable across turns, with cleanup when no longer needed.

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

* issueReporter: simplify the form and add a dedicated window (#343634)

* issueReporter: simplify reporting into a single-page form

Replace the wizard steps with Write/Preview, ordered file attachments, visible optional diagnostics, and a configurable reporter window.

Preserve attachment bytes and ownership, clarify upload failures, and reveal auxiliary windows after styled layout without losing initial focus.

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

* issueReporter: isolate the reporter window and simplify text input

Share reporter behavior between the editor host and a dedicated native window without workbench chrome or command leakage.

Use a padded native description field with Write/Preview and retain its undo state across editor tab switches. Preserve native editing, attachment ownership, source-window capture and guarded close behavior.

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

* issueReporter: address review feedback and CI failures

Protect standalone drafts during shutdown, cancel submissions on discard, and transfer controller ownership without leaving stale capture controls.

Preserve attachment MIME types and filename suffixes, restore reporter-only zoom, and fix cross-platform native-menu tests and Markdown table escaping.

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

* issueReporter: preserve menu shortcuts and capture chord state

Use guarded standalone menu commands instead of stale native close and undo roles, and keep normal source accelerators registered on Windows and Linux.

Complete intercepted capture chords through the keybinding dispatcher so ordinary typing and IME state recover immediately.

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

* issueReporter: reduce shared infrastructure changes

Keep window and tab modes while accepting native undo reset on tab switches and the classic reporter's native-menu limitations. Remove the editor DOM retention, platform menu mode and private zoom relay.

Scope stylesheet-ready reveal to the reporter and reduce close ownership to one asynchronous callback, checking vetoes before discarding content.

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

* issueReporter: keep the selected description mode visible

Mark Write and Preview selection with a theme-aware underline and semibold label without competing with Button's inline colors and borders.

Cover persistent selection after focus changes with dark, light and high-contrast token values.

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

* issueReporter: reuse close veto only for edited drafts

Remove the shared auxiliary close hook and use the existing veto flow. Preserve drafts until actual unload or committed shutdown, cancel old submissions separately, and avoid vetoing shutdown after failed initialization.

Track title and description changes against their defaults, ignore untouched prefills and automatic templates, and protect added or pending attachments.

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

* issueReporter: fix recording uploads and copy error details

Send bare MIME types to GitHub's upload policy instead of forwarding recorder codec parameters, while preserving attachment metadata and bytes.

Make technical error details selectable and add an accessible Copy action with clipboard error handling and regression coverage.

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

* issueReporter: restore native text editing shortcuts

Handle resolved undo, redo and select-all commands inside the standalone form instead of relying on native browser defaults after workbench dispatch is isolated. Preserve native history and keep source-window editors untouched.

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

* issueReporter: check selectable error details across browsers

WebKit exposes text selection through -webkit-user-select. Check the computed standard or prefixed property without weakening the assertion or changing the reporter UI.

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

* issueReporter: use literal native text editing commands

Keep undo, redo and select-all behavior unchanged while making the permitted execCommand calls explicit for the tsec safety check.

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

---------

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

* Focus primary action instead of back button in customization detail pages (#343889)

chat: focus primary action instead of back button on customization detail pages

Opening a customization detail page (e.g. a migration item) focused the
back button, and the managed hover then showed its "Back to ..." tooltip
on focus. Detail pages now focus their enabled primary action (Migrate,
Install, Connect), then a visible editor, then the back button with its
tooltip suppressed. Focus rings on detail header controls only show for
keyboard navigation.

Fixes #342645

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

* sessions: fix remote Copilot presentation and draft visibility (#343887)

* sessions: fix remote Copilot presentation (Written by Copilot)

Hide runtime bootstrap controls without changing host configuration, recognize the Copilot provider icon, and keep default chat titles aligned with session titles.

Keep locally owned unsent drafts out of saved-session discovery and caches while preserving eager initialization. Publish accepted sends even if the later handoff fails.

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

* sessions: retain drafts through peer activity (Written by Copilot)

Keep owned eager drafts suppressed through delayed discovery responses. Publish them after a host-observed turn and preserve sessions and detached worktrees used by another controller when the local draft is discarded.

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

---------

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

* sessions: fire the cloud commit once the provider listens (#343720)

The cloud commit test re-fired onDidCommit every 5 ms until sendRequest
settled, because _waitForCommittedSession subscribes only after the send
resolves. Complete a deferred from the emitter's onDidAddFirstListener hook
and fire the commit once after it. The response still completes before the
commit.

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

* Add tool set and chat participant migration guidance (#343882)

* chat: add participant and tool-set migration guidance

Show extension chat participants and explicit tool sets as read-only migration entries with Learn More links. Include guidance in migration counts and Ignore/Restore without adding it to executable migration candidates.

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

* chat: fix migration guidance formatting

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

* chat: add review details for tool set and participant migrations

Opens tool-set and chat-participant migration guidance in a detail page that
matches the other migration details: an arrow back button, a linked source,
and a warning card with descriptive guidance links. Labels extension-owned
items as Extensions and links directly to the relevant docs sections.

Refs #341362

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

* chat: add migration guidance dashboard fixture

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

---------

Co-authored-by: Harald Kirschner <hkirschner@microsoft.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: digitarald <8599+digitarald@users.noreply.github.com>

* mcp: verify local servers after the latest startup scan (#343920)

At startup, two local MCP server scans run at the same time. An old scan
could start a registry sync before the newest scan had stored its servers.
The newest scan did not start a sync, so in registry-only mode the local
servers stayed unverified and disabled until mcp.json changed.

- Start a registry sync after each accepted local scan, and not after a
  query promise completes.
- Remove the separate syncs after the initial query and after a profile
  reset. The accepted scan now starts the sync.
- Register the gallery manifest listener in the constructor, so that a
  registry status change during startup is not missed.
- Add regression tests for both scan completion orders and for a
  registry status change before the initial query completes.

Fixes https://github.com/microsoft/vscode/issues/343589

(Commit message generated by Copilot)

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

* Fix Browse customization creation flows (#343921)

Reuse section creation actions for file customizations, MCP servers, and plugins instead of forcing AI generation or only navigating to a page. Preserve cancellation and disabled-state behavior and document the flow in accessibility help.

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

* agentHost: adopt Universe Copilot SDK build (#343916)

agentHost: adopt Universe Copilot SDK build (Written by Copilot)

Pin SDK 1.0.27-unstable.39903661716.gbccf8a3 and runtime 1.0.103-unstable.r39903661716.gbccf8a3 in desktop and remote dependencies. Refresh the managed-model schema description for the Fusion alias.\n\n(Written by Copilot)

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

* agentHost: remove cached agent SDK versions that are no longer used (#343281)

* agentHost: remove cached agent SDK versions that are no longer used

Each Claude/Codex SDK version is cached under
<userData>/agent-host/sdk-cache/<sdk>/<version>/<target> (200-400MB each)
and was never removed, so every SDK bump left the previous version behind.

Shortly after agent host startup, delete cached versions that this build
doesn't request and that no process has used for a week, plus scratch dirs
of interrupted downloads. A cache hit refreshes the mtime of the version's
.complete sentinel at most hourly, which is how processes sharing the cache
(remote servers of different versions) keep a version alive. Versions are
renamed before deletion so a version in use on Windows is never half-deleted.

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

* agentHost: clean up interrupted SDK downloads in every kept version

Address review feedback: remove stale <target>.tmp.<pid> scratch dirs in every
cached version that is kept, not only the requested one; catch the scheduled
cleanup's promise; capture the time once in the last-use test.

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

---------

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

* sessions: fix blank harness picker with environment selection (#343956)

sessions: hide the harness picker when no types are available

Hide the entire picker slot when environment filtering leaves no harnesses, so options-row styles cannot expose an empty trigger. Restore the labeled picker when types become available.

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

* agentHost: retain encryption keys after authentication (#343970)

agentHost: retain relay encryption keys (Written by Copilot)

Preserve listener-owned metadata when projecting authenticated root subscriptions so provider and MCP credentials can still be sealed after the initial handshake. Cover hosts with and without listener extensions without mutating shared host state.

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

* chat: preserve Browse cards on unchanged installation updates (#343923)

* chat: preserve Browse cards on unchanged installation updates

Only rerender Browse after a displayed customization's installation state changes. Keep cards and keyboard focus intact during unrelated background MCP and installation notifications, while preserving real installation updates and search refreshes.

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

* chat: compare Browse installation URIs by value

Use resource equality for installation target URIs and setup URLs so equivalent inventory snapshots preserve Browse cards and focus. Cover skill/plugin target refreshes, changed targets, and setup URL actions.

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

---------

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

* sessions: retry cleanup of archived session worktrees (#343924)

* sessions: retry cleanup of archived session worktrees

Expose authoritative host cleanup status and reported errors in Worktree Cleanup. Allow manual retries without restoring sessions or deleting their history, preserving shared-worktree and archive safety checks.

Fixes #343922

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

* sessions: preserve worktree cleanup progress across refreshes

Keep pending cleanup status through transient host errors and cache accepted retry outcomes so polling resumes correctly. Preselect archived worktrees unless removal failed, and fix cleanup editor formatting.

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

* sessions: group worktrees unavailable for cleanup

Keep actionable worktrees first and explain unavailable worktrees in a collapsed section without disabled checkboxes. Preserve visible progress for requested cleanup and cover grouping, filtering, and status transitions.

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

* sessions: fix cleanup status label type narrowing

Pending cleanup already implies an archived session, so exclude eligible rows directly before rendering status labels.

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

---------

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

* Fix keyboard focus and text selection in customization modals (#343858)

* Trap focus and allow copying in customization modals

Keep Tab and Shift+Tab within modal editor boundaries and make all embedded customization details selectable. Fixes #314168.

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

* Preserve modal editor Tab commands

Keep equal positive tab indices in DOM order and defer to active editor or widget Tab keybindings before wrapping modal focus.

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

---------

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

* Apply the organization's managed default permissions to new agent sessions (#343925)

Fixes https://github.com/microsoft/vscode-internalbacklog/issues/10280

Admins can set `permissions.defaultMode` (`manual`, `assisted` or `allow-all`) in Copilot managed settings, but VS Code ignored it. In the Agents window, a remembered permission pick also overrode the admin default. With this PR, the organization's default is the starting permission level for new agent sessions in both the Editor and the Agents window, the same way the managed default model works:

- **The org default wins** over the user's remembered pick and their `chat.defaultConfiguration.approvals`. The user's `mode` still applies, and users can still change permissions within a session as the policy allows.
- **Settings shows "Managed by organization"** on `chat.defaultConfiguration` and describes the org default.
- **Permission pickers show an Org default badge** on the matching level. Screen readers announce it.
- **Disallowed modes fall back to Manual.** This happens when the admin sets Assisted or Allow All as the default but also disables it.

VS Code reads these managed keys through a new `ChatDefaultConfiguration` policy on `chat.defaultConfiguration` and merges it per property. That way an approvals-only policy keeps the user's `mode`. The runtime's own enforcement doesn't change.

## How to test

1. Put `{"permissions": {"defaultMode": "assisted"}}` in the Copilot managed-settings file.
2. In the Agents window, pick Manual, then start a new session. It should start on **Assisted**, with **Org default** shown on Assisted in the picker.
3. Set `chat.defaultConfiguration` to `{"mode": "plan", "approvals": "manual"}`. A new Editor session should start in Plan mode with Assisted permissions, and Settings should show the setting as managed.

---

*🤖 Authored with GitHub Copilot on behalf of @rwoll.*

* agentHost: update client tools without restarting sessions (#343980)

Update Copilot client tools in place when session initialization data stays the same.

- Replace client tool definitions and handlers through the SDK setTools API.
- Compare applied initialization data before a live update or required restart.
- Keep customization scopes stable across turns and client tool changes.
- Compare discovered resource URIs without their mutable serialization caches.
- Add restart diagnostics and tests for tool updates, routing, and scope isolation.
- Use a short-lived Set to track ancestors during stable serialization.

(Commit message generated by Copilot)

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

* workspaces: preserve remote Windows folder trust (#343931)

* agentHost: preserve remote Windows workspace trust

Normalize agent-host trust URIs across checks and persisted entries so Windows drive-letter casing does not trigger repeated trust prompts. Add regression coverage for reopening, reloads, existing entries, revocation, and trust boundaries.

Regression of #338078.

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

* workspaces: retain Windows folder trust for Remote-SSH

Normalize vscode-remote trust entries as well as agent-host resources so persisted drive-letter casing matches restored folders. Cover both canonical drive-letter spellings while preserving folder and host boundaries.

Related to #289835 and #339479.

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

---------

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

* ci: name the Windows Agent Host E2E job after what it runs (#343914)

The Windows Agent Host E2E caller job was named "Windows (run)". When the
changes cannot affect the Agent Host E2E tests, it is skipped at the caller,
so GitHub shows only that name: a lone skipped "Windows (run)" row with no
"/ Agent-Host-E2E" suffix and no Linux or macOS twin, which looks like a bug.

Rename it to "Windows (agent host)". It now shows as
"Windows (agent host) / Agent-Host-E2E" when it runs and as
"Windows (agent host)" when it is skipped. The required "Windows / Electron"
check is reported by required-checks and does not change.

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

* sessions: Improve Remote Environments entry points (#344031)

Expose Manage Remote Environments in the Command Palette and Sessions overflow, rename the editor, remove code-action tooltips from the environment menu, and left-align inline actions. Preserve the same modal sizing behavior as Customizations and Language Models.

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

* sessions: keep group rename draft across list rerenders (#343774)

* sessions: keep group rename draft across list rerenders

The inline group name editor was recreated from the saved name on every list refresh, discarding what the user had typed. Share the draft/selection/focus restoration used by session and chat renames with the group renderer.

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

* sessions: close reopened group rename editor in test teardown

In browser unit tests the focused editor was blurred on disposal and committed into a groups service mock that lacks renameGroup.

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

---------

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

* sessions: Add Remote Environments picker visibility controls

Layer a profile-local hidden preference over existing provider availability and expose Show/Hide actions without affecting connections or sessions.

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

* sessions: Reflect remote picker eligibility in management

Distinguish unavailable hosts from hidden preferences, share picker eligibility checks, and preserve visibility preferences across registration and availability changes.

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

* sessions: Reveal selected remotes and preserve hidden-host drafts

Unhide explicit remote folder selections without overriding availability, keep existing drafts sendable on hidden connected hosts, and fix CI formatting.

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

* sessions: Keep visibility icons shown and show section refresh progress

Show per-section spinners beside counts until each discovery completes, with cancellation-safe progress and accessible busy state.

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

* sessions: Gate remote visibility and management on its setting

Restore original picker availability when remote management is off, retain saved hidden preferences, and gate the command, overflow entry and open editor.

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

* sessions: Add Environments setup guide action

Link the section info action and empty-state guide to the planned vscode-agent-environments redirect.

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

* agentHost: un-skip the durable workspace transition restart test with a disk I/O budget (#342357)

agentHost: give the durable workspace transition restart test a disk I/O budget

'restores one durable transition before provider output after service restart' was skipped as flaky (#339669). It opens, closes and reopens a real SQLite database on disk, so most of its time is spent in fsync-bound commits. Where the node.js unit tests run with mocha's 2s default (the ADO Flaky Smoke Tests runs), an occasional file system stall on a loaded Linux agent pushes it past the budget. Its SessionDatabase siblings with the same pattern were fixed the same way in #340024.

Un-skip the test with an explicit 10s timeout.

Fixes #339669

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

* sessions: polish cloud automations (#344003)

* sessions: polish cloud automations for Universe

Hide unsupported cloud actions, improve repository ownership recovery, and keep grouping and trigger metadata consistent across visual and accessible presentations.

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

* Engineering - update code owners (#344048)

* sessions: Preserve hidden-host workflows and report discovery failures

Keep automation history and restored remote container destinations independent of picker visibility. Surface per-section discovery failures immediately, including missing tunnel authentication.

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

* sessions: Use a disabled eye for unavailable remote visibility

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

* Engineering - Rerun failed tests in isolation and split integration CI steps (#344036)

Rerun failed tests in isolation and split integration CI steps

Select failed tests and hook suites by title in fresh Electron windows or Node processes, retaining file-level fallback for large failure sets. Keep runner safety checks and per-file pass attribution intact, and report recovered failures as flaky.

Split node and extension-host integration runs so extension-host coverage continues after failures, and enable bounded retries for node integration and Agent Host E2E in pull request CI.

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

* issueReporter: enable the wizard by default (#344049)

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

* Engineering - increase default timeout for flaky test job (#344050)

* distro: enable Copilot Chat proposals for auth issuers and rate limits (#344051)

Picks up microsoft/vscode-distro#1478, which adds the authIssuers and
languageModelRateLimit API proposals to GitHub.copilot-chat in product.json.
The extension already declares both proposals (#337846, #340100), so without
this the workbench logs that product.json enables fewer API proposals than
the extension wants, and built products do not enable the proposals.

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

* agentHost: route offered client tools before replacement settles (#343998)

The runtime can start a newly offered client tool before the setTools
response reaches the host. Previously routing was only committed after
the response, so such a start had no client contributor and its handler
could wait forever.

Stage routing before replacing tools instead: route the union of applied
and offered client tool names, and prefer offered definitions when
resolving the owning client, while replaceTools is in flight. Commit the
offered set on success and restore the applied routing on rejection.

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

* sessions: add row actions to artifact details lists (#343763)

* sessions: add row actions to artifact details lists

Artifact details items can declare actions that run directly through their details lease, like Load More, without the run executor. Lists render them in a floating row action bar that keeps focus and shows per-item progress. The GitHub pull request integration uses this to rerun failed GitHub Actions checks and resolve review comments, hiding resolved threads immediately rather than after the next poll.

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

* sessions: fix Chats section test broken by concurrent main merges

#343746 removed the QUICK_CHATS_SECTION_ID import and the Chats section under date grouping, while #343744 added a capped Chats section test that used both. Restore the import and run that test for the groupings that still have a Chats section, workspace and repository. This fixes the client type check in Compile & Hygiene.

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

* sessions: harden artifact row actions after review

Rerun Check now refreshes and requires current core and check results before running, verifies with GitHub that the linked job is that check's run on the current head, and is only offered when the linked job is the check's own run. Only the list's focused row puts its actions in the tab order, and a focused row action follows its item when the list reorders instead of staying with the reused row.

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

---------

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

* Move webSocketOverDuplex test to Node layer and clean up ESLint config (#344059)

Agent Host changes for lszomoru/agents/investigate-websocketoverduplex-test

* sessions: hide external banner for automation sessions (#344007)

* sessions: hide external banner for automations

Keep automation sessions external for ownership and filtering while suppressing the external-session banner.

* sessions: remove flaky artifact details CommentsInformation fixture (#344062)

The sessions/artifactDetails/CommentsInformation fixture rendered the same
view as the Attention fixture and only added a click-opened instant hover
on the Comments tab information button. That transient hover was captured
inconsistently, so the Light screenshot changed on unrelated PRs.

Remove the fixture and its now-unused tabInfo scenario. The same hover is
still covered by sessions/artifactIntegrations/PullRequestCommentsInformation.

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

* Engineering - fix test module import failure handling in browser runner (#344047)

* Agent Host changes for lszomoru/agents/test-module-import-failure-fix

* Fix browser test dependencies exposed by import failure checks

Replace Node-only events and Buffer usage in the common WebSocket fixture so its tests run in browsers. Move the CommonJS-dependent TextMate fixture suite to the Electron test lane without dropping coverage. Keep module import errors fatal.

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

* Fix browser benchmark imports and drain console logs before cleanup

Use the cross-platform environment helper so the opt-in object mutation benchmark can be imported without a Node process global. Wait for pending console listeners before closing the page so error argument serialization does not race browser cleanup and mask the original import failure.

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

* Use browser-supported strict assertions in terminal escaping tests

The browser assertion shim does not export assert.strict. Import strictEqual directly to preserve strict comparisons while allowing the suite to register in browser runs.

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

* Drop WebSocket test changes superseded by upstream Node move

Keep the relocated test identical to origin/main now that #344059 places its Node-only dependencies in the Node test lane. Preserve the browser runner and remaining compatibility fixes.

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

---------

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

* Automations: graduate settings (#344001)

* Automations: graduate settings

* Engineering - delete test from a previous exploration (#344075)

* sessions: Improve Remotes search and tunnel sign-in

Add inline clear and collapse actions, and offer explicit tunnel permission sign-in instead of a generic discovery error when no usable token exists.

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

* chat: Fix GitHub Feed plugin activation and lifecycle (#344000)

* Fix GitHub Feed plugin activation and installation identity

Persist runtime enablement for direct plugins, activate confirmed catalog installs, and reload live chat contributions. Reconcile Browse rows and uninstall actions using stable installation identity while preserving separate marketplace copies.

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

* Fix formatting in plugin installation UI

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

* Handle plugin activation cancellation and rejected enablement

Await all post-uninstall chat reloads before surfacing errors. Guard runtime enablement against local policy collisions and restore its previous state if the local commit is rejected. Update the MCP test to supply plugin discovery and await the async action, fixing browser and Electron CI.

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

---------

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

* sessions: Center Remotes search field actions vertically

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

* sessions: Show progress beside tunnel sign-in

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

* sessions: Handle GitHub tunnel sign-in cancellation quietly

Normalize GitHub Authentication's documented cancellation results while preserving ordinary authentication listeners and auto-connect behavior.

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

* sessions: Delete user-shared environments from Remotes

Add an inline Delete action without confirmation for user-local registrations. Guard account ownership, invalidate stale inventory, and withdraw local connections after deletion. Fixes #343985.

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

* ci: run only the unit tests a change can affect on macOS and Windows (#342907)

* ci: run only the unit tests a change can affect on macOS and Windows

Adds build/ripple, a Rust change impact engine built on oxc. It maps a
diff to the unit test files it can affect, at the level of individual
declarations, in about a second. A new Plan Unit Tests job runs it on
the pull request's merge commit and uploads the per-runner lists as an
artifact. The macOS and Windows unit test jobs pass them to the test
runners with the new --runList option. Linux still runs every unit
test on every push.

The jobs run every unit test when the plan fails, when the change
reaches outside the module graph (test runners, transpiler, compiler
options, runtime versions), or when it affects more than half of the
unit test work. On last week's 2,184 pull request pushes they would
have run 13.5% of the macOS and Windows unit test work, about 38 VM
minutes less per push.

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

* ci: TEMPORARY plan a fixed main commit to validate the selection path

Revert before merging. This pull request changes the test runners, so its own plan selects every unit test. Planning #342662 instead makes the macOS and Windows unit test jobs download the plan and run 20 Electron, 8 node.js and 12 browser test files with --runList.

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

* Revert "ci: TEMPORARY plan a fixed main commit to validate the selection path"

This reverts commit 9c453973d31. The validation run passed: the macOS and Windows unit test jobs downloaded the plan and ran only the listed files.

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

* ci: plan unit tests in the Detect Changes job

Saves a VM per push. The planning steps run in the existing job, which now needs a depth-2 checkout instead of a sparse one. They never fail the job, so a planning problem only means that macOS and Windows run every unit test, and it never affects the change detection outputs.

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

* ripple: close the selection gaps found in review

- Never list deleted or renamed tests: the runners fail to import them.
- Run every unit test when a change touches the test launchers, the
  transpile and install pipeline, the npm scripts or the job definitions
  the macOS and Windows unit test jobs run.
- Hash each declaration's syntax tree along with its tokens, so changes
  that only move line breaks but change the parse are detected.
- Add a node per exported name, so retargeting an export or re-export
  selects its consumers.
- Detect reordered load-time statements and effectful imports, and make
  mutable module state depend on the load-time code that writes it.
- Print every test from 'ripple affected' when a change runs everything.

On the replayed history, the engine changes leave the selection of the
same commits unchanged (6.79% -> 6.80%); the new triggers make 1.6% of
commits run everything.

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

* ci: warm the ripple cache in its own workflow

main now models pr-node-modules.yml as node_modules cache warming jobs,
and its test rejects any other job, which failed Compile & Hygiene. The
new pr-ripple.yml only runs when ripple changes, and daily in case the
cache was evicted, instead of on every push to main.

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

* ripple: move repository knowledge into vscode.jsonc

The engine now only knows TypeScript, JavaScript, npm and git. What it
knows about this repository is in build/ripple/vscode.jsonc, which every
command reads with --config: the modules and tests, the vs/ path alias,
the files every unit test depends on, the toolchain packages and test
scripts, the globals the test runners inject, and the repository's pure
functions and implicit methods.

- The test runners own their test sets: ripple writes one unit.txt, and
  --runList now runs the tests a runner would run by default, but only
  from the listed files. The browser runner exits without launching a
  browser when none of the listed files are browser tests.
- Remove what CI does not use: product entry points, OS and WebKit
  sensitivity, test keys and the pushes command.
- Changes to ripple or its configuration run every unit test.

On 630 commits of main, the old and new binaries select the same unit
test files and make the same run-everything decisions, and the old
hard-coded file rules match the configuration on every repository path.

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

* ci: download the unit test plan by pattern

Detect Changes only uploads the plan when the selection applies, and a
download by name fails without it, which annotated every macOS and
Windows unit test job with an error when they ran every unit test. A
download by pattern downloads nothing instead, and the unit test steps
now check for plan.json rather than the step outcome.

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

* ci: TEMPORARY plan a fixed main commit to validate the selection path

Revert before merging. This pull request changes the unit test jobs, so
its own plan runs every unit test. Planning #342662 instead makes the
macOS and Windows unit test jobs download the plan and pass its 20 test
files to each runner, which should run 20 Electron, 8 node.js and 12
browser test files.

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

* Revert "ci: TEMPORARY plan a fixed main commit to validate the selection path"

This reverts commit 8e23984bea6. On that run, the macOS and Windows unit
test jobs downloaded the plan of #342662 and ran 20 Electron, 8 node.js
and 12 browser test files in 2 to 4 minutes each.

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

* ripple: follow `this` in static members, and keep member keys unique

- Code reaches a static or object literal member directly (`X.member`),
  without its parent, so `this` and `super` inside it lost their
  dependencies. Changing `MoveCaretCommand.getEditOperations` selected
  no test: the cursor calls it through `CommandExecutor.executeCommands`,
  whose `this._innerExecuteCommands(...)` chain was not followed. Such
  members now depend on the sibling that `this.name` names, or else on
  their class or object.
- A static and an instance member of the same name (`Position.equals`)
  shared a key, so any edit to their file, even a comment, counted both
  as changed: a comment in `Position.isBefore` selected 819 test files.
  Instance members are now keyed `X.prototype.name`, and accessor pairs
  get a suffix.
- `ripple affected` prints the declarations each changed module changed.
- The READMEs compare with the merge base, and show how to include
  uncommitted changes.

On 630 commits of main, the first fix adds 19 test files to one commit,
and the second removes spurious selections from nine (307 -> 24 test
files for one of them).

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

* ripple: reject unknown options and missing option values

The option parser took a missing value as an empty string, consumed the
next option as a value, and ignored unknown options, so `--config` at
the end failed with "cannot read the configuration", `--base --head X`
handed `--head` to git, and the renamed `--lists` silently wrote no
plan. It now fails with a clear message in each case.

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

* ripple: close five selection gaps found in review

Each of these changes could produce a plan that skipped affected tests:

- Strings that name a repository file or folder from the root, such as
  the grammars 'extensions/json/syntaxes/JSON.tmLanguage.json' that the
  syntax highlighting fixture reads, are now path references. The linker
  keeps those that exist and never resolves them as packages.
- Reordering the members of a declaration: members whose load-time code
  is order-relevant are evaluation order entries of their own, and the
  parent's hash records the order of its properties, enum members,
  namespace members and static fields. Moving methods changes nothing.
- Constructing a class runs code: `new X()` is a call. Constructing an
  imported class is an effect; constructing a local class runs its
  constructor, instance fields, superclass, and the methods they call
  through `this`, not its other methods. Effects are now recorded per
  declaration or member, so a class is no longer impure because one of
  its methods is.
- Mutations of module state: besides assignments and updates, property
  writes, `delete`, calls of methods that may mutate their receiver and
  values passed to calls now make the state depend on the code doing it,
  including writes in the functions, constructors and methods that
  load-time code calls. Calls of local members (`Registry.add(x)`,
  `this.update()`) run them.
- Members with the same name, such as a static getter and its setter,
  are one dependency.

On 708 commits of main, 206 commits select more tests, none newly
exceed the 50% limit, and the mean share stays 9.0%. Four select fewer:
path.ts was falsely marked as having global load-time effects because
an assignment to `posix.win32` counted as calling `posix`, whose methods
use `process.cwd()`. Re-scoring the saved CI failures misses nothing
that was selected before.

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

* …
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants