Repository navigation
agentHost: await real signals instead of hidden polling waits in agent host tests - #343728
Merged
Alexandru Dima (alexdima) merged 2 commits intoOct 23, 2026
Merged
Conversation
…t host tests 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>
Contributor
There was a problem hiding this comment.
🟢 Approval recommended
The test-only changes use the relevant completion signals, preserve assertions, and have no unresolved blocking findings.
No open issues 🎉
What changed in this PR
This PR continues the Agent Host test synchronization cleanup by replacing hidden polling waits with explicit completion signals. It changes only tests, preserving existing scenarios and assertions.
Changes:
- Await fake SDK events, model publication, and deferred stub signals in Claude tests.
- Await root configuration persistence before reading the saved file.
- Replace protocol request microtask loops and chunk-acknowledgement timer waits with transport send events.
No actionable findings remain.
| File | Description |
|---|---|
src/vs/platform/agentHost/test/node/claudeProxyService.test.ts |
Waits for an explicit upstream-call signal before testing disposal. |
src/vs/platform/agentHost/test/node/claudeAgent.test.ts |
Uses SDK events, refresh completion, observable state, and deferred signals instead of polling. |
src/vs/platform/agentHost/test/node/agentService.test.ts |
Awaits dispatch and configuration persistence before asserting saved values. |
src/vs/platform/agentHost/test/electron-browser/agentHostProtocolClient.test.ts |
Waits for transport sends during chunk staging and request lookup. |
Review effort: Balanced
…ling-agent-host-v2
Alexandru Dima (alexdima)
marked this pull request as ready for review
October 23, 2026 13:58
Alexandru Dima (alexdima)
enabled auto-merge (squash)
October 23, 2026 13:58
Vijay Upadya (vijayupadya)
approved these changes
Oct 23, 2026
Alexandru Dima (alexdima)
deleted the
agents/no-timeout-polling-agent-host-v2
branch
October 23, 2026 14:10
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> * …
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Follow-up to #342698 and #343092.
Problem
An audit of origin/main at eeedb17 found waits for state in four agent host test files that
local/code-no-timeout-polling-loopdoes not report. The rule reports loops whose body only waits on a timer; these loops wait onsetImmediate, asetIntervalcallback or a microtask, or do other work in the same body (atry/catchre-read, answering a request).npx eslint --rule '{"local/code-no-timeout-polling-loop": ["warn", {"exclude": []}]}'reports 0 problems on all four original files. Each wait stood in for a specific piece of work:claudeAgent.test.ts, 6 loops).ClaudeAgentqueues its first model refresh withqueueMicrotaskin the constructor and keeps it only in the private_modelRefreshInFlight. Five tests ran up to 100setImmediateticks until the fake SDK had counted asupportedModels()oraccountInfo()call, then one more tick for the refresh to publish. A sixth, in the SDK setup channel suite, ticked until the bootstrap reached enumeration, so that a gate it raises next blocks only the download's enumeration. The comment on one of them said_fetchNativeModelsawaits a realmkdtemp; it no longer does (buildModelEnumerationOptions()usestmpdir()).claudeAgent.test.ts, 2 loops) and a download enumeration (1 loop). Two loops ticked untilagent.modelswas not empty, one until the fake SDK had counted the download'ssupportedModels()call.claudeAgent.test.ts, 2 loops;claudeProxyService.test.ts, 1 waiter). Twowhile (!persistEntered)loops spun onsetImmediateuntil the test's stubbedsetMetadatahad been entered. The proxy test polled a flag set by its stubbedmessagesevery 10 ms withsetInterval.agentService.test.ts, 1 loop). The test re-read the root config file up to 20 times, every 5 ms, until it parsed and matched, and continued with a failure flag when it ran out. It waited for the serialized write thatAgentConfigurationService.persistRootConfig()chains onto_rootConfigWrite, whichwhenIdle()already exposes.agentHostProtocolClient.test.ts, 1 loop). After acknowledging eachvscode/stageCreateSessionImportChunkrequest, the test waitedsetTimeout(0)for the client to send its next message (agentHost: support turn-by-turn conversation import for remote sessions #343312).agentHostProtocolClient.test.ts, 2 helpers).waitForRequestandwaitForRequestAtspun onawait Promise.resolve()until the transport's outbox had the request. They have 99 call sites in the soft reconnect suite; a probe (P1 below) counted 123 calls in that suite, 79 of which had to wait for a send. A microtask spin never yields to timers, so it hangs if the send ever moves behind one.The tick and timer budgets depended on machine load, and the bounded loops continued with stale state when they ran out.
Change
claudeAgent.test.ts1727, 1755, 1775, 1796, 6398, 6981bootstrapModelRefresh(agent, sdk):sdk.waitForCalls(() => sdk.accountInfoCallCount > 0), then the agent's_modelRefreshInFlightclaudeAgent.test.ts1688, 6421agent.modelsnot emptywaitForState(agent.models, models => models.length > 0)claudeAgent.test.ts6415supportedModels()callsdk.waitForCalls(() => sdk.supportedModelsCallCount > enumerationsBefore)claudeAgent.test.ts4501, 5878setMetadataenteredDeferredPromisecompleted by the stubclaudeProxyService.test.ts1360messagescalledDeferredPromisecompleted by the stubagentService.test.ts8106await svc.dispatchAction(...), thengetConfigurationService(svc).whenIdle(), then one readagentHostProtocolClient.test.ts2154Event.toPromise(transport.onDidSend), subscribed before the acknowledgementagentHostProtocolClient.test.ts4869, 4879transport.onDidSendLine numbers are from eeedb17; none of these files changed between it and the base of this PR.
Details worth a look:
FakeClaudeAgentSdkServicegetswaitForCalls(condition), in the shape ofTestCopilotClient.waitForCallsfrom agentHost: await real signals instead of polling timers in copilotAgent tests #343092: it checks the condition and otherwise awaitsEvent.toPromise(Event.filter(...))on an emitter thatFakeQueryfires after it counts asupportedModels()oraccountInfo()call.bootstrapModelRefreshreads the private_modelRefreshInFlightthrough element access in a single helper, asproxyRefresh(agent)does incopilotAgent.test.ts. The field is only set once the constructor's microtask has run, so the helper first waits for the refresh'saccountInfo()call; after that the field holds the bootstrap refresh, or is already cleared because the refresh has published. Nothing else starts a refresh in these tests. Callingagent.refreshModels()instead would coalesce or start a second enumeration depending on timing, and would hide a missing bootstrap.[], which is also the initial value, so it is only meaningful after the refresh has published. M3 and M3b below show that awaiting the in-flight refresh is what makes it fail when the product publishes the static list.setImmediateticks gave the same result, and the test relies on it: therefreshModels()that follows must start a new refresh instead of coalescing onto the bootstrap. Its comment says so.dispatchActionreturns the queued dispatch promise when it defers a client action andundefinedwhen it applies it at once; awaiting it covers both.persistRootConfig()snapshots the values when it is called, so the write thatwhenIdle()awaits already contains the change. The existingwhenIdle()before cleanup is kept.There are no product-code changes. All scenarios and assertions are kept.
Not changed:
settle()helper in the "ClaudeAgent — agent SDK setup channel" suite runs a fixed 20setImmediateticks and has 21 call sites, including negative checks. Each site needs its own signal, probably an event on the root transient values that the setup channel publishes, so it is left for a separate change. "a download that lands staysdownloadinguntil the catalog does", changed here, still calls it twice, once right after thewaitForStatethis PR adds (M5 below).await tick()calls,await new Promise(resolve => setImmediate(resolve))in the shutdown test atclaudeAgent.test.ts4401,setTimeout(resolve, 0)waits inagentHostProtocolClient.test.ts4230 to 4395 andagentService.test.ts41652, and the 2 sPromise.racein the streaming abort test inclaudeProxyService.test.ts.Validation
The baseline ran on eeedb17. The change was then rebased onto 37b0141, the base of this PR; the rebase was clean and no upstream commit in between changed the four test files or
claudeAgent.ts,claudeProxyService.ts,agentConfigurationService.ts,agentService.tsoragentHostProtocolClient.ts. The mutation checks ran before the rebase, the 10 runs, CPU load runs and final checks after it. The machine was shared, so load averages are given with each timed run../scripts/test.sh --run src/vs/platform/agentHost/test/node/claudeAgent.test.ts --run src/vs/platform/agentHost/test/node/claudeProxyService.test.ts --run src/vs/platform/agentHost/test/node/agentService.test.ts --run src/vs/platform/agentHost/test/electron-browser/agentHostProtocolClient.test.ts: 2027 passing, 16 pending (1 min Mocha time, 263 s wall, load average 20 to 42).git grep -n -E 'for \(let i = 0; i < 100 && .*; i\+\+\) \{|while \(!persistEntered\)|const i = setInterval\(|attempt < 20; attempt\+\+|await new Promise\(resolve => setTimeout\(resolve, 0\)\);|while \(true\) \{|^\t\t\t\tawait Promise\.resolve\(\);$' <ref> -- <the 4 files>: on eeedb17 it lists the 9 tick loops and 2persistEnteredloops inclaudeAgent.test.ts, thesetIntervalwaiter, the 20-attempt loop, the chunk loop'ssetTimeout(0)and the two helper loops. After the change none of them remain; the remaining matches are unrelated: the event-drivenwhile (true)loops inwaitForPendingWorktreeRemovalsandwaitForCondition(agentHost: await real signals instead of polling timers in the remaining agentService tests #343603), the chunk loop itself (each iteration now awaits a send), the fake query's prompt drain, and the standalonesetTimeout(0)waits listed above.npx eslint --rule '{"local/code-no-timeout-polling-loop": ["warn", {"exclude": []}]}' <the 4 files>: 0 problems, before (run on the eeedb17 contents through--stdin --stdin-filename) and after.for i in $(seq 10); do ./scripts/test.sh --run <the 4 files> 2>&1 | grep -E 'passing|failing'; done: 10/10 with 2027 passing and 16 pending. Mocha time 33 s to 1 min and wall time 35 to 70 s, at a 1-minute load average of 6.7 to 26.yesprocesses,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 4 files> 2>&1 | grep -E "passing|failing"; kill "${pids[@]}"', alternating with the original files:yesprocesses raised the 1-minute load average to about 27 to 34 on this machine. Neither version failed, so this load does not show a difference between them.--grep, and restored byte for byte (verified withfilecmp):await agent['_modelRefreshInFlight']inbootstrapModelRefresh, three of the four bootstrap tests fail with an empty catalog ("signed out with an SDK-reported account", "the SDK default alias row is dropped", "signed out, the native catalog bootstraps"). "native model enumeration closes the throwaway query" still passes: the query closes before the test resumes, earlier in the same refresh.fireDidRecordCall()not firing, "the SDK default alias row is dropped", "nothing configured" and "a download that lands staysdownloading" hit the Mocha timeout.waitForState, "first sign-in keeps the native catalog published" fails withbootstrap: [].waitForStateafter releasing the enumeration, the test still passes, because thesettle()that follows also covers it. Without thewaitForCallsfor the download's enumeration, it also passes: the download publishesdownloadingsynchronously and the catalog is empty until the gate opens, so the snapshot is the same. The wait sets up the state the test names but does not decide its result, as with the old loop.setMetadatastubs never completingpersistEntered, both race tests hit the Mocha timeout. Without awaiting it, "agent.dispose() during a racing first sendMessage" fails (rejectedIsCancellation: false,warmQueryDisposed: false); "teardown racing _writeCustomizationDirectory" still passes.upstreamCalled, "dispose() with in-flight non-streaming aborts the upstream call" fails with "expected abort to fire on dispose".whenIdle()before the read, and separately with the product'swhenIdle()not awaiting_rootConfigWrite, "applies and persists root config changes from clients" fails withENOENTfor the config file.onDidSendwait never resolving, the first two soft reconnect tests that call them hit the Mocha timeout, and the failingafterEachstops the suite. With the chunk loop's next send never resolving, "stages large imported conversations in bounded chunks" hits the Mocha timeout.lockf -t 3600 /tmp/vscode-no-timeout-polling-typecheck.lock npm run typecheck-client: no errors in the changed files, before the rebase and on 7e76185. The command still exits with errors in files this PR does not touch, 19 before the rebase and 20 after it:fusionTierin the Copilot agent files and their tests, and after the rebasesetParentWindowinterminalProcess.tsfrom Parent the ConPTY console window to the VS Code window #342784. Both come from the sharednode_modules, whose@github/copilot-sdk(1.0.24-preview.0) andnode-pty(1.2.0-beta.15) are behind this tree's pins (1.0.26 and ^1.2.0-beta.18).npm run eslint -- <the 4 files>: no problems.code-reviewskill: no findings. Earlier, the first test run after the change found a test that usedagentwithout destructuring it, and the first type check found that the type guards in a first version ofwaitForRequestandwaitForRequestAtdid not narrow; both were fixed before the runs above.