Skip to content

[pull] main from microsoft:main#1296

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

[pull] main from microsoft:main#1296
pull[bot] merged 9 commits into
code:mainfrom
microsoft:main

Conversation

@pull
Copy link
Copy Markdown

@pull pull Bot commented May 26, 2026

See Commits and Changes for more details.


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

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

roblourens and others added 9 commits May 26, 2026 10:50
Render web_fetch invocation and completion messages with the fetched URL instead of falling back to the generic tool display name.\n\n(Written by Copilot)\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix SSH remote agent host passphrase auth

Support IdentityAgent from resolved SSH config and prompt for encrypted private key passphrases when connecting SSH remote agent hosts.

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

* Clarify SSH IdentityAgent config comment

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

* Try SSH agent before encrypted on-disk keys

When the configured agent has the identity loaded, auth should succeed before we ever read an encrypted IdentityFile from disk - otherwise the user gets a passphrase prompt for a key the agent already holds unlocked.

Also fix _isDefaultKeyPath to normalize `~` paths so the absolute IdentityFile that `ssh -G` returns is correctly recognized as a default and not promoted to an explicit (encrypted) attempt that fires the passphrase prompt before the agent.

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

---------

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

* agentHost: add setting to disable worktreeCreated task auto-dispatch

Adds `chat.agentHost.runWorktreeCreatedTasks` (default `false`) which
gates `WorktreeCreatedTaskDispatcher` for agent host sessions. The
generic dispatcher now consults the setting before dispatching and skips
agent host sessions when it's disabled. Non-agent-host sessions and
manual `Run Task` invocations are unaffected.

(Written by Copilot)

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

* fix new dispatcher tests: set worktree after added event

