Rob Lourens
90d · built 2026-07-24
90-day totals
- Commits
- 290
- Grow
- 28.8
- Maintenance
- 33.8
- Fixes
- 22.5
- Total ETV
- 85
Where this dev ranks
Percentile against the global top-100 leaderboard (all-time totals).
- By commits
- Top 4 %
- By Growth share
- Top 48 %
30-day trajectory
Last 30 days vs. the 30 days before. Up arrows on Growth and ETV mean improvement; up arrow on Fixes share means more time on fixes (worse).
↑+29.7 %
vs 74 prior
↑+7.7 pp
recent vs prior
↓-5.3 pp
recent vs prior
Daily performance
Daily ETV, stacked by Growth, Maintenance and Fixes.
Work-mix over time
Share of Growth / Maintenance / Fixes over a rolling 7-day window. Reads as 'where is effort flowing right now'.
Repository spread
Where this developer's commits land. Concentrated work (top1 > 80%) vs polymath spread (top1 < 30%).
Most impactful commits
Top 20 by ETV in the 90-day window.
- 2.5ETVAdd Agent Host E2E coverage and expand protocol scenarios (#326493) * Add Agent Host E2E coverage and scenarios (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Stabilize Agent Host E2E tests across platforms (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Gate macOS-recorded Agent Host snapshots on Windows (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use behavior snapshots for Agent Host scenarios (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 693614c9 · 2026-07-19
- 2.3ETVAdd Agent Host settings commands to editor window (#325187) * Add Agent Host settings commands to editor window (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use Agent Host enablement context key (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use camelCase in Agent Host config editor (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 48e0a100 · 2026-07-09
- 2.0ETVFix remote agent host reconnect hang for SSH and tunnel paths (#315552) * Fix remote agent host reconnect hang for SSH and tunnel paths When an SSH or tunnel connection silently dies (TCP half-open before ssh2/dev-tunnels keepalives detect it), the SDK calls used to (re)create the relay would hang forever. The renderer's reconnect await would never settle, leaving the per-host pending flag set and effectively disabling auto-reconnect for the lifetime of the shared process. The user-visible symptom: reloading the window doesn't help, only quitting and restarting the app does. Fixes: - sshRemoteAgentHostService: bound _createWebSocketRelay in connect(replaceRelay=true) with raceTimeout. On timeout the existing catch tears down the dead sshClient so the next attempt starts fresh. - tunnelAgentHostService: bound the four hangable dev-tunnels SDK calls (relay connect, waitForForwardedPort, connectToForwardedPort, ws open) with per-step timeouts; dispose relayClient on failure so we don't leak it. - remoteAgentHost.contribution: rewrite _reconnectSSHEntries with exponential-backoff retry mirroring the tunnel pattern. Per-host state lives in a single SSHReconnectState with a MutableDisposable timer, owned by a DisposableMap so disposal of the contribution (or removal of a host) cancels pending timers automatically. Adds a unit test that simulates a stuck relay via a hangRelayCreationOnCall hook and verifies the timeout fires and disposes the SSH client. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR feedback - SSHReconnectState.scheduleRetry: clear _timer.value when the timer fires so hasPendingTimer reflects reality after the handler runs. - tunnelAgentHostService.withTimeout: switch to raceTimeout so the timer is cleared in finally on success (no stray timers per step). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Detect silently-dead agent host transports via watchdog After laptop sleep + network change the SSH/tunnel transport's underlying TCP can be half-open: writes succeed locally but never deliver, and no FIN/RST is ever observed. The agent host protocol client used a plain WebSocket with no keepalive/timeout, so subsequent requests just hung forever. Reloading the renderer didn't help — the dead transport state lived in the shared process. Add a no-ping watchdog at RemoteAgentHostProtocolClient that mirrors PersistentProtocol's _recvAckCheck mechanism: - Track a sentAt timestamp per pending request and _lastReadTime for the most recent inbound message of any kind. - Every 5s, if there's an outstanding request, no inbound traffic for 20s, and the oldest pending request is older than 20s, force-close the connection so the existing reconnect machinery takes over. - Idle connectio After laptop sleep + network change the SSH/tunnel transport's underlying TCP can be half-open: writes succeed locally but never deliver, and no FIN/RST is ever observed. The agent o aTCP can be half-open: writes succeed locally but never deliver, and no FerFIN/RST is ever observed. The agent host protocol client used a plainutWebSocket with no keepalive/timeout, so subsequent requests just huneaforever. Reloading the renderer didn't help — the dead transport s21lived in the shared process. Add a no-ping watchdog cd /Users/roblou/code/vscode.worktrees/agents-vsckb-implement-i-m-having-some-kind-of-2a7030e7 && git log --oneline -3 && git status --short cd /Users/roblou/code/vscode.worktrees/agents-vsckb-implement-i-m-having-some-kind-of-2a7030e7 && git log --oneline -3 cd /Users/roblou/code/vscode.worktrees/agents-vsckb-implement-i-m-having-some-kind-of-2a7030e7 && git log --oneline -3 && echo --- && git status --short tail -200 /var/folders/ss/g5zgxl3j787811nn36my74s80000gn/T/1778448442759-copilot-tool-output-k6w908.txt | head -100 echo hello grep -E watchdog * Fix reconnect tearing down the new tunnel On a reconnect to the same address, addManagedConnection disposed the previous entry's store, which included the previous transportDisposable. That disposable calls _mainService.disconnect(connectionId). Because the new entry shares the same connectionId (e.g. ssh:host) with the just- established shared-process tunnel, the disconnect call immediately tore down the brand-new connection. Track transportDisposable separately from the entry's store so it only runs on true removal (removeRemoteAgentHost, _removeConnection, full service dispose), not when the entry is replaced. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Stop the watchdog and ignore late messages after close When the protocol client is closed (e.g. by the watchdog forcing a close on a silently-dead transport) the client may live on for a moment before being replaced by addManagedConnection. During that window: - The interval timer would keep ticking pointlessly. - The shared SSHRelayTransport message source feeds both the old and new transports for the same connectionId, so the old client could see late responses for requests that were already rejected. Cancel the watchdog inside _handleClose and drop incoming messages in _handleMessage when _isClosed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · f91a396d · 2026-05-11
- 1.9ETVagent-host: report git-driven session file diffs (#312632) * agent-host: report git-driven session file diffs (Written by Copilot) Adds an alternative diff source for agent sessions that derives changes from the working-tree git state instead of from edit-tool emissions, so edits made via terminal/shell commands also show up in the Changes view. Approach -------- * IAgentHostGitService gains computeSessionFileDiffs() and showBlob(). * gitDiffContent.ts encodes 'git-blob:' content URIs that pin a blob to a session + sha + repo-relative path. * AgentService routes 'git-blob:' resourceRead requests to gitService.showBlob(); AgentHostFileSystemProvider.stat() short- circuits 'git-blob:' alongside 'session-db:' so the diff editor's stat-then-read flow works end-to-end. * AgentSideEffects._tryComputeGitDiffs runs after each turn (debounced with the existing diff scheduler) and overrides edit-tool diffs when git is available. Tests ----- Unit + integration coverage in src/vs/platform/agentHost/test/node/. * agent-host: regression tests for git-blob: stat fast-path Adds five tests against AgentHostFileSystemProvider covering the synthetic content scheme fast-path in stat(): git-blob: and session-db: URIs must return a File stat directly without trying to list a parent directory that doesn't exist. Verified by reverting the git-blob: branch of the theallowlist new 'git-blob: stat' and 'full stat-then-read round-trip' tests fail with EntryNotFound, which is exactly the error the diff editor surfaced when opening a diff of a new file. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agent-host: address Copilot review feedback - agentHostGitService: bump default execFile maxBuffer to 32MB so diff output in large repos doesn't fail with ENOBUFS and silently drop terminal-driven diffs. - agentHostGitService.showBlob: validate sha is a hex object name before passing it to git, so a malformed git-blob: URI can't inject options or resolve to surprising refs. - mockAgent terminal-edit branch: void+catch the async IIFE so a filesystem failure surfaces as a chat delta instead of an unhandled rejection (test flake source). - agentSideEffects.test: replace setTimeout(100) with awaiting the SessionDiffsChanged envelope event for both new diff-computation deterministic and immune to slow CI.tests - sessionDiffsRealSdk integrationTest: shell-quote the target file path so temp dirs containing spaces don't break the prompt. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agent-host: use IFileService and INativeEnvironmentService in AgentHostGitService Replace direct fs/promises and os.tmpdir usage with platform services so the temp-index dance in computeSessionFileDiffs goes through the same file system abstraction as the rest of the workbench. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agent-host: set COMMAND_HOOK_LOCK=1 in temp-index env for GVFS repos Mirrors the extension's buildTempIndexEnv which sets this flag to avoid holding the GVFS command hook lock during temp-index git operations. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agent-host: inject IAgentHostGitService via DI into AgentSideEffects Instead of threading gitService through IAgentSideEffectsOptions, register it in the local ServiceCollection and inject it via @IAgentHostGitService decorator, which is the normal pattern everywhere else. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix deleted file diffs: use IChatSessionFileChange2 with undefined modifiedUri for deletions For deleted files, the 'modified' side of the diff editor must be absent. The renderer detects deletions via `change.modifiedUri === undefined`, so producing `IChatSessionFileChange2` (which carries a `uri` key alongside optional `modifiedUri`) is the right shape. Previously diffsToChanges returned IChatSessionFileChange (required modifiedUri) and fell back to the deleted file's pre-deletion path as modifiedUri, causing the diff editor to try to read a nonexistent file. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 8ae0d8ea · 2026-04-27
- 1.6ETVagentHost: centralize and type-check AHP `_meta` access (#322304) * agentHost: centralize and type-check AHP `_meta` access The Agent Host Protocol uses an open `_meta` bag (`Record<string, unknown>`) on many protocol/state messages to carry well-known extra data between server and client. This was read in an ad-hoc, untyped way in many places. This change makes all `_meta` access type-safe and centralized: - Add typed reader/builder functions per well-known slot, grouped under `platform/agentHost/common/meta/`, so nothing reads `_meta` untyped. - Readers take their parent object (e.g. `ToolCallState`, `AgentCustomization`, `RootState`, `ErrorInfo`, `UsageInfo`) and read `source._meta` internally, so passing the wrong slot's bag is a compile error. `readSessionGitState` stays a raw-value reader (the sessions provider holds a detached `_meta` snapshot). - De-duplicate the feedback-annotation slot: the sessions browser layer now maps the shared validated wire shape into its client view instead of re-declaring and re-validating it. - Replace a serialize-then-reparse round-trip in the Claude subagent signal path with a direct typed builder. - Add a syntactic local ESLint rule `code-no-untyped-meta-access` that flags member access off / casts of `x._meta`, scoped to the agent host surface. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: address Copilot review on `_meta` type-safety PR - protocolUpgrade: `readUnsupportedProtocolVersionErrorMeta` now returns `undefined` (not an empty `{}`) when `_meta` has no validated fields, matching its documented contract so presence checks stay correct. - code-no-untyped-meta-access: update the rule's header comment and diagnostic messages to recommend the new parent-object reader form (`readToolCallMeta(toolCall)`) instead of the old bag form. - stateToProgressAdapter: drop unreachable `resourceUri.length === 0` / `channel.length === 0` guards — `readToolCallMeta().ui` already guarantees a non-empty `resourceUri` and only sets `channel` when non-empty. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 033e0bef · 2026-06-21
- 1.6ETVReorganize Agent Host integration tests (#326531) * Reorganize Agent Host integration tests Separate protocol, provider E2E, mocked-LLM, and direct SDK test families, and split shared provider scenarios into focused suites.\n\n(Written by Copilot)\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address Agent Host test review feedback Keep coverage scope metadata and replay fixture documentation aligned with the reorganized suites.\n\n(Written by Copilot)\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Limit Agent Host coverage to provider E2E tests Exclude mock-agent and mocked-LLM suites so the report measures only the real server and bundled provider stacks with replayed model traffic.\n\n(Written by Copilot)\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clarify Agent Host E2E test boundaries Move synthetic-LLM suites into provider integration, flatten E2E captures, and simplify the checked-in coverage summary path without changing tests or fixture contents.\n\n(Written by Copilot)\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 3296e952 · 2026-07-20
- 1.5ETVagent-host: surface session git state via SessionState._meta (#312543) * agent-host: surface session git state via SessionState._meta The agent host process now computes per-session git state (branch, GitHub remote, ahead/behind, uncommitted changes) for sessions that have a working directory and publishes it through the protocol's per-session `_meta`. The Agents app reads it from `SessionState._meta` (not `SessionSummary`) and surfaces it via `ISessionWorkspace`, lighting up existing UI in the Changes view (e.g. ahead/behind indicators, branch info). Highlights: - New `AgentHostGitService` (server-side) computes git state by shelling out to git; refreshed on session open and after each turn. - New `SessionMetaChanged` action propagates `_meta` deltas without a full list refresh. - Client-side `AgentHostSessionAdapter` retains `_project` / `_workingDirectory` / `_meta` so the workspace observable can be rebuilt when only `_meta` changes. - `baseBranchProtected` is computed client-side from `git.branchProtection` config, so the workspace shape no longer carries it as a field on `ISessionRepository`. - `update()` only overwrites `_meta` when the source actually provides one (SessionSummary feeds have no `_meta` field), so the polling refresh path no longer clobbers good state pushed via `SessionState`. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address Copilot review feedback - Doc updates: reference SessionState._meta (not SessionSummary._meta) in agent service interface and the setMeta delta path. - changesViewModel.activeSessionHasGitRepositoryObs now derives the git-backed signal from surfaced git state on the workspace's first repository (uncommittedChanges/incomingChanges/outgoingChanges/ upstreamBranchName) rather than from mere workspace presence, so we don't enable git-specific UI for non-git working directories. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Render branch name in changes view tree root (Written by Copilot) Plumb 'branchName' through: - ISessionRepository (new optional field) - buildAgentHostSessionWorkspace + agentHostSessionWorkspaceKey (gitFields) - ChangesViewModel.activeSessionStateObs (fall back to workspace repo) - ChangesViewPane.getTreeRootInfo: only render parens when branchName known Also subscribe to activeSessionStateObs in the changes-tree autorun so the root rebuilds once branchName arrives asynchronously. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Show branch name in changes tree root even for non-worktree sessions (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: wire AgentHostGitService into AgentService at construction time Previously AgentService was constructed without a git service (the optional _gitService parameter was never passed), so _attachGitState always bailed with 'hasGitService=false' and no branch name was ever computed. The fix creates AgentHostGitService before AgentService and passes it as the fifth constructor argument. Also removes debug logging added during investigation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * harden: make IAgentHostGitService a required AgentService dep The optional `_gitService?` parameter was the root cause of git metadata never reaching the client: `agentHostMain.ts` and `agentHostServerMain.ts` constructed AgentService without passing it, and `_attachGitState` silently bailed at runtime. Making the dep required forces all callers (now and in the future) to wire it correctly at compile time. Also adds a regression test for the `subscribe()` lazy-fire path, which was the intended client-visible mechanism for surfacing branch name on sessions that already exist in the state manager. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Revert: only show branch name for worktree sessions Branch name on non-worktree sessions wasn't a goal. Restores the original guard so `(branch)` only appears when the session has a worktree. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * cleanups * Address Copilot review feedback (Written by Copilot) - changesViewModel: fall back to workspaceRepository.baseBranchName so agent-host sessions get branch protection UI when only the workspace repo carries baseBranchName - changesView: add comment explaining the intentional dependency read on activeSessionStateObs in the tree-update autorun - agentService: dedupe _ skip setSessionMeta when theattachGitState newly computed git state equals the current _meta.git, avoiding action churn after every turn Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 1fa1b7af · 2026-04-26
- 1.5ETVFix empty chat widget when opening an archived worktree session (#324341) * Fix empty chat widget when opening an archived worktree session Opening a recently-archived, worktree-isolated Copilot session showed an empty chat widget. Archiving deletes the worktree (keeping the branch), but resume still required the working directory to exist to bring up the SDK session — the only path to reading the transcript — so resume and its createSession fallback both failed and the session was restored with 0 turns. - Enforce read-only for archived sessions: AgentSideEffects rejects turns dispatched to a session whose status has SessionStatus.IsArchived. - Resume history against the persisted repository root when the worktree working directory is missing, so the transcript renders read-only. - Derive read-only from the session's archived flag in the sessions provider (shared effectiveChatInteractivity helper) so every chat hides its composer. - Surface unrecoverable resume failures: throw a typed SessionWorkingDirectoryMissingError when neither the working directory nor the repository-root fallback exists, and render a clear chat error in the handler instead of a silently empty session. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address Copilot review: preserve Hidden interactivity, generic load-error message - effectiveChatInteractivity now preserves ChatInteractivity.Hidden so archiving a session doesn't reveal internal worker chats as read-only tabs; it only downgrades interactive chats to ReadOnly. - The session-load error message is now generic ("This session couldn't be loaded.") since the specific cause can't be reliably distinguished at that layer (the typed error doesn't survive the protocol boundary). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Enforce read-only turns via chat interactivity, not just archived status interactivity is the general read-only mechanism in AHP (subagent worker chats are ReadOnly), but nothing enforced it — turn rejection previously only checked the session's archived flag. Enforce off the chat's effective interactivity instead (folding archived in via effectiveChatInteractivity / isChatReadOnly), so a single check covers subagent read-only chats and archived sessions alike, and closes the pre-existing gap where turns could be dispatched to a read-only subagent chat. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Make archived read-only turn-rejection message specific and actionable When a turn is dispatched to an archived session (e.g. a queued or in-flight message, or a remote client), the rejection error now reads "This session is archived and read-only. Restore the session to continue the conversation.", matching the "Restore" action label, instead of a generic read-only message. Non-archived read-only chats keep the generic message. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Show archived-specific read-only banner with a Restore action The read-only banner shown in place of the composer now explains an archived session specifically ("This session is archived and read-only.") and offers an inline "Restore" action that unarchives the session, instead of the generic "This chat is read-only" (kept for other read-only chats such as subagent transcripts). Adds a component fixture covering both states. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Extract UNARCHIVE_SESSION_COMMAND_ID and reuse it Move the 'sessionsViewPane.unarchiveSession' command id into a shared vs/sessions/common/sessionCommands.ts so both the action registration (sessionsViewActions.ts) and the read-only banner's Restore action (sessionView.ts) reference the constant instead of a hardcoded string. The common location keeps the parts/contrib sessions layering intact. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Recreate a live session's missing worktree instead of using the source repo A worktree-isolated session can lose its worktree while still active (the user deletes it, or a cleanup tool removes it). Previously resume silently fell back to the repository root, losing the session's isolation and risking running the agent against the user's working tree. Now the repair path distinguishes archived from live sessions: - Archived (read-only): resume against the repository root for history only, as before — turns are rejected host-side so nothing runs there. - Live (non-archived): recreate the worktree from its persisted branch via the shared _recreateWorktree helper and resume there. If recreation is impossible (branch gone / git failure), surface SessionWorkingDirectoryMissingError rather than degrade to the source repository. Extracts _recreateWorktree (shared with the unarchive path) and reads the persisted archived flag via _isSessionArchived. Renames _resolveResumeWorkingDirectory to _ensureResumeWorkingDirectory to reflect the side effect. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Share the archived-flag session-metadata keys via constants The 'isArchived'/'isDone' session-database metadata keys were hardcoded string literals in the writer (AgentSideEffects), the readers (AgentService), and the new CopilotAgent resume-repair read. Introduce AH_META_IS_ARCHIVED_DB_KEY / AH_META_IS_DONE_DB_KEY constants in sessionState.ts (next to AH_META_WORKSPACELESS_DB_KEY, the same shared-key pattern) and reference them everywhere so the writer and all readers share one definition. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Recreate deleted-but-registered worktrees and surface git errors to the UI Two fixes for the "live session whose worktree was deleted" repair path: - `git worktree add` refused to recreate a worktree whose directory was removed out-of-band because git still had it registered ("missing but already registered worktree"). Use `git worktree add -f` — it's our own managed per-session worktree, so overriding git's safeguard is safe. This makes the common manual-deletion case actually recreate instead of failing. - When recreation genuinely can't happen (branch gone, other git failure), the failure reason is now carried on SessionWorkingDirectoryMissingError and shown in the chat error instead of a generic "This session couldn't be loaded". `_recreateWorktree` returns a structured `{ ok, reason }`, and the session handler unwraps the restore-wrapper prefix to show the underlying git message. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 9aad6878 · 2026-07-10
- 1.4ETVPrompt for Agent Host authentication before send (#325725) * Prompt for Agent Host authentication before send Use the standard Copilot sign-in dialog when an Agent Host request has no usable token, including eager-created sessions, then forward the resulting token and resume the pending request. Preserve underlying authentication failures and dedupe repeated token forwarding. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Harden Agent Host authentication setup Deduplicate in-flight token forwarding, preserve setup failures without moving chat focus, and resolve authentication services through the instantiation accessor. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · efed051e · 2026-07-18
- 1.1ETVAgent host E2E: add executable AHP snapshots (#325892) * agent host e2e: add executable AHP snapshots (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agent host e2e: generate turn timestamps for snapshots (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agent host e2e: stabilize AHP snapshot rounds (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agent host e2e: make snapshot updates deterministic (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agent host e2e: canonicalize live AHP snapshots (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 2c669282 · 2026-07-15
- 1.0ETVAdd agent host user message telemetry (#316797) * Add agent host user message telemetry Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Propagate agent host telemetry level Use root config to propagate the client telemetry level into the Agent Host process and clamp Agent Host telemetry to the most restrictive level. Also forwards parent process telemetry disablement into spawned Agent Host processes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Extract agent host telemetry reporter Move the agentHostUserMessageSent event payload, classification, and publicLog2 call out of AgentSideEffects into a focused helper class. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add agent host user message telemetry metadata Rename the user-message event to agentHost.userMessageSent and include safe session and active-client metadata that is available at send time. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Trim agent host user message telemetry fields Remove boolean fields that can be derived from turnCount, activeClientId, and attachmentCount. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix agent host telemetry ID classifications Classify Agent Host protocol IDs as system metadata instead of end-user pseudonymized information. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 0ceddf2b · 2026-05-17
- 1.0ETVSync built-in skills to agent hosts and add skill buttons (#313277) * Sync built-in skills + add skill buttons for agent-host sessions Brings back the UX from #311815 for the Agents window: - Sync built-in prompts (e.g. /merge, /create-pr) into the local agent-host customization bundle so agent-host sessions can run the same slash commands as the Copilot CLI extension. The enumeration helper now reads the BUILTIN_STORAGE bucket from IPromptsService and includes those entries in the bundle pushed to the harness, alongside workspace, user, and extension prompts. - Add four skill buttons to the changes view of agent-host sessions: Merge Changes, Create Pull Request, Create Draft Pull Request, and Sync Pull Request. Each button dispatches the matching slash command to the active session via IChatService, scoped to git + GitHub state context keys so the right buttons appear at the right time. The first registered button is hoisted as the primary blue toolbar button; the rest live in the apply submenu. - Suppress the duplicate Copilot CLI extension buttons (Commit, Sync, Create PR, etc.) when the active session is an agent-host session, clause in extensions/copilot/package.json. The check only narrows the chatSessionType==copilotcli rows; claude-code rows are unchanged. - Mark the agent-host chat contribution supportsPromptAttachments so /create-pr and friends parse as slash commands in the chat input. Tests: - agentHostSkillButtons.test.ts: action registration, context key reactivity, when-clause coverage. - enumerateLocalCustomizationsForHarness.test.ts: built-in skill enumeration is folded into the bundle with BUILTIN_STORAGE. - resolveCustomizationRefs.test.ts: built-in entries are resolvable through the existing ref resolution path. End-to-end verified manually: clicking 'Merge Changes' on a debug-test agent-host session dispatches '/merge', the agent host receives the slash command, expands the merge skill, and runs its tool steps. Copilot CLI extension buttons are not visible on agent-host sessions. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agent-host: read git.branchProtection in repo scope The git.branchProtection setting is resource-scoped, so its value can differ per workspace folder. Reading it without an override picked up the host window's active workspace value instead of the session's own repository value, which made the agent host show a Merge Changes button for sessions whose repo had a protected main branch. Pass the session's project URI as the resource override so we read the setting in the scope of that folder. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agent-host: register skill buttons from sessions main, drop stale comment Move the skillButtons import to sessions.desktop.main.ts and sessions.web.main.ts so it is wired in both desktop and web sessions windows, instead of from the local-only contribution. Drop the now-redundant comment on supportsPromptAttachments in the chat session contribution registration. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agent-host: register client filesystem provider for local in-process agent host Previously, `vscode-agent-client://` was only registered for WebSocket agent host transports (dynamic and env-var driven). The local in-process utility-process agent host had no provider, so plugin syncs from the renderer (used by `/create-pr`, `/merge` and other built-in skills) failed with `ENOPRO`. This wires the same reverse-RPC pattern over the existing MessagePort IPC: * Renderer registers an `AgentHostClientResourceChannel` (server channel) on its `MessagePortClient`, wrapping the renderer's `IFileService`. * The renderer's clientId is now used as the IPC ctx so the agent host can route reverse calls to a specific client. * Agent host hoists `AgentHostClientFileSystemProvider` to a single shared instance and, for utility-process IPC connections, registers an authority per connection backed by the new channel. Result: `vscode-agent-client://` URIs resolve identically for local and remote agent hosts, the in-memory `vscode-synced-customization://` bundle is reachable from the agent-host process, and built-in skills sync. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agent-host: address Copilot review comments and fix branchProtection resource scope - resourceList now throws when target URI is not a directory - wrap BUILTIN_STORAGE listPromptFilesForStorage in try/catch so regular workbench prompts service (which throws on unknown storage) is handled - update test to model the throw case for regression coverage - use workingDirectory ?? project.uri as resource for git.branchProtection config lookup so worktree paths resolve the per-folder setting correctly (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 9cd698c3 · 2026-04-29
- 1.0ETVagentHost: Resolve symlinked read paths before auto-approval (#325716) * agentHost: Resolve symlinked read paths before auto-approval Check literal and real paths against the session working directory and require confirmation when realpath resolution is denied. Exercise directory-link containment on Windows with junctions.\n\n(Written by Copilot)\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: Preserve URI schemes in permission checks Avoid resolving non-file working directories through the local filesystem and use URI-relative home dotfile detection so Windows path casing remains safe.\n\n(Written by Copilot)\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 47405ef2 · 2026-07-13
- 1.0ETVagentHost: extract Copilot session launcher (#320203) agentHost: extract Copilot session launcher (Written by Copilot) Move Copilot SDK session creation and resume configuration into a focused launcher so CopilotAgent owns lifecycle concerns and CopilotAgentSession owns runtime behavior through a private adapter. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 9146ae1f · 2026-06-06
- 1.0ETVFolder picker chip for Agent Host sessions in multi-root windows (#320681) * Add Folder picker chip for Agent Host sessions in multi-root windows In a multi-root editor window the extension-host Copilot CLI shows a Folder dropdown so users pick which root folder the single-cwd session runs in. Agent Host sessions silently defaulted to folders[0]. This adds an equivalent Folder picker chip backed by a per-window selection store that all working-directory resolution sites consult. - New IAgentHostNewSessionFolderService stores the chosen folder per not-yet-started session and fires a change event. - The session handler, list controller, and config chips consult the store before falling back to the resolver / folders[0]. - A new OpenAgentHostFolderPickerAction + AgentHostFolderPickerActionItem render the chip (multi-root agent-host editor windows only), ordered last in the secondary chip row to match the extension-host Copilot CLI. - The provisional session service recreates the provisional backend session at the newly-selected cwd (working directory is immutable post-create), preserving config. (Written by Copilot) * Fix CI: register folder service in fixtures and fix test type - Register IAgentHostNewSessionFolderService mock in chat and inline chat component fixtures so AgentHostGenericConfigChips can be created. - Make the getValue stub generic in the folder picker visibility test to satisfy IContext.getValue. (Written by Copilot) * Address review feedback for folder picker chip - Validate the stored folder against current workspace folders; clear a stale selection and fall back to the first folder when the workspace changed. - Label the chip with the matching workspace folder's name, falling back to basename only when no folder matches. - Clear the per-session folder selection once the real backend session is created so the store doesn't retain state beyond the new-session phase. - Mention the Folder picker in the chat accessibility help dialog. (Written by Copilot) * Keep folder picker chip visible-but-disabled for active sessions Disable the chip via the action precondition (chatSessionIsEmpty) instead of hiding it once the session has started, and clear the chosen folder on session disposal rather than at creation time so the chip keeps showing the correct folder and no longer flickers to the first folder during the untitled-to-real session handoff. (Written by Copilot)github.com-microsoft-vscode · 31138723 · 2026-06-10
- 0.9ETVAdd AHP transport JSONL logging (#315129) * Add AHP transport JSONL logging Log AHP JSON-RPC frames at the transport boundary to per-connection JSONL files under the VS Code logs directory, with root-level metadata for direction, timestamp, connection id, transport, and byte length. Add focused tests for canonical JSONL shape and bounded rotation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address code review feedback - Truncate connectionId to 64 chars to avoid filesystem filename length limits - Memoize folder creation to avoid repeated filesystem calls per log line - Use specific transport labels: 'tunnel' for tunnel relay, 'ssh' for SSH relay Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use IInstantiationService for WebSocketClientTransport - Inject IFileService and ILogService via @-decorators - Accept IAhpJsonlLoggerOptions instead of pre-built logger - Build the AHP logger internally inside the transport - Use createInstance at the call site - Drop now-unused IFileService dependency from RemoteAgentHostService Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use IInstantiationService for AhpJsonlLogger Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Gate AHP JSONL logging on setting; export JSONL files instead of IPC traffic channel Adds the chat.agentHost.ahpJsonlLoggingEnabled setting (default on for non-stable builds) that controls whether the AHP transport writes JSONL logs for remote agent host connections. The export-debug-logs action now includes every <logsHome>/ahp/*.jsonl file in place of the per-connection `agenthost.<clientId>` IPC traffic output channel. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix RemoteAgentHostService tests after AHP logging refactor Stub IEnvironmentService and route the new createInstance(WebSocketClientTransport) call to a no-op MockTransport so createdClients only tracks RemoteAgentHostProtocolClient instances. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · e85a8295 · 2026-05-08
- 0.9ETVAdd generic agenthost config pickers to chatwidget (#316276) * Agent-host secondary-toolbar chips: dedicated AutoApprove picker + generic chip lane Adds a per-property chip widget for agent-host session config: - Dedicated AutoApprove chip with default/autoApprove/autopilot icons and themed colors (warning for autopilot, info for bypass). - Generic-fallback chip lane (`AgentHostGenericConfigChips`) that renders schema properties not claimed by a dedicated picker (e.g. Claude's permissionMode), styled to match the standard chip lane. (Written by Copilot) * Restructure secondary toolbar chips into wrapper row, register NullAgentHostService for web workbench (Written by Copilot) * Promote Claude approval to a well-known picker, restructure secondary toolbar chip layout, add 'Learn more' footer (Written by Copilot) * Agent-host secondary toolbar chips: dedup approvals picker + workbench gating - Remove duplicate sessions-side RUNNING_SESSION_CONFIG_PICKER_ID action and its AVI registration in favor of the workbench-side picker contributed by agentHostChatInputPicker. Both were appearing in the chat input secondary toolbar. - Align the new picker's CSS with the previous .chat-input-picker-item styling (16px height, 3px/6px padding, icon-foreground color, 10px chevron at 0.75 opacity, no base 0.75 opacity on warning/info). - Delete the now-orphan AgentHostPermissionPickerActionItem. - Workbench: gate the Branch and Isolation chips on IsSessionsWindowContext so they only appear in the Agents window. - Workbench AH session handler: default workbench-only sessions to Isolation='folder'. - AgentHostUntitledProvisionalSessionService: read chat.permissions.default for the initial approvals level (clamped by chat.tools.global.autoApprove policy). (Written by Copilot) * Remove duplicate IAgentHostService registration in workbench.web.main (Written by Copilot) * Drop redundant AutoApprove seed in agent-host untitled provisional service The sessions provider already seeds autoApprove from chat.permissions.default via getCreateSessionConfig, and the workbench permission picker drives its own state. Pre-seeding existingValues here permanently shadowed the filteredDefaults mechanism in agentHostSessionHandler. (Written by Copilot) * Seed isolation + autoApprove at provisional createSession in workbench The agent's server-side defaults (e.g. isolation: 'worktree') populate state.config.values before the workbench can dispatch its own defaults, which then get filtered out by the merge in agentHostSessionHandler. Sending the workbench seed at createSession time wins the race and lets chat.permissions.default propagate. (Written by Copilot) * Drop redundant workbench default-config merge in agent-host handler Workbench defaults (isolation: 'folder', autoApprove from chat.permissions.default) are now seeded at provisional createSession in agentHostUntitledProvisionalSessionService, so the handler no longer needs to compute or merge them. The Agents window flow continues to use request.agentHostSessionConfig from baseAgentHostSessionsProvider. (Written by Copilot) * Stub agent-host services in chat fixture registrations ChatInputPart now creates AgentHostGenericConfigChips, which depends on IAgentHostService, IAgentHostUntitledProvisionalSessionService, and IAgentHostSessionWorkingDirectoryResolver. Add no-op mocks so component fixtures can instantiate the input part. (Written by Copilot) * Force inline-flex on agent-host picker host inside action-bar The host element doubles as a toolbar .action-item, and `.monaco-action-bar .action-item { display: block }` was overriding our inline-flex. As a block, the inline-flex slot rendered inside an anonymous line box whose height was driven by the inherited line-height (~23.2px) instead of the chip's intended 22px content height. Re-assert inline-flex with matching specificity so the host sizes to its flex content. (Written by Copilot) * Stub agent-host services in inlineChatZoneWidget fixture ChatInputPart now creates AgentHostGenericConfigChips, which depends on IAgentHostService, IAgentHostUntitledProvisionalSessionService, and IAgentHostSessionWorkingDirectoryResolver. The InlineChatZoneWidget fixture instantiates ChatInputPart but does not use registerChatFixtureServices, so add the stubs locally. (Written by Copilot)github.com-microsoft-vscode · a7f6d3e3 · 2026-05-14
- 0.9ETVAgents: enhance SSH and remote agent host management (#312630) * Agents: enhance SSH and remote agent host management - Rewrite the 'Connect via SSH' picker to mirror the remote-ssh extension UX: configured aliases at the top, dynamic 'user@host' synthetic entry, plus '+ Add New SSH Host...' and 'Configure SSH Hosts...' footer items. - Add 'Add New SSH Host...' command that ensures ~/.ssh/config exists (mode 0700/0600 on POSIX) and inserts a Host snippet with tabstops via SnippetController2. - Add 'Configure SSH Hosts...' command that lists known SSH configuration files (user + system) and opens the picked one. - Add 'Manage Remote Agent Hosts...' F1 command that shows the same actions as the workspace picker's Manage submenu, with inline X buttons to remove non-tunnel remotes. - Show inline X (remove) buttons next to non-tunnel remote entries in the workspace picker Manage submenu, by propagating onRemove from child IActions through actionList. - Extract the per-remote management options popup into a shared showRemoteHostOptions(accessor, provider) helper and consume it from both the workspace picker and the new manage command. - Centralize all action/command IDs on a RemoteAgentHostCommandIds const block. - Add listSSHConfigFiles() to ISSHRemoteAgentHostService (user config always; system config when present) and update all impls + test mocks. (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Agents: add back button navigation to remote host management pickers - remoteHostOptions: add showBackButton option to showRemoteHostOptions(); now returns 'back' when the back button is pressed; picker is created with createQuickPick for full button support - remoteAgentHostActions: add showBackButton option to promptToConnectViaSSH(); the ConnectViaSSH action's run() accepts an optional onBack callback and calls it when the back button is pressed - manageRemoteAgentHosts: extract showManagePicker() inner function so it can be called recursively on back; pass showManagePicker as onBack callback to both the per-remote options picker and SSH sub-flow actions Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add back buttons to all SSH/tunnel sub-pickers - Configure SSH Hosts file picker now shows back button when launched from SSH picker, returning to SSH picker on click - Tunnel picker now shows back button when launched from manage picker, returning to manage picker on click - Both pickers fix leaked disposables by wrapping in DisposableStore - Remove leftover setTimeout from manage picker onDidAccept - Add comment explaining legitimate setTimeout in workspace picker Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address Copilot review: rename header + rethrow SSH config errors - Rename 'Connected' separator to 'Remote Agent Hosts' since items are not filtered by connection status - Rethrow errors from ensureUserSSHConfig so callers can surface real failures to the user instead of silently opening a bad path Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 672efcd7 · 2026-04-27
- 0.9ETVFix SSH remote agent host passphrase auth (#318244) * 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>github.com-microsoft-vscode · ac58dbf2 · 2026-05-26
- 0.9ETVchat: make archived agent sessions read-only (#326455) * chat: make archived agent sessions read-only (Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chat: track read-only state after session creation Keep newly materialized Agent Host sessions subscribed to archive and interactivity state without requiring the chat to be reopened.\n\n(Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chat: fix read-only session lifecycle Attach archive state after both direct and eager session materialization, avoid rewiring source sessions during forks, and keep archive dispatch ownership in the existing controller.\n\n(Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chat: address archived read-only review feedback Rebind materialized read-only sessions before rejecting sends, preserve focus for empty read-only chats, and cover chat interactivity transitions.\n\n(Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chat: clarify archived session banner Use the archived-session wording from the Agents window in editor chat surfaces.\n\n(Written by Copilot) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · eef13346 · 2026-07-19