vscode — Engineering Performance
89 engineers all time · Jan 2025 – Aug 2026 · built 2026-08-23 · GitHub
Performance snapshot
Today's rolling 90-day reading for vscode, compared with the start of the series. Pick a window to move that comparison point.
Eff. capacity added
+482.9engineers
64 devs deliver like 547 (8.5x pre-AI)
Avg. perf / dev / mo (ETV)
+321.9%
1.74 → 7.35
Active engineers
+39.1%
46.0 → 64.0
Features
−5.5pp
43.1% → 37.6%
vscode vs. Microsoft
Per-engineer ETV for vscode against Microsoft as a whole. Both lines are 90-day rolling averages scaled to a 30-day month, so they share one axis and can be read against each other at any point. Pick a window to zoom the chart to it.
Performance over time
ETV stacked by Features / Maintenance / Tests / Docs / Fixes — 90-day moving average, normalized to ETV / month.
Engineering capacity
Effective engineers behind vscode, in pre-AI terms. Per-engineer ETV divided by the Q1 2025 baseline of 0.86 ETV / dev / mo gives a capacity multiple, and that multiple applied to the engineers active in the trailing 90 days turns it into engineer-equivalents. The line is the real headcount, so the gap between line and area is what the leverage is worth.
Knowledge concentration
How dependent is this repo on a small number of engineers? Higher top-1 share = higher key-person risk.
roblourens owns 7.0 % of commits.
Reports
Written summary of the work completed each month.
No monthly reports available yet.
Top engineers
Most impactful commits
Top 10 by ETV in the all-time window.
- 17.5ETVagentHost: make the orchestrator own session enumeration and chat lifecycle (#329633) * agentHost: relocate Session ownership into the orchestrator (T2/T4) Make the orchestrator (AgentService + AgentHostStateManager) own the Session concept - identity, lifecycle, and grouping - so the agent harness talks only in chats. Session provisioning stays agent-specific but is now invoked through the chat surface instead of a Session-typed method, honoring "represent, don't orchestrate". - Create: `_provisionSessionViaDefaultChat` allocates the session URI and drives `chats.createChat(defaultChatUri, { provisionSession })`; the agent's provisioning runs inside creating the default chat and returns `IAgentCreateChatResult.provision`. - Dispose: routes to `chats.disposeChat(defaultChatUri)`. - Enumerate: `_enumerateProviderSessions` groups `listConversations()` into sessions via the default-chat URI convention. Gated per harness by `IAgent.orchestratorOwnsSession` (Codex, Claude, Copilot all opt in). Storage-preserving: session URIs and the derived `sdkSessionId == session raw id` (I3) are unchanged, agents read/write the same SDK stores, and providerData / PEER_CHATS_METADATA_KEY / protocol types are untouched. The legacy createSession/disposeSession/listSessions remain as the delegated fallback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: drop orchestratorOwnsSession opt-in; chat surface is the single path Address review feedback: the agent should not declare an orchestration policy, and the interface should not carry an optional flag that splits behavior. The opt-in was transitional scaffolding for a per-agent rollout; all harnesses have migrated, so remove it and make the orchestrator drive the chat surface unconditionally. - Remove `IAgent.orchestratorOwnsSession`; make `listConversations` required. - `AgentService` always provisions (non-fork/import) / disposes / enumerates through the chat surface; no per-agent branch. - Drop the flag from Claude/Copilot/Codex. - Make both test mocks first-class chat-surface agents (provisionSession bridge, default-chat disposeChat, listConversations) so their existing createSession/ disposeSession assertions still hold via the bridge. - Update the routing test to assert session create/dispose now also flow through the chat surface; refresh the architecture doc. Storage-preserving; no protocol/data change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: trim verbose comments on the T2/T4 session-ownership code Shorten the JSDoc/inline comments added for the session-ownership relocation to 1-2 sentences per the coding guidelines; drop obvious per-field comments. No behavior change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: drop redundant session-typed methods from IAgent (Category C) Remove `listSessions` and `getSessionMessages` from the IAgent contract - they are superseded by `listConversations` and `chats.getMessages`. Reroute the one remaining internal caller (the restore metadata catalog fallback) to `_enumerateProviderSessions` (which uses `listConversations`). The harnesses keep those methods privately as the implementation their chat/conversation bridges delegate to. `createSession`/`disposeSession` stay on IAgent as the session-lifecycle provisioning primitives the chat-surface bridge delegates to; `createSession` is also still used directly for fork/import, whose session id is minted server-side (sessions.fork) and so cannot fit the orchestrator-allocates-URI seam - left as a documented follow-up. No behavior change; storage-preserving. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: rename IAgent.getSessionMetadata to getConversationMetadata Align the single-item metadata lookup with the chat-addressed conversation surface: the method is now keyed by a chat URI and returns IAgentConversationMetadata, mirroring listConversations. All five implementers (Copilot, Claude, Codex, and both test mocks) derive the session from the chat URI and return chat-keyed metadata; the orchestrator maps the default-chat URI back to a session when hydrating restore metadata. Also reframe the fork/import createSession path in MULTI_CHAT_ARCHITECTURE.md from a deferred follow-up into a permanent, by-design exception (the fork id is minted server-side by the SDK, so the orchestrator cannot pre-allocate the URI). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: clarify IAgentConversationMetadata._meta is session-generic by design Document why the field keeps the SessionMeta alias rather than a conversation-specific type: _meta is the protocol's open property bag on SessionState / SessionSummary, carried through verbatim. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: clarify Claude disposeSession takes the agent's own SDK session URI Document that the session parameter is the provider's own SDK session (the SDK's terminology), NOT the AH-level Session grouping - that grouping lives in the orchestrator and the agent only ever deals in chats. The URI backs the default chat (invariant I3), so chats.disposeChat routes here when a default chat is disposed; peer chats go to _disposeChat. Teardown disposes that SDK session plus the peer-chat backings the agent parents under it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: document the AH-session vs SDK-session terminology convention Add a 'session is overloaded' convention table to the Mental Model section: in the protocol/orchestrator 'session' means the AH grouping; inside an agent harness it means the provider's own SDK session (Codex: thread); at the IAgent seam the session URI is a shared identity (AH-minted, SDK-session-id raw id per I3). Explains why we do not rename the provider-internal 'session' symbols. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: make IAgent enumeration session-keyed (orchestrator owns session->chat) Revert the chat-keyed enumeration surface (listConversations / getConversationMetadata) back to session-keyed listSessions / getSessionMetadata on IAgent. Chat-keyed enumeration forced every harness to derive default-chat URIs via buildDefaultChatUri for cold (SDK-discovered) sessions it never created in-process - re-deriving the session<->default-chat encoding that belongs to the orchestrator/protocol. Now each agent returns its own SDK-session identity (AgentSession.uri: provider scheme + SDK id, no protocol-chat knowledge) and the orchestrator owns the session->chat mapping. Drops the orchestrator's _conversationToSessionMetadata bridge (the enumeration/restore round-trip) and deletes the now-unused IAgentConversationMetadata type. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: stop agents synthesizing default-chat URIs at runtime Agents no longer call buildDefaultChatUri. Outbound events, default-vs-peer comparisons, and session-or-chat normalizers now reuse the chat URI the agent was already given - read back from the session entry's stored defaultChatKey (new getter on AgentSessionEntry) or the live session's stored chat channel, or tested with isDefaultChatUri - instead of re-deriving it from the session URI. The one irreducible conversion (a session URI first born inside the agent: a freshly forked SDK-assigned id, or a cold-restore/create seed) is centralized in a single node-layer helper, defaultChatUriForSession, in agentPeerChats.ts. This is creation-time only; no runtime routing/event path derives chat URIs anymore. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agents: reuse orchestrator default-chat URI on the provision path The provision (create) path already hands the agent the orchestrator-allocated default-chat URI via createChat(defaultChatUri, { provisionSession }). Claude and Codex decoded it to a session and then re-derived the identical URI inside createSession. Thread the supplied chat URI straight through (createSession's new optional defaultChat argument) so the agent seeds its entry with the URI it was handed instead of re-deriving the session-to-default-chat mapping itself. Copilot has no synchronous create seed (it stores a provisional session and seeds the default-chat key at materialize/resume), so it has no provision round-trip to thread; its derivations are the restart-lazy category. The remaining defaultChatUriForSession callers are the restart-lazy paths (cold resume, peer-send provisional default, fork/restore materialize) where the orchestrator supplies no chat URI in-call; documented as the single sanctioned, irreducible conversion. Behavior is unchanged (the mapping is deterministic); two Claude tests that deep-equal the emitted URI object are aligned with the file's toString-based convention since keying now populates the URI's cache. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: flatten provider chat bindings Make Agent Host own chat membership and pass contextual data only for individual operations. Providers route exact chats to their SDK conversations without deriving default or peer roles. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: make chat lifecycle exact and retry-safe Post-merge repairs and review follow-ups for the AH-owned multi-chat architecture, keeping providers on exact chat-to-SDK bindings: - Make `IAgentChats.releaseChat` mandatory so AgentService has one exact-chat release path with no optional legacy fallback; Claude, Copilot, Codex, and the test agents implement it explicitly. - Copilot chat disposal now propagates SDK deletion failures (preserving routing/state for retry) but tolerates an already-deleted session via an O(1) `getSessionMetadata` recheck, keeping a partially-completed multi-chat teardown retry-safe. - Claude: gate materialization on post-await cancellation, abort every live session's controller on dispose, and restore session-addressed resume without inferring chat membership from the URI. - Rename `IAgentCreateChatOptions.provisionSession` to `newSession` to state intent (this createChat creates the owning session). Verified typecheck, transpile, AgentService/Claude/Copilot/Codex unit suites, valid-layers, and hygiene. * agentHost: restore subagent transcripts via the chat-surface getMessages Copilot's `chats.getMessages` routes to `_getChatMessages`, which lacked the subagent-session-URI branch that only lived in the now-orphaned `getSessionMessages`. On the persisted replay/restore path the orchestrator loads a subagent's turns through the chat surface, so reopening a session rebuilt an empty subagent transcript — failing the "reopening a session keeps sub-agent messages out of the parent transcript (replay path)" E2E test on all platforms. Extract a shared `_getSubagentMessages` helper and route subagent URIs through it from both `_getChatMessages` and `getSessionMessages` (matching Claude, which already shares one path). Also address PR review feedback: - `AgentService._releaseSession` releases every catalog chat even if one rejects, then propagates the first error (idle eviction has already dropped the session state, so a skipped leaf would stay resident indefinitely). - `CopilotAgentSession` stores the host-supplied `IAgentChatContext.resource` as its persistence scope instead of re-deriving it from the mutable chat channel via `isDefaultChatUri`, so an explicitly chosen resource survives a later `bindChatChannel`. - MULTI_CHAT_ARCHITECTURE.md: correct the flat `IClaudeChatBinding` shape (`{ sdkSessionId, model? }`, no retained session/storageUri). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: orchestrator owns session provisioning; agents only create chats Removes the `newSession` seam so an agent no longer distinguishes "a chat for a new session" from "a chat for an existing session". Session provisioning now always goes through the agent's dedicated `createSession` + `chats.bindSessionChat` (the same path fork/import already used), and `chats.createChat` has exactly one meaning: add an additional chat to an already-provisioned session. Contract: - Delete `IAgentProvisionSession`, `IAgentCreateChatOptions.newSession`, `IAgentProvisionResult`, and `IAgentCreateChatResult.provision`. - Add `IAgentCreateChatOptions.inheritedContext` ({ workingDirectory, config }): the orchestrator supplies the owning session's resolved context when creating an additional chat, so the agent never reads it back from the parent session. Orchestrator: - `_createProviderSession` always provisions via `createSession` + `bindSessionChat`; delete `_provisionSessionViaDefaultChat`. - `_buildInheritedChatContext` resolves the AH-owned worktree/folder + session config values and passes them to `chats.createChat`/`fork`. Agents (Claude, Copilot, Codex): - Drop the `if (options.newSession)` branch and the `_provisionChat` method; the chat surface handles additional chats only. - Claude/Copilot consume `inheritedContext` for the additional-chat working directory (and Claude for its permission mode) instead of resolving the parent session; remove the now-dead `_createSession(target)` plumbing where the provision path was its only caller. Tests/docs: - Rewrite the AgentService routing test to assert provisioning via createSession + bindSessionChat. - Update MULTI_CHAT_ARCHITECTURE.md §2/§7 to the new seam. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: enable multi-chat for Codex (base for I3-removal branch) Adds Codex multi-chat support (parity with Claude/Copilot): the `multipleChats: { fork: true }` capability, `chats.createChat`/`chats.fork` minting a fresh backing Codex thread per chat, `materializeChat` restore, and a providerData codec. This is committed as the base of the dedicated I3-removal branch (it is intentionally not on the PR branch). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: add orchestrator-owned session registry (I3 removal stage 1) Introduce AgentSessionRegistry, a durable, orchestrator-owned index of the sessions that exist, keyed by session URI and persisted as a JSON blob in a reserved session database with serialized read-modify-write. Wire it into AgentService: register on every createSession success and on restoreSession, unregister on true delete (disposeSession). Add a Stage 1 validation surface (getRegisteredSessions) plus component and parity unit tests. This is additive and does NOT yet drive enumeration; listSessions still uses the provider-derived path. It is the foundation for switching enumeration off invariant I3 in stage 2. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: enumerate sessions from the registry, not providers (I3 removal stage 2) Switch AgentService.listSessions to iterate the orchestrator-owned session registry instead of unioning each provider's listSessions(). Per-session metadata still comes from the agent's direct getSessionMetadata lookup (I3 keeps the default chat's SDK id == session id, so it resolves), then flows through the existing DB and state-manager overlays unchanged. This decouples AH enumeration from the agents' SDK stores: peer-chat backings and subagent sessions never enter the registry (so they cannot leak as top-level entries), and a provider that transiently drops a session from its own snapshot no longer evicts it. Idle provisional sessions are suppressed explicitly via a new state-manager predicate (isIdleProvisionalSession), preserving #321269 now that the registry — not the provider snapshot — is the session source. A one-time, marker-gated backfill seeds the registry from the legacy provider enumeration so hosts created before the registry keep their on-disk sessions. I3 is unchanged; agents are untouched. Adds backfill and transient-drop tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: clarify Codex is already I3-decoupled (I3 removal stage 3a) Codex's default chat does not actively satisfy I3: a fresh session's raw id is an AH-minted provisional UUID while its backing thread id is app-server-assigned, with the real mapping persisted in the per-session metadata overlay. The residual sessionId == threadId uses (_readSession's ?? sessionId fallback and listSessions' thread->URI mapping) are legacy-compat shims for pre-existing sessions whose persisted identity is the thread id; they cannot be removed without a data migration (disallowed), so Codex is treated as already I3-satisfied. Comment/doc-only: clarifies the two shim sites and adds a per-agent nuance note to the I3 invariant in MULTI_CHAT_ARCHITECTURE.md. No behavior change. The active I3 removal targets are Claude and Copilot. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: collapse fresh-session provisioning into chats.createSessionChat (I3 removal stage 4, step 1) Add an optional chat-surface entry, chats.createSessionChat, that provisions a session AND binds its session-backed (default) chat in one call — the replacement for the IAgent.createSession + bindSessionChat provisioning pair. The agent reuses the session id as its SDK id (id-reuse kept; no storage change, no I7 for the default chat). The orchestrator mints the session URI, derives the default-chat URI, and calls createSessionChat; agents that don't implement it fall back to the create-then-bind pair. Claude implements it via its existing { kind: 'chat' } provisioning path (also used by truncate), so routing state is identical to create-then-bind. Only fresh sessions collapse: fork and import mint a fresh SDK-assigned session id inside the agent, so the orchestrator can't know the default-chat URI up front and keeps them on the create-then-bind pair. bindSessionChat is now documented as the restore-time counterpart. Additive and always-green: Copilot/Codex still use createSession. Validated typecheck, layers, eslint, hygiene; Claude units 206, AgentService 140, Claude E2E replay 8. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: implement chats.createSessionChat in Copilot and Codex (I3 removal stage 4, step 2) Both agents now provision a fresh session and bind its session-backed (default) chat through the collapsed chats.createSessionChat entry, delegating to their existing _createSession and then binding the default chat (id-reuse; no storage change, no I7 for the default chat). The orchestrator already prefers this path for fresh sessions across all providers; fork/import still use createSession. Validated typecheck, layers, eslint, hygiene; Copilot 347, Codex 47, AgentService 140 units; E2E replay Copilot 15 / Codex 6 / Claude 8. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: enable Codex multi-chat capability Advertise Codex multiple-chat and fork support now that the exact chat binding, model-provider forwarding, and registry-owned enumeration paths are complete. Keep provider-owned side chats disabled for Codex. Add replay-only parity gating for Codex model-backed peer/fork tests. Host-only capability checks and conformance catalog/lifecycle coverage remain enabled; recording mode still runs the gated tests once the documented live Codex recording defect is fixed. No capture files are fabricated or hand-edited. Validated typecheck, layers, ESLint, Agent Host unit suites, and Claude/Copilot/Codex strict replay. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: allow recording gated multi-chat E2E tests Keep Codex model-backed peer/fork tests skipped in strict replay while permitting both focused recording modes to execute them and generate fixtures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: harden session registry and chat lifecycle Make registry load/write mutations durable and retryable, require successful provider enumeration before marking backfill complete, and unregister before irreversible deletion. Dispose every peer and always run provider-level session finalization before surfacing the first error. Harden Codex workspace-less peer/fork managed-directory ownership across create, release, restore, and disposal; refresh an empty model catalog before validating restored provider-qualified models. Remove unsupported multi-chat capability from ScriptedMockAgent and add regression coverage for every reported failure/retry path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: remove Claude default-chat URI inference Use exact chat state routing and retain only the legacy bare-session compatibility path.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: make chat backings session-neutral Give every provider an exact default-chat backing, keep Agent Host authoritative for membership and lifecycle, and isolate provider enumeration to legacy discovery.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: dispose legacy Claude sessions Retain exact default-chat disposal while falling back to an unbound same-ID SDK conversation for direct legacy provider callers.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: route peer session events to owners Normalize session-scoped progress from exact chat resources, keep Codex peer lifecycle off backing session URIs, and resolve peer configuration through the owning AH session.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: restore Codex peer chat history Resume cold Codex peer threads before reading their turns and honor the persisted replacement thread ID. Share concurrent resume work with the first send and suppress idle usage notifications emitted during restore.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: update AgentService worktree deletion stub Use the current prepare/remove worktree deletion contract so durable registry retry coverage reaches the expected cleanup path.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: fork the exact Copilot source chat Pass the orchestrator-owned default chat channel through session forks so Copilot resolves independent SDK backings. Preserve refork support when imported protocol turn IDs already match provider event IDs.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: clarify btw command input Document that selecting the slash command consumes the command token, so the remaining input must contain only the side question.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Restore persisted subagent chats Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Store orchestrator state separately Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Attach restored peer rejection eagerly Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Cancel session cleanup before revival Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Enforce Agent Host routing channels Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use plural session working directories Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Apply provider feedback consistently Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clarify provider chat backing terminology Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Stop inferring chat role from resource Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Simplify provider chat resolution Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Require exact source chat for forks Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Let providers observe session config Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Restore subagent transcripts lazily Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Complete chat-only provider ownership Route provider provisioning, restore, lifecycle, configuration, and active-client behavior through exact chat-addressed seams. Preserve additive legacy default-chat migration across Claude, Copilot, and Codex and remove obsolete session compatibility paths. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix chat test field initialization Avoid directly reading the overridden chat surface from subclass field initializers so define-class-fields compilation remains safe. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Keep session chat roles in Agent Host Move legacy backing selection and session-versus-peer materialization filtering into Agent Host. Providers now recover or materialize exact opaque chat backings without retaining session/peer classifications. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Make provider chat creation uniform Remove provider-visible chat role classification and collapse runtime initialization and additional chat creation into one createChat operation. Document and test the registry backfill's idempotent, coalesced migration behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Flatten provider chat creation Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove session ownership from agent chats Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address active clients by chat Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Make agent provider seams chat-only Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Organize agent provider contract Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Group legacy chat recovery APIs Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Document agent capability optionality Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Separate agent provider model Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix cold peer-chat fork to read source chat's own persistence resource Cold peer-chat fork previously read the shared configurationResource overlay instead of the source chat's own persistence resource, so inherited model/agent/permissionMode came from the wrong scope for any non-default source chat. _chatConfigScopes now records both the configurationResource and the exact resource (IChatScopeBinding) for each chat, and _bindInheritedConversation reads the source overlay by the source's own resource. Also adds a backing-model fallback for a source that was created but never materialized. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add regression tests for cold peer-chat fork scope inheritance Covers two scenarios for the claudeAgent.ts fix (commit aabdead86d7): - a peer chat materialized before a cold restart forks with its own model/agent/permissionMode/workingDirectories, not the session-wide decoy overlay - a peer chat never materialized before a cold restart still recovers its model via the _chatBackings fallback Also adds a per-resource-aware ISessionDataService test double, since the shared sessionTestHelpers.ts fake ignores the resource argument and returns one flat database for all resources, which would otherwise mask the session-vs-peer overlay bug. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Complete Agent Host chat ownership migration Make session registry migration durable, preserve exact chat backings across provider restore and lifecycle paths, and harden deletion and rollback behavior. Rename the architecture spec and add regression coverage across providers, migration, concurrency, and protocol restore. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Restore Agent Host checkpoint lifecycle * Fix Agent Host CI test portability --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>Sandeep Somavarapu · 150119bd · 2026-08-12
- 9.3ETVgithub: add reusable platform API service (#330673) * Phase 1: GitHub API service foundations with transport, coordination, and deterministic testing - Enhance AgentHostAuthenticationService with token generation tracking and lifecycle - Implement GitHubScheduler, GitHubRequestQueue, GitHubRateLimitCoordinator for deterministic coordination - Implement GitHubTransport with no-store REST/GraphQL, exact ETag/body caching by account, request coalescing, priority queueing, retry with deterministic jitter - Implement GitHubCredentialService with stable account resolution via /user probe, generation-scoped caching, automatic invalidation on 401 - Implement GitHubHostCapabilitiesService with schema probing, fail-closed defaults, endpoint-change resets - Convert AgentHostOctoKitService to adapter using new transport stack, preserving behavior compatibility - Wire new services into AgentService with auth-required forwarding for credential/endpoint changes - Create ProgrammableGitHubServer loopback test helper with ordered REST/GraphQL scripting, ETag/304, redirects, delays, rate-limit, errors, disconnects - Create FakeGitHubScheduler for deterministic time control with injection, due-time scheduling, positive deterministic jitter - Add comprehensive unit tests for transport (no-store, caching, coalescing, rate-limit, priorities), credentials (stable account, generation tracking, invalidation), capabilities (probing, error handling), and schedule (advancement) - Fix review findings: dual-resource endpoint-change auth, legacy-token resurrection blocking, transient capability failure caching, GraphQL rate-limit coordination Type-checked; 18 new files, 6 modified production files, all tests deterministic. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: add shared GitHub pull request reads Introduce normalized pull request fragments, capability-aware request planning, canonical shared resources, independent polling, complete conversation and checks pagination, mergeability fallbacks, and generation-safe lifecycle handling. Also include the reviewed Phase 1 transport and coordination corrections that these resources depend on.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: add safe GitHub mutations and diagnostics Add typed idempotent comment and review-thread mutations, workflow diagnostics and rerun reconciliation, bounded redacted log downloads, expected-head branch updates, generation-anchored merge preparation, direct merge reconciliation, and merge-queue enrollment.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: complete typed GitHub service parity Add shared repository and issue resources, comparison and pull request context queries, viewer work searches, issue linkage, behavior-compatible lookup operations, typed pull request creation and auto-merge, GHES capability handling, and the final internal service facade.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: group GitHub implementation files Move GitHub contracts, implementations, and focused tests into dedicated github folders.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: expose a single GitHub service Collapse GitHub credentials, transport, capabilities, queries, pull request resources, and mutations behind one IGitHubService composition root. Keep only the endpoint configuration and legacy OctoKit adapter as separate compatibility services, update moved imports and coverage paths, and remove the implementation plan from the branch.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * github: add reusable platform service Move the new GitHub API implementation into src/vs/platform/github behind caller-supplied endpoint and token providers. Keep all existing Agent Host and Sessions GitHub/auth behavior unchanged; AgentService only constructs and registers the new service for future adoption.\n\nCo-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * github: reconcile pull request resource aliases Converge concurrent old and canonical repository subscriptions onto one scheduled entry while preserving issued resource handles. Reject review-thread pages and in-flight results that no longer match the current pull request head. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * github: add service diagnostics Add privacy-safe debug and trace logging for credential, transport, capability, resource, query, and mutation lifecycles. Cover the service path with a regression that verifies tokens and response payloads are not logged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * github: fix service hygiene Resolve the platform GitHub ESLint findings while preserving asynchronous request, scheduler, and loopback test behavior. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * github: retrigger CI after hygiene fix Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>Benjamin Christopher Simmonds · ff1603fb · 2026-08-14
- 8.1ETVAdd TypeScript 7 context support (#331798) * First cut of TS7 context * WIP * Bind events correctly * First TS7 implementation. * First cut of TS7 context providers * Minor improvements * Bug fixes for TS7 context provider * Add setting to enable TS7 language context * Use getSymbolsInScope * Implement nes rename on TS7 Api * First cut of code review * Add the TS7 enablement settings * Some bug fixes * Some final fixes * Make the shared API work * Reject nes rename on symbols from libs * Consider typescriptteam.vscode-typescript extension id * Move tests to test folders * Fix registration code. * Handle cancellation correctly * Fix test case and awaits * Make inflight request fail save * Implement correct dispose * Fix failing test * Potential fix for pull request finding Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> * Use 7.0.2 again --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>Dirk Bäumer · b0b3635a · 2026-08-21
- 6.6ETVOmni-chat with multi-session routing (#326698)Megan Rogge · 49af1f71 · 2026-08-07
- 5.7ETVEnable chat input pill features by default on insiders (#331724) * Chat input pills: reusable widget, artifacts, customizations and visibility Rework the pill row above the Agents-window chat input: - Left-align the row and make it horizontally scrollable, with a reusable observable-driven ChatPillsWidget in the workbench layer. Sessions owns the adapters from session state so the workbench layer never imports sessions. - Add chat.agentSessions.showSessionMetadataInInput, which moves the session header metadata pills down into the input row, hides the header second row, moves Chats into the title toolbar and shows workspace metadata inline. - Add agent-host artifact tools (add/remove/list_artifacts) with persistence, a gating setting and an artifacts pill. GitHub pull request and issue artifacts are promoted into the session GitHub links rather than shown twice. - Derive the customizations a chat used or read from its output stream and surface them in a customizations pill that reveals the picked entry in the customizations editor. - Add a right-click visibility menu for the row, with Hide <pill> for the clicked pill and kinds grouped by whether they have data. Customizations and Subagents start hidden; Changes can never be hidden. - Consolidate pill rendering onto one base plus four implementations: icon and label, dropdown, resource label, and the animated changes pill. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * also add this to the pr * Fix chat pill rendering crash from space-separated class names `classList.add` rejects tokens containing spaces, so the changes and resource pills threw while rendering. Subclasses now contribute a single modifier class instead of the full class list, which makes the mistake impossible, and the base always applies the shared classes. Port the changes pill's styling onto the shared pill classes and retire the now-dead chatTurnPills.css, whose rules all targeted the pre-refactor DOM. Cover the render path of every pill implementation, which is what CI caught and the existing unit tests missed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review feedback on chat input pills - Restrict artifact `link` to http(s). A link is opened with `openExternal`, so a `file:` or custom-scheme link would reach the OS protocol handler from an agent-labelled pill. - Never let promotion lose an artifact. A GitHub reference is only removed from the artifacts pill when the GitHub pills actually surface it, so a session with no repository, or a reference belonging to another repository, keeps showing it. References from another repository are also no longer polled against the checkout's coordinates. - Let the dropdown pill's trigger close its own dropdown, and expose `aria-haspopup`/`aria-expanded` while it is summarized. - Keep the Windows drive prefix attached when matching customization paths, so `C:\repo\...` resolves. - Derive a plugin's container folder from its type rather than basename punctuation, so a versioned root such as `plugins/foo/1.2.0` no longer claims its sibling roots. - Gate customization data presence on the turn-status setting, without gating it on visibility, which would drop the pill from the menu that restores it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Show session metadata above the chat input by default on insiders `chat.agentSessions.showSessionMetadataInInput` now defaults to on for non-stable builds, matching `chat.artifactTools.enabled`, which already uses the same gate. Stable keeps the session header's metadata row. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>Benjamin Christopher Simmonds · 8629d2d1 · 2026-08-19
- 5.5ETVTerminal output compaction code (#325937) * logging compaction hint * splitting and checking against split tokens * adding compaction experimentation code * removed the other telemetry lines * removing useless codeAiday Marlen Kyzy · fa94ee6b · 2026-07-16
- 5.4ETVAutomations: Management UI (create/edit dialog, list widget, ChatInputPart integration) (#323914) * feat(automations): add management UI — list widget, create/edit dialog, modal polish Adds the complete automations management interface: - AutomationsListWidget: WorkbenchList-based view with run status, dynamic row heights - Create/Edit dialog: ChatInputPart-hosted prompt editor with ghost text - WorkspacePicker integration for folder selection - Isolation mode dropdown (Worktree/Folder via ActionListWidget) - Static 'Copilot CLI' harness chip (future picker placeholder) - Schedule configuration (Manual/Hourly/Daily/Weekly with time/day pickers) - Permission level and model selection via ChatInputPart toolbar - CSS styling matching form field backgrounds to prompt editor - PlaceholderTextContribution registered on ChatInputPart editor - List widget tests Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix(automations): polish isolation chip and fix its default label Add a hover highlight and remove the redundant chevron so the isolation chip matches the new-session picker. Fix the chip showing 'Folder' for an unset isolation mode: the label now derives from !== 'workspace', so an undefined mode reads as 'Worktree' to match the picker, provider, and run defaults (previously it lied and the session ran as a worktree). * fix(automations): replace unknown fontWeight-medium with semiBold The stylelint rule flags --vscode-agents-fontWeight-medium as unknown. Only regular and semiBold are registered in vscode-known-variables.json. Use semiBold for form labels — visually equivalent for this context. * fix(automations): address review findings — CCR patterns, test gaps, bug fixes - Remove 33 em dashes from comments - Compress 5 over-length JSDoc blocks to 1-2 sentences - Fix semicolons-as-conjunctions in comments - Track rAF via MutableDisposable (use-after-dispose fix) - Switch runNow to CancellationToken.None (phantom CTS removal) - Restore defensive typeof guard in getCategoryLabel - Re-add ILabelService for URI display in remote contexts - Add tests: openEditDialog error, openCreateDialog, runNow failure, resetLanguageModelToDefault - Add race-safety comment in createSessionTypeBinder * refactor(automations): replace querySelector toolbar injection with menu-driven actions Migrate the harness chip and isolation group from DOM surgery (querySelector on ChatInputPart internals) to the structured MenuId + actionViewItemProvider pattern used by the New Session Page. - Register OpenAutomationsHarnessChipAction on MenuId.ChatInputSecondary - Register OpenAutomationsIsolationGroupAction on MenuId.ChatInputSecondary - Gate both with ChatContextKeys.inAutomationsDialog context key - Add secondaryToolbarActionViewItemProvider to IChatInputPartOptions - Route custom items in ChatInputPart secondary toolbar provider - Remove querySelector and eslint-disable-next-line comments * fix(automations): honor storeSelection in setChatMode2, handle hidden saved modes - setChatMode2 now gates _syncInputStateToModel behind storeSelection, preventing unintended persistence of transient mode changes. - automationDialog detects when a saved mode is hidden by the hideCustomChatModes filter and falls back to default instead of setting up an infinite retry watcher. * feat(automations): restore accessibility help provider and fix a11y issues * Signing commit * fix: correct indentation in dialog.ts focus-out handler * Signing commit --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>Ben Villalobos · 4c959fa6 · 2026-07-02
- 5.3ETVInitial revision of automated release sanity checks. (#280857)Dmitriy Vasyura · b1bf400d · 2026-01-09
- 5.1ETVsessions: single-pane layout as a sibling controller with composed strategies (#324657) * sessions: fix base-controller single-pane leak via Template Method hooks (R1) Move the single-pane branches out of BaseLayoutController into SinglePaneDesktopSessionLayoutController via three protected hooks (_suppressEditorVisibilityDuringRestore, _shouldRevealEditorPartOnApply, _shouldRevealEditorPartForEmptyWorkingSet). The base controller no longer reads isSinglePaneLayoutEnabled. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: segregate docked-editor layout concerns into IDockedEditorLayout (R3) Extract handleDockedEditorPartLayout and isEditorRevealedExplicitly into a focused IDockedEditorLayout interface that IAgentWorkbenchLayoutService extends, keeping the cross-cutting isSinglePaneLayoutEnabled and suppressEditorPartAutoVisibility on the main contract. Fix stale typo comment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: extract side-pane presentation Strategy from workbench (R2/R4) Replace the 26 scattered _dockDetailPanel branches in workbench.ts with an ISidePaneLayoutStrategy (GridSidePaneStrategy + DockedSidePaneStrategy), selected once at initLayout. DockedSidePaneStrategy owns the docked width, the DockedAuxiliaryBarController lifecycle, the reveal-sync, and a DockedEditorSizeMemento for the docked size bookkeeping (R4). Workbench implements ISidePaneLayoutHost and delegates geometry, grid-descriptor, visibility-mutator, and reveal-sync work to the strategy. Behaviour is unchanged in both layouts; the only remaining _dockDetailPanel reference is the strategy selection point. Rewrites workbench.test.ts to drive the real strategy through a host harness. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: replace side-pane Strategy with Workbench subclass (R5) Convert the composition-based ISidePaneLayoutStrategy into inheritance, matching the layout-controller Template Method pattern. The base Workbench now carries the classic (grid) layout as protected _-prefixed hooks; SinglePaneWorkbench overrides them for the docked detail-panel layout and owns the docked width, DockedAuxiliaryBarController, reveal-sync, and DockedEditorSizeMemento. A createSessionsWorkbench factory picks the subclass from the setting at construction; web.main.ts and sessions.main.ts use it. Removes sidePaneLayoutStrategy.ts and the ISidePaneLayoutHost callback interface. No behaviour change in either layout. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: single-pane editor part owns the auxiliary bar (R6) Make editor + auxiliary bar a single unit in the single-pane (new) layout by having the editor part create and own the auxiliary bar instead of the workbench/pane-composite service: - New SinglePaneMainEditorPart extends MainEditorPart; lazily creates the SinglePaneAuxiliaryBarPart via a getter and owns the DockedAuxiliaryBarController (created in create(), calling setContentRightInset directly). - EditorParts.createMainEditorPart() returns SinglePaneMainEditorPart when the shared shouldUseSinglePaneLayout(config) predicate is true. - AgenticPaneCompositePartService retrieves the same aux bar instance from the editor part in single-pane; classic/mobile create it as before. - SinglePaneWorkbench drops DockedAuxiliaryBarController ownership; keeps the docked width (exposed via getDockedAuxiliaryBarWidth/setDockedAuxiliaryBarWidth on IDockedEditorLayout) and reveal-sync, delegating layout to the editor part. - workbenchFactory, EditorParts, and the pane-composite service all select via the single shouldUseSinglePaneLayout predicate so the workbench, editor part, and aux bar are always chosen together (fixes a phone-viewport + setting-on mismatch that would pair SinglePaneWorkbench with a plain MainEditorPart). Classic (default) and mobile layouts are unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: make isSinglePaneLayoutEnabled class-based, not a config read Address review feedback: since the workbench subclass is selected at construction (Workbench vs SinglePaneWorkbench), isSinglePaneLayoutEnabled is now a class-level constant — false in the base, overridden to true in SinglePaneWorkbench — instead of reading DOCK_DETAIL_PANEL_SETTING at runtime. Removes the _configurationServiceForLayout field. This also aligns the flag with the phone-aware workbench selection, so it no longer reports single-pane on a phone viewport where the classic workbench is used. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: single-pane editor-group header menus, docked aux bar, and header styling - Make the full-width Changes header a group-level editor concept: the editor part configures header menu ids via IEditorGroupViewOptions.headerMenuIds and the editor opts in via IEditorPane.getHeaderActions(); EditorGroupView renders the menus (no concrete menu points leak into core). - Docked aux bar: top border connecting to the sash, and hide editor/aux when their sash collapses them. - Changes pill and file-diff open reveal the editor explicitly (revealEditorPartExplicitly), and close the Files tab when a real file opens. - Header styling: re-scope diff-stats/picker CSS via marker classes, restore inter-action spacing, and shrink the right toolbar buttons to 24px. - Fix setHeaderContent wiping freshly-rendered content on re-render; tie per-group header listeners to group removal. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: reparent single-pane layout to a sibling controller with composed strategies Make `SinglePaneLayoutController` a sibling of the classic desktop `LayoutController` (both extend `BaseLayoutController`) instead of extending it, so the desktop controller can be deprecated/deleted without affecting single-pane. Its behaviour is composed from focused strategy objects under `contrib/layout/browser/singlePane/`: - Detail (aux bar) ownership split in two — `SinglePaneDetailVisibilityStrategy` owns per-session shown/hidden memory (D1-D4); `SinglePaneDetailPanelStrategy` owns container selection (Changes/Files), maximize, browser-hide, and the nothing-to-show hide. Removed the overlapping `EmptyAuxCleanup` (D10) strategy and desktop's redundant saved-container machinery. - `SinglePaneManagedTabsStrategy` + `SinglePaneEditorAreaCollapseStrategy` share a `SinglePaneDockedTabsCoordinator`; plus `SinglePaneResponsiveSidebarStrategy` (Toggle Details), `SinglePaneNewSessionRulesStrategy` (R1), and `SinglePaneQuickChatEditorHideStrategy`. - Strategies coordinate through the controller via `ISinglePaneLayoutContext`. - Fresh per-session storage keys (`sessions.singlePane.*`) so single-pane never shares state with the classic controller. Fix a chain of new-session-submit / Detail-only bugs (all verified in-app): - New-session submit no longer reveals the docked editor or hides the just-opened detail. `onDidReplaceSession` fires before the controller's later-registered listener, so submit is detected intrinsically from the reactive transition (`!previousIsCreated && isCreated`); D3c leaves the detail as-is when a session has no saved state; the empty-editor-group hide is skipped during a layout restore. - Detail-only sessions no longer flicker the editor open on switch or reload: the editor-part grid view (which hosts the docked aux bar) no longer maps its visibility to `setEditorHidden`, the width-based reveal-sync bails while editor-part auto-visibility is suppressed, and the persisted editor width uses the node's real visibility so a reload restores the collapsed node width. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix component fixture screenshot CI Add the missing workbench layout service mock needed by the changes view fixtures and update blocks-ci screenshot hashes to the expected CI output. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: fix cramped Changes actions bar in the single-pane editor header The `ChangesActionsBar` marker (`.changes-actions-bar`) only carried a height rule in the single-pane editor-group header; the classic `.session-changes-editor-header-right` normalization does not reach that header, so the primary split-button and the trailing secondary icon actions rendered cramped together with no spacing or button chrome. Add the container flex/gap layout and the secondary icon-button chrome (padding, corner radius, secondary background/border + hover) keyed off `.changes-actions-bar`, using design tokens, so it applies in the single-pane editor-group header while staying idempotent for the classic internal changes-editor header (whose element also carries `.session-changes-editor-header-right` with the same values). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: match classic Changes actions bar chrome in single-pane editor header The single-pane editor-group header renders the Changes actions bar (`.changes-actions-bar`) inside `.editor-group-header-secondary`, where the high-specificity `editorgroupview.css` rules stretched the primary split-button but gave the trailing secondary icon actions (Mark as Done, Run Code Review) no inter-button gap and no button chrome, so they rendered flat and cramped against the dropdown chevron. Add, at matching specificity in `editorgroupview.css`, the container flex/gap and the secondary icon-button chrome (padding, corner radius, secondary background/border + hover) mirroring the classic `.chat-editing-session-actions` actions bar. Drop the equivalent low-specificity rules from `sessionChangesEditor.css`, which lost the cascade to the editor-group-header selectors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: fix single-pane Changes actions bar and move its styles out of core In the single-pane editor-group header the Changes actions bar renders as a toolbar action item inside a `.monaco-action-bar`, where the generic rule `.monaco-action-bar .action-item .codicon { width: 16px; height: 16px }` clamped every codicon — including the button elements themselves (which carry the `codicon` class), squashing the secondary icon buttons and detaching the split-button chevron. - Un-clamp the codicons and lay out the bar (primary split-button grows, trailing secondary icons stay natural size) scoped to `.monaco-action-bar .action-item.changes-actions-bar`, so the classic internal changes-editor header and the aux-bar Changes view are left untouched. - Move all `.changes-actions-bar`-specific rules OUT of core `editorgroupview.css` into the contributing component's `sessionChangesEditor.css`; core keeps only the generic header/toolbar layout. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: draw the single-pane header divider under the editor header/tab bar Move the single-pane detail-panel separator from the auxiliary bar's top border to a bottom divider on the editor header (spanning the editor content and docked detail), so the line runs the full header width. When the active editor has no header toolbars (e.g. Files), the divider is drawn under the tab bar instead so a separator is always present below the header row. The docked auxiliary bar is absolutely positioned over the right of the editor part with a solid background, so it would overlay the divider. Rather than fight it with z-index, start the aux bar one divider-thickness below the header/tab bar (new `DockedAuxiliaryBarController.DIVIDER` offset applied to the aux top/height and the resize sash), so its background sits just beneath the line. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: update docked aux geometry tests for the header-divider offset The docked auxiliary bar now starts one divider-thickness below the header/tab bar (`DockedAuxiliaryBarController.DIVIDER`), so its top and height shift by 1px (top 34->35, height 566->565). Update the two workbench geometry snapshot tests to the new expected values. Fixes the CI unit-test failures on the PR. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>Sandeep Somavarapu · e656eb8d · 2026-07-07
- 5.0ETVchat: add pet achievements and accessory rewards (#331883) * pet: add achievements and accessory rewards Add persistent cross-window pet achievements with six enabled rewards, a standalone collection modal, account badges, and semantic unlock triggers. Add the body-owned accessory rig and atlases, unlock star and New state, accessibility help, fixtures, and tests while retaining disabled rewards for later re-enablement. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5c8a4f1e-3bb0-4d6f-a3ed-249fbcd4ce15 * pet: address achievement review feedback Defer customization observation until the pet is enabled, detect newly installed MCP servers independently of enablement, and fully clear legacy fork state on reset. Rename the Crown persistence ID and use contrast-paired badge colors for the New affordance. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5c8a4f1e-3bb0-4d6f-a3ed-249fbcd4ce15 * pet: update model and skill rewards Reward changing the model picker selection with the Construction Hard Hat, and reward adding a custom skill with the Crown. Keep the instructions achievement and Sailor Hat disabled for future use. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5c8a4f1e-3bb0-4d6f-a3ed-249fbcd4ce15 * pet: fix component fixture asset loading Serve pet fixture media from the source tree used by both Vite and the CI rspack server, remove the intentionally empty screenshot variant, and approve the new blocking fixture snapshots. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5c8a4f1e-3bb0-4d6f-a3ed-249fbcd4ce15 * pet: accept component fixture screenshots Record the authoritative Linux CI hashes for the new blocking pet achievement and accessory fixtures. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5c8a4f1e-3bb0-4d6f-a3ed-249fbcd4ce15 * pet: restore fake timers within unlock test Avoid leaving the renderer test clock installed after the unlock-state interaction test so later notebook and notification suites can advance timers normally. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5c8a4f1e-3bb0-4d6f-a3ed-249fbcd4ce15 * remove unused achievements for now * pet: remove unrelated branch changes Restore server command, session artifact, and chat pill files to current main after they were accidentally included with the dormant achievement cleanup. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 5c8a4f1e-3bb0-4d6f-a3ed-249fbcd4ce15 --------- Copilot-Session: 5c8a4f1e-3bb0-4d6f-a3ed-249fbcd4ce15Justin Chen · eb2df9f4 · 2026-08-21