The 3 new agent-host gating tests were creating sessions that already had
a worktree at the time of the 'added' event. _trackSession returns early
in that case (the session isn't 'pending'), so the dispatcher's gate was
never exercised. Match the existing pattern: start with hasWorktree=false,
fire the added event, then set the workspace.

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

* address review feedback

- Drop ISessionsProvidersService injection from the dispatcher; check
  session.providerId directly via a new isAgentHostProviderId() helper.
- Improve setting description: quote the actual tasks.json JSON shape.
- await TestConfigurationService.setUserConfiguration in the new test.

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Agent host: clearer worktree git timeout errors and 60s budget

The 30s timeout in addWorktree/addExistingWorktree/removeWorktree was
fine under normal conditions but bumped to 60s to absorb transient
disk-I/O contention on the remote (e.g. many concurrent npm installs
across multiple agent sessions).

When git timed out, _runGit re-threw `new Error(stderr || error.message)`,
which lost the timeout indicator. For `git worktree add`, stderr only
contains git's progress meter (`Updating files: 0% (149/14834)`), so
the surfaced error looked like git progress instead of a timeout.

Now _runGit uses its own timer to flag the timeout case definitively
and a new formatGitError helper produces messages like:

  git worktree timed out after 60000ms: <stderr tail>
  git worktree exited with code 128: fatal: invalid reference: ...

The underlying ExecFileException is preserved as Error.cause.

(Written by Copilot)

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

* Address review feedback on agent-host git error reporting

- Use child.on('exit') to clear the timeout, so 'timer' is no longer
  referenced in the execFile callback before its declaration.
- Add summarizeStderrForError() to squash carriage-return-heavy progress
  meter output into a single short line for the thrown error message,
  with a 200-char cap.
- Log the full unmodified stderr at warn level via ILogService whenever
  git exits with an error, so the raw output is still available even
  though the thrown error message is summarized.
- Add unit tests for summarizeStderrForError and update the existing
  formatGitError timeout test to exercise multi-line input.

(Written by Copilot)

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Normalize LF to CRLF in agent host terminal tool output

The detached xterm used to render terminal tool output treats input as a
raw TTY stream where a lone \n is just LF (cursor moves down without
column reset), producing a staircase rendering.

The custom terminal tool's output goes through xterm's serialize addon
which emits proper VT with \r\n line endings. The agent host SDK path,
however, was passing the SDK's plain text through unchanged, so multi-line
output rendered with each line starting at the column where the previous
one ended.

Normalize \n to \r\n in getTerminalOutput, the adapter boundary where SDK
content is shaped into terminalCommandOutput. The replace is idempotent
on already-CRLF input.

(Written by Copilot)

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

* Update agentHostChatContribution tests for CRLF normalization

Two assertions checked the previous raw \n output from getTerminalOutput;
update them to expect the normalized \r\n.

(Written by Copilot)

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

---------

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

sessions: restore X-button removal of SSH remote agent host entries (Written by Copilot)

The X button on remote agent host SSH entries in the workspace picker
disconnected the SSH tunnel but did not remove the entry from configured
storage: on the next reconcile pass (or on reload) `_reconnectSSHEntries`
found the entry still configured and immediately auto-reconnected it.

This regressed in [#316810](#316810),
which routed SSH disconnect through the provider's `_disconnectOnDemand`
hook. The provider's `disconnect()` returns early when that hook is set,
so it no longer called `removeRemoteAgentHost` for SSH entries (the
pre-#316810 behavior). Combined with the synchronous reconcile that fires
from `_sshService.disconnect`'s own close event, the entry was reconnected
before the disconnect even returned.

Call `removeRemoteAgentHost` from `_disconnectSSHOnDemand` before the
`_sshService.disconnect` await so the entry is gone before the close-event
chain triggers `_reconnectSSHEntries`. `removeRemoteAgentHost` also runs
the SSH transport disposable, which itself tears down the main-process
SSH tunnel; the explicit `_sshService.disconnect(connectionKey)` is kept
as belt-and-suspenders.

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

The command `workbench.action.chat.openNewChatSessionInPlace.agent-host-copilotcli`
was registered twice:

1. Statically in `electron-browser/chat.contribution.ts` (added in #314187)
2. Dynamically in `chatSessions.contribution.ts` via the autorun that
   registers an in-place action for every contributed session type. The
   agent host calls `registerChatSessionContribution` for the
   `agent-host-copilotcli` type at startup, which triggers that
   registration.

The static duplicate hit `CommandsRegistry.registerCommand`'s 'Cannot
register two commands with the same id' assertion. Remove the static
 the dynamic one already covers it and is explicitlyregistration
designed to handle programmatically-registered contributions like
`agent-host-copilotcli`.

The neighbouring `openNewSessionSidebar` / `openNewSessionEditor`
static commands stay; they have distinct ids and serve their documented
purpose of providing stable command ids for automation that may run
before the agent host has registered.

(Written by Copilot)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* launch: build copilot in compile; wait for CDP in launch.sh

Two related improvements to the agent dev-loop workflow:

- npm run compile now builds the Copilot extension in parallel with the
  rest of the client, mirroring the structure of npm run watch. Previously
  only the watch path included extensions/copilot, so a one-shot build
  left the Copilot extension stale.

- .agents/skills/launch/scripts/launch.sh now runs preLaunch.ts in the
  foreground (surfacing any failure synchronously with a log tail), then
  launches Code OSS with VSCODE_SKIP_PRELAUNCH=1 and blocks until the
  renderer's CDP endpoint responds (90s timeout) before printing the JSON.
  Previously the script returned in ~1s while Electron was still mid-
  bootstrap, which made it racy for agents driving the workbench via
  @playwright/cli and could let an early-dying child go unnoticed.

SKILL.md updated to drop the now-unnecessary attach retry loop and to
document the new error-surfacing behavior.

(Written by Copilot)

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

* launch: clarify launcher's actual external deps in SKILL.md

Per code review, `launch.sh` does not invoke `lsof` or `jq` itself
those are used only by the example caller snippets. Reword the
prerequisites bullet so it reflects what the script actually requires
(`rsync`, `curl`, `nohup`, Node) and notes `jq` / `lsof` as optional
for the caller-side examples.

(Written by Copilot)

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

---------

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Preserve unread state across remote host disconnect

Avoid reporting cached remote agent host sessions as removed when a host is temporarily unpublished during disconnect/reconnect. Re-announce cached sessions when the host reconnects so the sessions list refreshes without treating the outage as deletion.

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

* Address remote session reconnect review

Report updated cached sessions as changed when re-announcing them after a remote reconnect, and fix the sessions list documentation grammar.

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

---------

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant