Connor Peet
copeet@microsoft.com
90d · built 2026-05-28
90-day totals
- Commits
- 150
- Grow
- 29.7
- Maintenance
- 13.9
- Fixes
- 12.3
- Total ETV
- 55.8
Where this dev ranks
Percentile against the global top-100 leaderboard (all-time totals).
- By commits
- Top 35 %
- By Growth share
- Top 13 %
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).
↑+9.8 %
vs 41 prior
↑+3.5 pp
recent vs prior
↓-5.0 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.2ETVfeat(agent-host): gate inbound filesystem RPCs with a permission service (#314194) * feat(agent-host): gate inbound filesystem RPCs with a permission service Reverse `resource{Read,List,Write,Delete,Move}` from remote agent hosts were routed straight to `IFileService` with no authorization. Add a permission service that gates each reverse RPC, returns typed `PermissionDenied` with `data.request`, handles negotiation via the new `resourceRequest` reverse RPC, and surfaces a Deny / Allow / Always Allow prompt above the chat input. URIs are canonicalized through `IFileService.realpath` before comparison so `..` and symlinks can't escape grants. Implicit read grants are auto-registered for customization URIs the client sends to the host, so plugin sync remains friction-free. Always-Allow grants persist into a new user setting, `chat.agentHost.localFilePermissions`. * comments and testsgithub.com-microsoft-vscode · c30ed7c4 · 2026-05-04
- 2.0ETVagent host: eagerly create sessions when a folder is picked (#313841) * agent host: eagerly create sessions when a folder is picked Previously the agent-host backend session was only created when the user sent their first message. Move creation up to folder-pick time so the new-chat view interacts with a real session URI throughout: model selections, session-config picks, etc. all dispatch against a known session, and the chat handler avoids a duplicate createSession round-trip on the user's first send. This is particularly in advance of support for completions, which necessarily are derived in the context of a workspace, agent customizations, etc. While the work for these new 'provisional sessions' is trending towards gnarly internally, the protocol is kept pretty clean with the only change being semantic guidance that sessions with no messages should be garbage collected. To make eager creation cheap, sessions are ephemeral in the agent until the first message lands — no SDK session, no worktree, no on-disk metadata. Materialization happens inside `sendMessage` and fires `onDidMaterializeSession`, at which point the agent service emits the deferred `notify/sessionAdded` and transitions lifecycle to `Ready`. Switching workspaces or closing the new-chat view disposes the provisional record (`disposeSession` over the wire); a 30s server-side empty-session GC backstops crashes and dropped disconnects. The new-session bookkeeping in the sessions provider previously lived across 11 loose `_currentNewSession*` fields and 4 keyed-by-sessionId maps. Bundle them into a single `NewSession` class held as a `MutableDisposable` — assigning a new value automatically tears down the previous one (subscription release + disposeSession RPC). Subtle wire-ordering note: `NewSession.eagerCreate` awaits `createSession` *before* opening the state subscription. Reversing the order races the wire — the server sees `subscribe` for an unknown session, returns `AHP_SESSION_NOT_FOUND`, and the client subscription enters an unrecoverable error state. New unit tests pin the ordering and the bail-out behaviour for workspace-switch-mid-flight. --- Architecture (provisional → real session): ```mermaid sequenceDiagram participant U as User participant SP as SessionsProvider participant H as ChatHandler participant A as Agent (CopilotAgent) participant S as StateManager U->>SP: pick folder SP->>A: createSession(uri) A->>S: createSession(emitNotification=false) Note over A: provisional record<br/>(no SDK, no worktree, no DB) SP-->>U: session.resource U->>SP: pick model / config (optional) SP->>A: SessionModelChanged / SessionConfigChanged Note over A: updates provisional record U->>H: send first message H->>A: sendMessage() A->>A: _materializeProvisional<br/>(create worktree,<br/> SDK session, persist DB) A->>S: onDidMaterializeSession S-->>U: notify/sessionAdded S->>S: SessionReady U-)SP: switch workspace SP->>A: disposeSession (old uri) Note over A: drops provisional record<br/>cancels worktree creation ``` * reviewgithub.com-microsoft-vscode · 8309b220 · 2026-05-02
- 2.0ETVplugins/mcp: allow disabling/enabling similar to extensions (#300273) * plugins/mcp: allow disabling/enabling similar to extensions Introduces an EnablementModel which is used to allow users to enable and disable both plugins and MCP at both a workspace and global level. Accessible on the mcp/plugins editors, inline within the marketplace view, and in the chat customizations view. * commentsgithub.com-microsoft-vscode · c3788b7b · 2026-03-09
- 1.9ETVagentHost: adopt OTEL log channel, support logs from remote agent hosts (#317876) Wires up the new `channels-otlp/` protocol so the agent host's `ILogService` is mirrored over an `ahp-otlp://logs/{level}` channel and surfaced as a per-host Output channel in the workbench. - Add `OtlpLogEmitter` / `OtlpEmitterLogger` (`platform/agentHost/common/otlp/`). `LogService` is constructed with the OTLP logger as a secondary sink in both `agentHostMain.ts` and `agentHostServerMain.ts` so every log call fans out to subscribers. - `ProtocolServerHandler` advertises `telemetry.logs` in `InitializeResult`, routes `subscribe`/`unsubscribe` on `ahp-otlp:` channels through a typed `ChannelSubscription` union, canonicalises the channel URI per-level, and broadcasts `otlp/exportLogs` notifications filtered per subscriber severity. - `RemoteAgentHostProtocolClient` stores the full `InitializeResult`, adds `subscribeStateless` and `onDidReceiveOtlpLogs`. - New `RemoteAgentHostLogForwarder` in the workbench layer registers an `Agent Host (${host})` Output channel via `IOutputChannelRegistry`, subscribes at the workbench's `ILogService` level (re-subscribes on change), and appends decoded records. Constructed from `remoteAgentHost.contribution.ts::_setupConnection` so it covers WebSocket, SSH and tunnel paths. Local agent host IPC logging is unchanged. - Existing remote IPC traffic channel renamed to `Agent Host IPC (${host})` to disambiguate from the new OTLP-derived channel. - Move `UriTemplate` from `workbench/contrib/mcp/common/` to `base/common/` so the forwarder can use it for `{level}` expansion. Tests: 8 unit tests for the emitter, 7 for the server-side OTLP routing (including URI canonicalisation), 3 integration tests for the end-to-end wire flow, and the existing protocol/handshake/reconnect suites. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 3400e0f7 · 2026-05-21
- 1.6ETVagentHost: replace AgentHostEditingSession with direct externalEdit progress part (#318053) The legacy AgentHostEditingSession (844 LOC) only existed to translate completed tool-call file edits into a markdownContent/codeblockUri/textEdit cluster that CollapsedCodeBlock would then re-derive into a diff pill by asking the editing session for stats it had just been handed. The agent host protocol already exposes FileEdit.diff and before/after content URIs up-front, so cut out the round-trip: - New IChatExternalEdit progress part carries uri, editKind, originalUri, beforeContentUri, afterContentUri, and diff stats directly. - stateToProgressAdapter.completedToolCallToEditParts emits one IChatExternalEdit per FileEdit, wrapping every URI via toAgentHostUri so remote sessions resolve through the agent host file system provider. - Extract ChatEditPillElement base class from CollapsedCodeBlock — same DOM / styling, no editing-session coupling. New ChatExternalEditContentPart extends it and renders a static pill from the progress data. - ChatThinkingContentPart.appendItem now accepts IChatExternalEdit metadata directly (via the new ChatThinkingItemMetadata alias); it derives the title (Created/Deleted/Renamed/Edited <filename>) and the pencil icon without any synthesized markdown. Diff stats bubble up through onDidChangeDiff (fired on a microtask so subscribers attach first). - AgentHostSnapshotController (~330 LOC) replaces the legacy editing session: implements IChatEditingSession but only restoreSnapshot, requestDisablement, and snapshot URIs do real work. Everything else is a no-op so the chat-level Restore-to-checkpoint UI keeps working without dragging in the full diff pipeline. - ChatChangesSummaryPart is intentionally skipped for agent host responses — per-file pills already convey the change counts inline. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 5bb22231 · 2026-05-23
- 1.4ETVagentHost: adopt improved AHP file edits (#307502) * agentHost: adopt improved AHP file edits Adopts https://github.com/microsoft/agent-host-protocol/pull/35 * commentsgithub.com-microsoft-vscode · 02a92c1b · 2026-04-02
- 1.3ETVchat: add support for agent plugin sources (#299081) * chat: add support for agent plugin sources - Adds support for agent plugins to reference sources as specified in PLUGIN_SOURCES.md, enabling installation from GitHub, npm, pip, and other package registries - Integrates source parsing and validation into the plugin installation service and repository service - Adds comprehensive test coverage for plugin source handling and installation from various sources - Creates PLUGIN_SOURCES.md documentation describing how to specify plugin source configurations (Commit message generated by Copilot) * comments * windows fixes and fault handling * fix testsgithub.com-microsoft-vscode · a4e35e0d · 2026-03-04
- 1.2ETVmcp: make gateway spawn a gateway per mcp rather than a combined gateway (#301741) * mcp: make gateway spawn a gateway per mcp rather than a combined gateway Closes https://github.com/microsoft/vscode/issues/301013 Usage is not terrible: ```ts const disposable = vscode.commands.registerCommand('extension.helloWorld', async() => { const gateway = await vscode.lm.startMcpGateway(); gateway?.onDidChangeServers((e) => { console.log('new gateways:', gateway?.servers.map(s => [s.label, s.address.toString()])); }); console.log('initial gateways:', gateway?.servers.map(s => [s.label, s.address.toString()])); }); ``` * pr comments * testsgithub.com-microsoft-vscode · d87bb196 · 2026-03-18
- 1.2ETVagentHost: fix other cases of client-provided tools getting stuck (#312942) * agentHost: fix other cases of client-provided tools getting stuck * comments and cigithub.com-microsoft-vscode · e78dfbd5 · 2026-04-28
- 1.2ETVmcp: move to askquestions for elicitations (#300294) * mcp: move to askquestions for elicitations This reuses the askquestions UI to make elicitation requests. This is a nicer UX than the quickpick flow. It adds data validation to askquestions, as required by MCP, and also switches the answer types from `unknown` to `IChatQuestionAnswerValue` which is a bit more predictable to manage. * fic tests * pr commentsgithub.com-microsoft-vscode · 261701ae · 2026-03-10
- 1.1ETVplugins: allow updating agent plugins (#300344) * plugins: allow updating agent plugins Add update detection and update buttons to the agent plugins view and editor. This allows users to see when installed plugins have newer versions available and update them directly from the UI without manually checking for updates. - Export hasSourceChanged() from pluginMarketplaceService for reuse - Add 'outdated' and 'liveMarketplacePlugin' fields to IInstalledPluginItem - Fetch marketplace data in AgentPluginsListView.show() to cross-reference installed vs live versions and mark outdated plugins - Add UpdatePluginAction to list view with live marketplace data - Add UpdatePluginEditorAction to plugin editor with live marketplace data - Both update actions re-register the plugin with updated metadata after successful update so the UI immediately reflects the new version - Read fresh installed metadata from pluginMarketplaceService.installedPlugins store (not stale IAgentPlugin.fromMarketplace) for accurate version checks - Pass 'silent' option to runInstall() to show non-blocking notification instead of dialog when silent=true - Re-register plugins with live data after updateAllPlugins() completes so stored sourceDescriptor reflects new version/ref/sha (Commit message generated by Copilot) * pr comments and cleanup * fix test failuregithub.com-microsoft-vscode · 0a8edf7b · 2026-03-10
- 1.1ETVagentPlugins: normalize to user data dir storage (#304977) * agentPlugins: normalize to user data dir storage Previously we stored plugins in a very internal way that was inaccessible by other tooling. This sets up a `agent-plugins` folder beside `extensions` and creates an `installed.json` which is easy to integrate with. * comments * fix compile --------- Co-authored-by: Raymond Zhao <7199958+rzhao271@users.noreply.github.com>github.com-microsoft-vscode · 1d62cc62 · 2026-03-27
- 1.1ETVagentHost: ui side for queued messages (#304954) * agentHost: initial queuing/steering data flows * agentHost: ui side for queued messages Steering messages still don't quite work yet, I need to hook up some more stuff in the CLI for that I believe. * comments * rm dead codegithub.com-microsoft-vscode · 29d9808b · 2026-03-26
- 1.1ETVplugins: fix a bunch of issues in customizations (#303270) - Adds a "Show Plugin" option on every plugin-contributed item in the customizations view (closes #302514) - Fixes MCP servers from plugins showing under "built-in" - Fixes "Show Configuration" on plugin MCP servers opening a not found file - Fixes hooks from plugins not showing in the customizations list. A bit of a special case here because hooks get parsed from plugin manifests and have special interpolation logic.github.com-microsoft-vscode · bb5aae30 · 2026-03-19
- 1.1ETVplugins: add Plugins section to Chat Customizations (#299265) * plugins: show in customizations view * plugins: address PR review commentsgithub.com-microsoft-vscode · b3ad9079 · 2026-03-04
- 1.1ETVagentPlugins: clone locally when in a remote (#303606) * agentPlugins: clone locally when in a remote The git extension runs on the remote side, so it's not suitable to use to clone. This just does it directly. I would kind of like to just take this path in all cases since I previously had to add some internal commands in the git extension. But for now going into next release this only affects the remote case which was previously broken. Closes #298701 * cleanup * commentsgithub.com-microsoft-vscode · 89d0d131 · 2026-04-03
- 1.0ETVagentHost: fix client-provided tool weirdness (#310870) * agentHost: fix client-provided tool weirdness There was a few weird stuff with client-provided tools still, especially those that needed confirmations. These would generally just hang. Now they don't. * testsgithub.com-microsoft-vscode · 32162cfc · 2026-04-17
- 1.0ETVagent-host: stop config pickers flashing during resolveSessionConfig (#317856) * agent-host: stop config pickers flashing during resolveSessionConfig When a user changed a session-config picker (isolation, branch, autoApprove, mode, claude permission mode), all schema-driven pickers visually disappeared and reappeared while the async resolveSessionConfig round-trip ran. Root cause: NewSession.setConfigValue wiped the cached schema to { properties: {} } during the optimistic update, so every well-known mode/autoApprove guard returned false and hid its picker until the new schema arrived ~200-500 ms later. Fix: - Preserve the existing schema in NewSession.setConfigValue. - Introduce an observable isResolvingConfig on NewSession, owned by resolveConfig's finally, with begin/endResolveConfigSync helpers for the synchronous-set-before-event path and the no-connection early- return path. - Expose IObservable<boolean> isSessionConfigResolving(sessionId) on IAgentHostSessionsProvider; constObservable(false) for any session that isn't the in-flight new session. - Distinct from session.loading: the latter also stays true while config is complete-but-required-values-missing, where pickers must remain interactive. Every picker that mutates session config now disables on this observable: generic per-property chips, the mode/claude permission mode enum pickers, the autoApprove permission action item, the mobile bottom-sheet mode picker, and the mobile combined Mode+Model new-session chip. The autoApprove permission picker also gates the delegate's setPermissionLevel on the same observable, because ActionWidgetDropdown opens via Enter/Space directly on its label and CSS pointer-events: none does not block keyboard activation. A defense-in-depth bail in setSessionConfigValue drops second-arrival changes on a new session while a resolve is already in flight. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agent-host: update FakeProvider mocks for isSessionConfigResolving Two unit-test FakeProvider mocks were missing the new isSessionConfigResolving method that the production AgentHostPermissionPickerDelegate and AgentHostSessionEnumPicker (claude permission mode) now call. Add a no-op constObservable(false) implementation to both so the rendered delegate / picker code paths don't TypeError. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agent-host: address Copilot review feedback on PR #317856 Move _isResolvingActiveSessionConfig derived initialization into the constructor so its body safely closes over parameter-property service references (avoids depending on class-field/parameter-property initialization ordering). Split the picker trigger's read-only (permanent: <span> + aria-readonly) state from the resolving state (transient: <a> stays focusable, slot gets .disabled class, aria-disabled is set). Click is blocked at the picker level by an in-flight resolve check in _showPicker. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 650352e6 · 2026-05-21
- 1.0ETVsessions: show status of remote connections, reconnect AH connects (#306538) * sessions: show status of remote connections, reconnect AH connects - Add automatic reconnect with exponential backoff (1s-30s) when a remote agent host WebSocket connection drops, preserving the session cache during reconnect attempts - Add RemoteAgentHostConnectionStatus enum (Connected/Connecting/ Disconnected) to IRemoteAgentHostConnectionInfo and expose it on ISessionsProvider via an observable - Add reconnect(address) method to IRemoteAgentHostService for explicit reconnect with reset backoff - Always show configured remote hosts in the workspace picker with connection status indicators and a gear button for management - Gear menu offers Reconnect, Remove Remote, Copy Address, Open Settings, and Show Output actions via quickpick - Remote host browse actions are grouped into the "Select..." submenu alongside other providers when multiple providers exist  * address PR review comments - Fix outputChannelId mutability: use getter + setOutputChannelId() - Fix disposable leak on reconnect: dispose old entry in _connectTo() - Remove duplicate AGENT_HOST_LABEL_FORMATTER registrations from contribution files; centralize in AgentHostFileSystemService - Fix duplicate IRemoteFilesystemConnection: re-export from provider - Localize all user-facing status/hover/quickpick strings properly - Fix setTimeout leak: track timer in _renderDisposables - Register authority disposal in agentHostChatContribution - Re-setup ConnectionState when clientId changes on reconnect * fix tests for new connection status behavior - Update remoteAgentHostService tests: connections now include Connecting/Disconnected entries, use waitForConnected() helper, add status field to deepStrictEqual assertions - Add IAgentHostFileSystemService stub to agentHostChatContribution test setupgithub.com-microsoft-vscode · de413b28 · 2026-03-31
- 1.0ETVagent host: negotiate protocol version + surface incompatibility in UI (#314262) Adopt the AHP protocol's WebSocket-style version negotiation: clients now send `protocolVersions: string[]` (SemVer) and the server picks one, returning `UnsupportedProtocolVersion` (-32005) with a typed `UnsupportedProtocolVersionErrorData { supportedVersions }` payload when nothing matches. Removes the legacy numeric `PROTOCOL_VERSION` / `MIN_PROTOCOL_VERSION` / `capabilitiesForVersion` API in favor of the generated registry under `state/protocol/version/`. Surface the new error to users in the agents workspace picker: - `RemoteAgentHostConnectionStatus` is now a discriminated union with a new `incompatible` variant that carries the host's rejection message, the versions we offered, and the versions the host advertised. - The picker entry for an incompatible host renders with `Codicon.warning`, an "Incompatible" label, and a hover that includes the host's message. - Clicking the entry opens the management quickpick with a title ("Options for <label> (<address>)") and a sticky `Severity.Warning` validation banner explaining the version mismatch and pointing at how to recover. Other failure states are unchanged. - Auto-reconnect is suppressed only on -32005; network-level failures keep their existing exponential backoff. Manual Reconnect clears the state and retries. WebSocket, SSH, and tunnel paths share one helper (`RemoteAgentHostConnectionStatus.fromConnectError`) so they all surface incompatibility identically. Tests updated to the new wire shape; new server-side test covers the -32005 rejection path, new client-side tests cover the offered SemVer array and the typed error data, new tests cover the picker label, hover, and validation banner.github.com-microsoft-vscode · e1a89568 · 2026-05-04