github.com-microsoft-vscode
all · 89 devs · built 2026-07-10
Repository snapshot
Monthly reports
Highlights
- A foundational *Automations subsystem* was introduced, providing core infrastructure for scheduled tasks with DST-safe scheduling, persistent storage, optimistic concurrency, and leader election [041ae8b0 · Ben Villalobos].
- Enhanced *chat tab management* with *browser-style keybindings* (Cmd/Ctrl+T, Cmd/Ctrl+Shift+T, Delete) for improved user experience in multi-chat sessions [e7bf9e83 · Sandeep Somavarapu].
- Accuracy of *AI agent tool call telemetry* was significantly improved and centralized for *Claude*, *Codex*, and *Copilot* agents, addressing parity gaps and providing richer insights [f18c6b4f · Tyler James Leonhardt].
- New *explainability* for *Copilot's auto-mode routing decisions* was implemented, allowing users to understand the rationale behind model and action choices directly in the *chat interface* [04b756ba · Logan Ramos].
- The *Sessions Changes view* gained a dedicated 'Session Files' section, offering visibility into agent-created, edited, or deleted files outside the workspace [63790479 · Benjamin Christopher Simmonds].
- A 'terminals' pill was added to the *session header meta row*, providing quick access and visibility into a session's terminal activity and commands [35f6ba07 · Benjamin Christopher Simmonds].
Observations
- The *Maintenance* score increased by 48% (147 current vs 100 5-month average), indicating a substantial focus on refining existing systems, fixing bugs, and improving code quality.
- The *commit volume* decreased by 36% (1581 current vs 2474 5-month average), suggesting a more concentrated development effort compared to previous months.
- Significant development and refinement activity was observed across *Agent Host* and *Sessions* features, encompassing new capabilities, usability enhancements, and bug fixes, as seen in commits like [041ae8b0 · Ben Villalobos], [e7bf9e83 · Sandeep Somavarapu], [ece376a4 · Sandeep Somavarapu], and [6cde2e9b · Sandeep Somavarapu].
- A recurring pattern of UI/layout adjustments, particularly for *floating panels*, *sidebars*, and *editor margins*, was addressed in multiple commits, including [6d8b7045 · mrleemurray], [b30acd1b · mrleemurray], and [48e992cc · mrleemurray], indicating ongoing complexity in achieving consistent visual presentation.
- Several commits addressed bug fixes related to *Agent Host* and *Sessions* functionality, such as loading changesets [75758121 · Ladislau Szomoru], session order persistence [b168fa7e · Benjamin Christopher Simmonds], and subagent rendering [cb39ed9e · Justin Chen], with some contributing to waste.
- *Copilot*-related features saw enhancements in telemetry [f18c6b4f · Tyler James Leonhardt], explainability [04b756ba · Logan Ramos], and configurability [33dec983 · Dirk Bäumer], alongside critical test fixes [c04d3b4d · Giuseppe Cianci] and temporary test skips [2ad1a520 · vs-code-engineering[bot]].
Performance over time
ETV stacked by Growth, Maintenance and Fixes — 90-day moving average, normalized to ETV / month.
Average performance per developer
ETV per active developer per month — 30-day moving average.
Active developers over time
Unique developers committing each day — 90-day moving average.
Knowledge concentration
How dependent is this repo on a small number of contributors? Higher top-1 share = higher key-person risk.
Benjamin Pasero owns 6.7 % of commits.
Top contributors
Most impactful commits
Top 20 by ETV in the all-time window.
- 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
- 4.9ETVdebt - fix some leaks found by copilot (#293731)Benjamin Pasero · 45a35b80 · 2026-02-09
- 4.6ETVsessions: quick chats (workspace-less sessions) in the Agents window (#323972) * sessions: quick chats — workspace-less single-chat sessions Adds quick chats to the Agents window: lightweight chats not scoped to a workspace, backed by an agent-host session. The host infers workspace-less from an absent workingDirectory (forks excluded) and assigns a stable scratch dir; the workspaceless tag rides the generic _meta bag. Quick chats are single-chat, use the normal session presentation (Done hidden), render in an always-visible in-list "Chats" section, and persist across reloads. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: New from a quick chat opens another quick chat (Round 23) The primary "New" action gated quick-chat routing on `isCreated && isQuickChat`, but a quick-chat draft is Untitled (isCreated=false), so it fell through to the workspace composer seeded with a throwaway scratch dir (no session-type picker, "No models available"). Route on `isQuickChat` alone so a quick chat — draft or committed — opens another quick chat mirroring its harness. Extract the routing into a pure, side-effect-free `openNewChatOrQuickChat` helper so it is unit-testable (chat.contribution.ts is not test-importable). Supersedes Round 14(2) and updates Round 22(3); the Round 14(2) discard branch and Round 17 picker re-parent are kept as internal defense. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: quick-chat list & layout polish (Round 22 items 1-2) - Suppress the redundant per-row chat icon when a quick chat is rendered under the always-visible "Chats" section (the section header already carries a chat icon); keep it in Pinned/custom/date groups where the chat identity is useful. - Disable the "Toggle Side Panel" command for quick chats via precondition IsQuickChatSessionContext.negate(), since a quick chat has no side pane (the empty aux bar is hidden and the chat is full-width). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: persist empty peer-chat catalog sentinel to avoid re-running legacy migration When a session has no legacy peer chats, write an empty catalog so _readPersistedPeerChatCatalog returns [] on subsequent restores and _migrateLegacyPeerChats never re-runs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: Cmd+N always creates a new session; New Quick Chat gets Cmd+K Cmd+N (Round 24) Per user feedback, Cmd+N must always open a NEW SESSION — never a quick chat. Drop the context-aware quick-chat routing from NewChatInSessionsWindowAction (rename its title "New Chat" -> "New Session", keep the id) so it unconditionally calls openNewSession from the active session; the helper is renamed openNewChatOrQuickChat -> openNewSessionFromActive. Quick chats are created only via the Chats-section "+" (NewQuickChatAction), which now has a default Cmd+K Cmd+N chord. The peer-chat "+" (Cmd+T) is unaffected. Supersedes the Round 22(3)/23 mirror routing; the Round 14(2) discard branch and Round 17 picker re-parent are untouched. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: Cmd+N never inherits a quick chat's folder into the workspace composer (Round 25) New from a quick chat must always land on the clean New Session composer with a visible session-type picker. Gate openNewSessionFromActive's folder inheritance on isQuickChat so a quick chat never carries a (possibly leaked scratch) workspace URI into openNewSession. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: re-seed workspace draft when composer swaps out of quick-chat mode (Round 25b) Cmd+N from a quick chat reuses the new-session composer and only _activate(undefined), leaving it session-less. The session-type picker hides itself when it has no folder types (no active session), so no picker showed. Re-run the constructor's workspace-draft seed from an autorun when the composer transitions out of quick-chat mode with no active session, matching a freshly opened new-session composer (folder + visible picker). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: quick-chat untitled title falls back to "New Chat" via shared helper (Round 26) An untitled quick chat's titlebar showed "New Session" because the empty-title fallback was hardcoded and not quick-chat aware. Add getUntitledSessionTitle(isQuickChat) to the common layer and route all 5 fallback sites (titlebar, session header x2, list hover, sessions picker) through it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: track isQuickChat in titlebar re-render autorun (Round 27) The SessionsTitleBarWidget re-render autorun read the active session's title and workspace but not isQuickChat, which _render() consumes for the untitled title fallback. Track it as a reactive dependency for forward-safety and consistency with other reactive render sites. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: move workspace-less marker ownership to the AH service Each agent used to persist and re-emit its own workspace-less (quick chat) marker (copilot.workspaceless / claude.workspaceless) in the shared session database, and agents that persist nothing (Codex) lost the marker on restart. Make the AH service the single owner: AgentService persists a single agentHost.workspaceless key at create/materialize (from the value it already infers in _buildInitialSummary) and overlays _meta.workspaceless onto every agent's summary in listSessions. Agents no longer write or namespace the marker; Copilot reads the shared key for its resume system prompt, and the now-dead workspace-less plumbing is removed from the Claude session. This fixes restored quick chats for every agent (including Codex) with no per-agent code. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions/agentHost: address review feedback (naming + inline) - Rename the workspace-less launch-plan flag from isQuickChat to workspaceless in CopilotSessionLaunchPlan and IAgentHostPromptContext (and the disposeSession local) so the flag matches the workspaceless marker it flows from throughout the AH layer. Feature-descriptive names (COPILOT_AGENT_HOST_QUICK_CHAT_INSTRUCTIONS, _quickChatScratchDir) are kept. - Inline openNewSessionFromActive back into NewChatInSessionsWindowAction.run and remove the single-caller seam module + its test. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: make the AH service the sole owner of the workspaceless marker Following the earlier ownership move, the agents still read + re-emitted _meta.workspaceless in their metadata projections, which was redundant on the listSessions path (AgentService overlays it centrally) and only load-bearing on the single-session restore path. Centralize the restore overlay in AgentService.restoreSession (reads agentHost.workspaceless in its existing batch metadata read and merges it into the restored summary _meta), then drop the per-agent re-emit: remove it from the Claude metadata store entirely (Claude has no runtime need) and from the Copilot listSessions/getSessionMetadata projections. Copilot keeps reading the AH key for its resume system prompt and scratch-dir cleanup. Codex is now covered centrally with no Codex code. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: inline openQuickChatAndFocus into NewQuickChatAction Single-caller helper folded into the action's run(). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: make ISessionsProvider.createQuickChat mandatory Replace the optional createQuickChat with a mandatory method that throws when the provider does not support quick chats; callers now gate solely on the supportsQuickChats capability instead of probing for the method. Workspace-bound providers (Copilot chat, local chat) get an explicit throwing implementation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: use "workspace-less chat" terminology instead of "quick chat" Rename the agent-host-internal quick-chat identifiers, prompt tags, and prose to workspace-less: COPILOT_AGENT_HOST_QUICK_CHAT_INSTRUCTIONS -> COPILOT_AGENT_HOST_WORKSPACELESS_INSTRUCTIONS, the <quick_chat> system-message tag -> <workspaceless_chat>, and the scratch-dir helpers (_quickChatScratchDir/_ensure*/_cleanup*/_withQuickChatScratch). The workbench UI term "Quick Chat" is kept only where the agent host documents that mapping. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: address Copilot Code Review feedback on quick chats - sessionsList: select the row chat icon from isQuickChatSession(), not from workspace === undefined, so a workspace session with a transiently-undefined workspace no longer briefly shows the chat icon. - sessionContextKeys: correct the isQuickChat comment to reflect that the key is sourced from the isQuickChat tag, never inferred from workspace absence. - Agents window accessibility help: document the New Quick Chat command (Cmd/Ctrl+K Cmd/Ctrl+N) and the Chats section plus button, and note that the workspace picker does not apply and Toggle Side Panel is disabled for quick chats. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>Sandeep Somavarapu · e63efae7 · 2026-07-02
- 4.0ETVsessions: refine the single-pane detail-panel layout (#324348) * sessions: single-pane detail-panel layout for the Agents window Add an experimental `sessions.layout.singlePaneDetailPanel` setting (default off) that docks the detail panel (auxiliary bar) inside the editor part, so a single editor tab bar spans the editor content and the docked panel. Introduces a custom Changes (multi-diff) editor, Files/Browser tabs, and a "+" add-tab menu, with the Changes view and diff-stats split into standard vs single-pane subclasses chosen at startup. The redesign uses a mode-based architecture: all single-pane parts, editors, serializers, actions and views are registered/gated behind the setting via `IAgentWorkbenchLayoutService.isSinglePaneLayoutEnabled` (the single source of truth), so the standard Agents-window layout is unchanged when the setting is off. Core editor support: `EditorPart.setContentRightInset` (concrete class, not the public `IEditorPart` interface) insets only right-edge groups so the tab bar stays full-width; a generic `MenuId.EditorTabsBarAddTab` renders a core-owned "+" dropdown at the end of the tab strip. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: address CCR feedback on single-pane layout - empty-file editor: register a touch Gesture target and handle Tap (iOS) in addition to click, and set `touch-action: manipulation` to avoid the tap delay. - docked detail panel border: use `var(--vscode-strokeThickness)` instead of a hardcoded 1px. - drop the internal `[Option A]` design-discussion marker from comments across workbench.ts / style.css / sessionConfig.ts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: fix use-before-init in DetailPanelController The _activeEditorObs / _auxBarVisibleObs field initializers referenced the constructor-injected _editorService / _layoutService, which run before the parameter properties are assigned (TS2729, caught by tsc in CI but not by the tsgo typechecker). Move their initialization into the constructor body. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: update blocks-ci screenshot hashes Refresh the committed blocks-ci-screenshots.md to the current CI-rendered image hashes (CodeEditor / InlineChatZoneWidget fixtures). These are bare editor-widget fixtures not affected by this PR's editor-tab changes; the drift is from the screenshot service re-render. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: make SessionChangesService resolvable without the workbench layout service SessionChangesService is a DI singleton also instantiated in component fixtures / unit tests, which do not register IAgentWorkbenchLayoutService. Read the single-pane setting via IConfigurationService (available everywhere) instead, so resolving ISessionChangesService no longer fails with 'depends on layoutService which is NOT registered'. The layout service remains the single source of truth for contributions that run only in the real Agents window. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: re-sync blocks-ci screenshot hashes Update the committed hashes to the current CI render (the 6 CodeEditor / InlineChatZoneWidget fixtures shifted with the merged upstream editor changes). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: fix single-pane layout bugs from layout audit Grid/sizing: persist the logical editor width (excluding the docked panel) so the Sessions Part no longer shrinks by the panel width on every reload; clamp the stored docked width to its minimum and yield to the editor's minimum in narrow windows; keep the editor grid leaf visible when only the docked aux bar toggles. Editor content inset: recompute on group maximize/restore so a maximized non-right group is not rendered under the docked panel, and re-layout the docked panel after the un-maximize resize. Controllers: DetailPanelController shows Changes while the editor is maximized (agreeing with the D5 rule) and classifies editor types (file/empty-file -> Files, Changes -> Changes, Browser -> hidden, other -> preserve); the LayoutController no longer auto-reveals the Changes view on editor open in single-pane, so existing sessions keep the 'never auto-open' rule. Docs: fix stale method references in LAYOUT.md. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: single-pane detail panel refinements and controller merge Merge the single-pane detail/tab controllers into the layout controller, add a dedicated Toggle Details command, refine R1 (transition-triggered editor hide), default a created session to the Changes editor with the detail closed, reveal the docked editor part for created sessions, and remove the docked reveal-sync suppression mechanism. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>Sandeep Somavarapu · 5cfa7158 · 2026-07-05
- 4.0ETVsessions: support Multi-Chat in the Claude agent-host harness (#323625) * Support multiple chats for Claude agent-host sessions Enable a single Claude (agent-host `provider === 'claude'`) session to own multiple peer chats in the Agents window, matching the Copilot CLI experience. - ClaudeAgent: add `_chatSessions` map plus `createChat` / `disposeChat` / `getChats`, per-chat persistence, lazy resume of restored peer chats, and per-chat routing on `sendMessage` / `abortSession` / `changeModel` / `changeAgent`. Fork a peer chat from a source chat's SDK conversation at a turn, falling back to a fresh chat when the fork anchor can't be resolved. - Agent-host sessions provider: advertise `supportsMultipleChats` for the `claude` logical session type in addition to `copilotcli`. - Update SESSIONS.md and ClaudeAgent tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: fix Claude peer-chat signal routing and harden multi-chat lifecycle Fix additional (peer) chats in Claude agent-host sessions getting stuck in progress: a peer chat passes its `ahp-chat` channel URI as the session's `sessionUri`, but `ClaudeAgentSession` derived its routing channel via `buildDefaultChatUri(sessionUri)`, double-encoding it so the renderer never matched the channel. Use the chat URI directly when `sessionUri` is already an `ahp-chat` channel. Also harden the peer-chat lifecycle per code review: - serialize all catalog read-modify-write on the parent session id (createChat / disposeChat / _updateChatCatalogModel) to avoid lost updates - hold the per-chat lock across both materialize and send so disposeChat / disposeSession serialize against an in-flight turn (no use-after-dispose) - make _disposeChildChats async + per-chat serialized to avoid zombie entries - abort provisional peer chats up front during shutdown - route setPendingMessages steering to peer chats - shape-guard the persisted catalog model Refs https://github.com/microsoft/vscode/issues/322776 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: thread chat channel through setPendingMessages for peer-chat steering Address CCR feedback: peer-chat steering was non-functional because `AgentSideEffects._syncPendingMessages` always dispatched the parent session URI to `agent.setPendingMessages`, so the Claude peer-chat routing branch was never reached and steering landed on the default chat. Add an optional `chat?` param to `IAgent.setPendingMessages` (mirroring sendMessage/abortSession/changeModel), dispatch the chat channel from `_syncPendingMessages` (undefined for the default chat), and route via it in ClaudeAgent. Copilot/Codex 3-param implementations remain valid and unchanged. Adds an AgentSideEffects dispatch test asserting the peer chat URI is forwarded as the `chat` arg (and is undefined for the default chat). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: unify Claude session/peer-chat plumbing into one entry container Address review feedback (connor4312): stop overloading session/chat URIs and the parallel-map split that special-cased peer-chat dispatch. - ClaudeAgentSession now takes an explicit `chatChannelUri`; its `sessionUri` is always the real session URI and is never a chat URI (`isAhpChatChannel(sessionUri)` can no longer be true). Per-chat resources (db, overlay, config scope, server-tool advertise) key off a derived `_storageUri` so peer chats stay isolated without overloading `sessionUri`. - Drop the parallel `_chatSessions` map: a single `_sessions` map of `ClaudeSessionEntry` containers now holds each session's default chat plus its peer chats. Dispatch resolves a chat via `_findChat(session, chat)` / the entry, and teardown disposes the whole entry (main + peers) via `_teardownEntry`. - Unify peer-chat message reconstruction with `getSessionMessages` via a shared `_reconstructTurns(sdkId, routingUri, primeOn)`; remove the duplicated `_getChatMessages`. No behavior change to storage keying (main -> session URI, peer -> chat URI). All ClaudeAgent / AgentSideEffects / CopilotAgent / AgentService node tests pass (425 claude tests). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: add opaque providerData to chat catalog + multi-chat tests Wave A + gate G-B1 of the multi-chat unification: - AgentHostStateManager: add an opaque, agent-owned `providerData?: string` to peer-chat catalog entries (addChat/restoreChat) plus getChatProviderData. Stored verbatim and never parsed; the default chat carries none. This becomes the single source of truth for a peer chat's backing-conversation token, replacing the agents' private copilot.chats/claude.chats persistence. - Add characterization tests for the StateManager catalog (default chat, add/ remove/restore, summary roll-up) and peer-chat + restore round-trip tests for CopilotAgent and ClaudeAgent, guarding the upcoming de-dup waves. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: orchestrator owns the peer-chat catalog (Wave B de-dup) Make AgentHostStateManager's catalog the single source of truth for peer chats, removing the agents' private copilot.chats/claude.chats persistence: - agentService: restore peer chats by enumerating the orchestrator's own catalog (using the opaque providerData blob) instead of agent.getChats; call materializeConversation(chatUri, providerData) before getSessionMessages so the agent re-attaches its conversation backing; persist providerData on createChat and re-persist on onDidChangeConversationData. - IAgent: createChat returns IAgentCreateChatResult { providerData? }; add materializeConversation + onDidChangeConversationData. - CopilotAgent / ClaudeAgent: stop writing their private *.chats catalogs; shrink _chatSessions to a live-only map; decode providerData to rebuild the chatUri -> sdkSessionId mapping; emit onDidChangeConversationData on per-chat model/fork change. A one-time legacy *.chats READ (triggered by an undefined providerData blob) migrates in-flight sessions. Typecheck, valid-layers-check, and the agentService/Copilot/Claude/StateManager suites (511 tests) all pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: add scope/conversation IAgent surface + dispatch mapper (gate G-C1) Introduce the orchestrator-owned scope/conversation vocabulary on IAgent, additively alongside the legacy (session, chat?) surface (kept as a compat shim until waves C2-C5 migrate each agent): - IAgent: add createScope/disposeScope and an IAgentConversations surface (createConversation/disposeConversation/getMessages/fork, conversation- addressed sendMessage/abort/changeModel/changeAgent). - AgentService: map feature-level (session, chat) -> (agent, scope, conversation) and own default-chat resolution; resolveConversationUri helper. Typecheck, valid-layers-check, and the AgentService dispatcher suites (112 passing) all pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: agents adopt scope/conversation surface (Wave C) CopilotAgent, ClaudeAgent and CodexAgent now implement the new scope/ conversation IAgent surface (createScope + conversations: createConversation/disposeConversation/getMessages/fork and conversation- addressed sendMessage/abort/changeModel/changeAgent), and agentSideEffects threads it through where straightforward. The legacy (session, chat?) compat shim is intentionally retained for now; it is removed centrally in gate G-C2. Typecheck, valid-layers-check, and the Copilot/Claude/Codex/AgentService suites (563 passing) all pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: remove legacy (session, chat?) shim from IAgent (gate G-C2) With every agent migrated to the scope/conversation surface (Wave C), drop the agent-facing legacy methods — sendMessage(session,chat,...)/createChat/ disposeChat/getChats and the chat?-suffixed abort/changeModel/changeAgent — leaving only the conversation-addressed surface on IAgent. AgentService, agentSideEffects and the three agents migrate their remaining call sites; the mock agent is updated to the new surface. The orchestrator-facing IAgentService/IAgentConnection (session,chat) API and the wire protocol are unchanged — they remain the (session,chat) -> conversation mapping boundary. Net -209 lines. Typecheck, valid-layers-check, and the Copilot/Claude/Codex/ AgentService suites (559 passing) all pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: add harness spawn-conversation channel + catalog routing (gate G-D1) Generalize the subagent_started/subagent_completed signals into a first-class membership channel: IAgent.onDidSpawnConversation({ scope, conversation, parent? }) / onDidEndConversation(conversation). AgentService subscribes on provider registration and routes spawned conversations straight into the chat catalog (addChat/removeChat), so harness-spawned chats (teams, fleet, subagents) and user-driven chats share ONE catalog path, preserving the parent relation. Per-agent emission of these events lands in Wave D. Typecheck, valid-layers-check, and the AgentService suite (107 passing) pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: agents emit spawn events + capability-driven UI gating (Wave D) - CopilotAgent / ClaudeAgent emit onDidSpawnConversation/onDidEndConversation from their subagent/fan-out paths, so harness-spawned chats flow into the shared catalog via the G-D1 channel (carrying the parent relation). - IAgentDescriptor advertises IAgentCapabilities { supportsMultipleChats, supportsFork, supportsTeams }; the agent-host sessions provider maps these onto ISessionCapabilities instead of the hardcoded supportsMultipleChats(logicalSessionType) session-type check, and exposes supportsFork/supportsTeams context keys so UI gates generically with no per-harness branches. Typecheck, valid-layers-check, and the agentHost + sessions provider suites (1725 passing) all pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: test default-chat rename is restored on restoreSession Re-add coverage for restoring a default chat's independently-persisted custom title (customChatTitle:<defaultChatUri>), homed in the dedicated restoreSession suite using the localService + TestSessionDatabase pattern. A version of this test arrived via a merge but was misplaced in the createChat suite; this puts it in the right place. The behavior itself lives in AgentService.restoreSession. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Remove unused supportsTeams capability The supportsTeams capability was fully plumbed (protocol to agents to ISessionCapabilities to SessionSupportsTeamsContext) but had zero consumers: no when-clause and no widget read it. Harness-spawned teams/subagents surface automatically via onDidSpawnConversation regardless of any flag, so this was speculative dead weight. Remove all 13 references across 9 files. supportsMultipleChats and supportsFork are left untouched as they are actually consumed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: unify subagent catalog membership onto the spawn channel (DR1) Make the spawn-conversation channel the single owner of subagent catalog membership, removing the duplicate add path: - AgentSideEffects._handleSubagentStarted no longer calls addChat; it keeps only the subagent lifecycle (ChatTurnStarted, _subagentChats tracking, parent tool-call Subagent content, buffered-signal drain, teardown). - AgentService now sequences a subagent_started/subagent_completed signal onto the spawn-channel handlers (_onConversationSpawned/_onConversationEnded) via a new onDidSessionProgress subscription registered BEFORE the side-effects progress listener. This deterministically guarantees the subagent chat exists in the catalog before its turn is started, independent of when the agent registers its own subagent->spawn bridge (addChat/removeChat are idempotent). - Extract the subagent-signal -> spawn-event mapping into shared helpers (subagentSpawnConversationEvent/subagentEndConversation) reused by the agents' bridges and the AgentService sequencer. Adds a "subagent membership sequencing" suite: exactly one catalog entry with parent origin/title/started turn regardless of order, buffered inner-signal drain, and completion teardown. Typecheck, valid-layers, and the agent suites (567 passing) all pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: add multi-chat architecture spec Living architecture spec for the agent-host multi-chat design (scope/session vs conversation/chat, orchestrator-owned catalog, opaque providerData, unified spawn channel, capability gating) with mermaid diagrams. Kept in sync with the implementation, like SESSIONS.md. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: legacy peer-chat migration (BC1) + Copilot session container (F2) Two changes to the Copilot/Claude agents and the orchestrator restore path: BC1 - backward-compatible restore of legacy peer chats: sessions whose additional chats were persisted only in the old agent-owned copilot.chats / claude.chats format (no orchestrator peerChats catalog) previously restored with those chats invisible. AgentService now performs a one-time migration when the orchestrator catalog is absent (undefined, not []): it enumerates the agent's legacy chats via a new migration-only IAgent.listLegacyChats, restores them through the normal catalog path, and writes the peerChats key so the drain runs once. Fixes the stale JSDoc that claimed a fallback removed in G-C2. F2 - collapse CopilotAgent's default-vs-peer _sessions/_chatSessions two-map split into a single _sessions map of a CopilotSessionEntry container (mirroring ClaudeSessionEntry): the entry holds the default chat plus a nested _peerChats map. Removes the special-casing Connor flagged on #323625. Typecheck, valid-layers-check, and the AgentService/Copilot/Claude suites (570 passing, incl. the migrate-once / empty-catalog / new-format restore cases) all pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: rename agent scope/conversation surface to session/chat (N1) Collapse the agent-facing vocabulary back to session/chat, so the whole stack (protocol, orchestrator, UI, agents) speaks one language. The scope/conversation terms were a 1:1 veneer over concepts already named session/chat elsewhere (the create* methods even returned IAgentCreateSessionResult). The sessionUri vs chatChannelUri TYPE separation is preserved — this is a naming change only. - IAgent: createScope/disposeScope -> createSession/disposeSession; the conversations surface (IAgentConversations) -> chats (IAgentChats) with createChat/disposeChat/getMessages/fork + conversation-addressed send/abort/ changeModel/changeAgent now chat-addressed; materializeConversation -> materializeChat; onDidSpawn/End/ChangeConversation* -> onDidSpawn/End/ChangeChat*. - Types: IAgentSpawnConversationEvent -> IAgentSpawnChatEvent, IAgentConversationDataChange -> IAgentChatDataChange; drop IAgentCreateConversationOptions (reuse IAgentCreateChatOptions). - Helpers: resolveConversationUri -> resolveChatUri and the private _*Conversation* members across AgentService/agents renamed to _*Chat*. - IAgentService/IAgentConnection/protocol/UI names unchanged (already session/chat). - Reconcile agentSideEffects tests to the renamed chat surface (mock URI normalization) and update MULTI_CHAT_ARCHITECTURE.md terms/diagrams. Typecheck, valid-layers-check, and the agent suites (686 passing) all pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: align architecture diagram label with chat terminology Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: align multi-chat spec terminology with the session/chat rename Refine MULTI_CHAT_ARCHITECTURE.md wording after N1: the default chat's backing SDK *session* (not "SDK chat") is the session, peer chats are backed by their own sdkSessionId, and clarify the (session, chat) -> (agent, session URI, chat URI) mapping label and the per-chat state description. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: group refactor-added helpers into logical units (NS1) Reduce loose top-level exports in common/agentService.ts introduced by the multi-chat refactor (the pre-existing config/env helpers are left untouched): - Move resolveChatUri to common/state/sessionState.ts next to its sibling chat-URI helpers (buildChatUri/buildDefaultChatUri/isDefaultChatUri/ parseChatUri) — its logical home. - Group the subagent signal -> spawn-channel mappers into an `export namespace SubagentChatSignal { toSpawnEvent, toEndChat }` (mirroring the existing AgentSession namespace), updating the Copilot/Claude bridges and AgentService._sequenceSpawnedChat call sites. Pure move/regroup, no behavior change. Typecheck, valid-layers-check, and the agent suites (686 passing) all pass. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Make ISession.capabilities observable so late-hydrating capabilities reconcile The agent-host adapter exposed `capabilities` as a live plain getter reading the connection's root state. When `rootState.agents[].capabilities` hydrated after a session's first `SessionState`, existing sessions were never reconciled: a multi-chat catalog processed while `supportsMultipleChats` was still `false` stayed collapsed to `[defaultChat]`, and the `supportsMultipleChats`/`sessionSupportsFork` context keys stayed stale because a plain getter cannot be tracked by the `setActiveSessionContextKeys` autorun. Change `ISession.capabilities` to `IObservable<ISessionCapabilities>`. The agent-host adapter derives it from `connection.rootState` (bridged via `observableFromEvent`) with `derivedOpts` + `structuralEquals`, and re-applies the last `SessionState` catalog in an autorun when capabilities change. Static providers wrap their capabilities in `constObservable`; consumers read `.read(reader)` (context keys) or `.get()` (one-shot). Adds a regression test and updates SESSIONS.md and the sessions skill. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Keep completed subagent chats live (fix subagent integration tests) A DR1 regression conflated 'subagent turn completed' with 'chat removed': a subagent_completed -> removeChat path tore the child subagent chat out of the catalog on completion, so subscribing to it after the parent turn completed failed with 'Resource not found'. A completed subagent chat must stay live and subscribable (merely hidden from listSessions), with its turn completed via AgentSideEffects.completeSubagentSession; subagent chats are removed only on session teardown via removeSubagentSessions. - agentService._sequenceSpawnedChat: handle spawn only (no removal on completion) - copilotAgent/claudeAgent spawn bridges: stop firing onDidEndChat on completion - remove now-unused SubagentChatSignal.toEndChat (keep toSpawnEvent) - keep onDidEndChat as a generic membership-removal hook - tests: assert the subagent chat survives subagent_completed and that completion does not fire onDidEndChat Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add non-opaque backingSession to IAgentCreateChatResult Introduces a first-class, non-opaque backingSession URI on the peer-chat create result so the orchestrator can correlate and suppress a peer chat's backing SDK session. Kept distinct from the opaque providerData blob so the providerData opacity invariant is preserved. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Report peer-chat backingSession from Claude and Copilot agents ClaudeAgent._createChat mints a fresh top-level SDK session per peer chat in the same store its listSessions enumerates, so it now returns that session as backingSession for the orchestrator to suppress. CopilotAgent sets it too for uniformity (harmless — its peer sessions already don't leak). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Filter peer-chat backing sessions from the top-level session list createChat now stamps a persisted peerChatBacking marker into the backing session's database, and listSessions drops any enumerated session carrying it (batched into the existing metadata overlay, mirroring the subagent filter). Fixes Claude peer chats leaking as separate top-level sessions. Adds a unit test covering the filter and its persistence across a restart, plus doc invariant I7. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Share peer-chat scaffolding across Claude & Copilot agents Extract the near-verbatim multi-chat peer scaffolding shared by the Claude and Copilot agents into a new node-target module `src/vs/platform/agentHost/node/agentPeerChats.ts`: - Move the opaque `providerData` codec (`IPersistedChat`, `encodeProviderData`, `decodeProviderData`) into the shared module and export it. Use Claude's stricter `model` validation, which is a superset of Copilot's unconditional cast. Both agents import it and drop their private copies. - Add a generic `AgentSessionEntry<TSession extends IDisposable>` container holding the optional default session plus the peer-chat map. Rewrite `CopilotSessionEntry` as an empty subclass and `ClaudeSessionEntry` as a subclass that narrows `session` to non-optional. Behavior-identical refactor; existing Agent* suites stay green. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Persist migrated legacy peer chats in a single atomic catalog write `_migrateLegacyPeerChats` wrote the migrated peer chats to the orchestrator catalog one entry at a time in a loop. Each `_persistPeerChat` is a separate read-modify-write of `PEER_CHATS_METADATA_KEY`, so after the first write the key is present containing only the first entry. If the agent-host process crashed (OS kill, power loss, forced restart) after write 1 but before write N, the catalog was left partial; on the next restart `_readPersistedPeerChatCatalog` returns that subset (not undefined), the catalog-present branch short-circuits, and migration never re-runs -- chats 1..N-1 are lost forever. Write the whole migrated set in a single atomic `_enqueuePeerChatCatalogWrite`, so the key is absent before and complete after; no partial catalog can survive a crash mid-migration. Adds regression tests asserting the full set is persisted in one write and that a rejected write leaves the key absent (never a subset). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>Sandeep Somavarapu · b10844ef · 2026-07-01
- 3.8ETVagent host: multi-chat session support for Copilot CLI (#321888) * Implement multi-chat session support for Copilot CLI in Local Agent Host Provider Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address CCR feedback: session-rename telemetry, createChat race, observable read - Add dedicated onDidRenameSession event + agents/sessionRenamed telemetry so session-title renames are no longer misclassified as chat renames - Re-check chat existence inside the per-session sequencer in createChat to avoid a race overwriting/disposing an already-registered conversation - Cache mainChat.title read in chatCompositeBar autorun Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * agentHost: dispatch default-chat turn lifecycle on session URI After merging origin/main's default-chat compat layer, turn-lifecycle actions (turnStarted, truncated, turnCancelled) must target the session URI for the default chat (and the peer chat URI for peer chats), so the server routes them to the default chat and subagent session URIs derive correctly. Conversation side-channel actions and tool-call observation keep using the resolved chat URI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>Sandeep Somavarapu · ee44398a · 2026-06-18
- 3.6ETVCopies sources from vscode (#688) * Copy sources from vscode * NodeJS.Timeout -> TimeoutHandle * Fixes copy sources fallout * Fixes snapshotsHenning Dieterichs · 5a50ffb9 · 2025-08-20
- 3.6ETVChronicle - local and remote (#308602) * chronicle * local and cloud store * upload vscode events to remote store * few updates * consent ui and settings * few optimizations * test fix * feedback updates * test fix * check setting to enable cmd * fix test * Settings update and tool update * command update * Settings update * merge main * feedback updates * setting and test update * few updates * updates * test update * blocks ci update * feedback updates * comment updateVijay Upadya · 602484ad · 2026-04-16
- 3.5ETVPrompt files provider API V2 (#286457) * wip * updates * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * test * dispose * clean * remove * invalidate * wip * pr * use enum * PR * clean * more cleanup * more cleanup * more cleanup * more cleanup * more cleanup * nit * add optional metadata * use new proposal * clean * clean * nit * v2 * yaml clean * clean * Update src/vs/workbench/api/common/extHostChatAgents2.ts Co-authored-by: Martin Aeschlimann <martinae@microsoft.com> * PR * wip * PR * Update src/vs/base/common/yaml.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * add command * pr * PR * PR * PR * clean * PR * use cache * nit clean * clean --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Co-authored-by: Martin Aeschlimann <martinae@microsoft.com>Paul · a357e63b · 2026-01-15
- 3.5ETVmerge to main (#299794) * sessions - fix chat input shrinking at narrow widths (#299498) style - set width to 100% for `interactive-input-part` * modal - force focus into first modal editor always * fix: update precondition for FixDiagnosticsAction and hide input widget on command execution (#299499) fixes https://github.com/microsoft/vscode/issues/299251 * refactor: remove workspace context service dependency from FolderPicker * Add logging for agent feedback actions * modal - some fixes to actions and layout * modal - surface some editor actions in a new toolbar (#299582) * modal - surface some editor actions in a new toolbar * ccr * keybindings - remove "Edit as JSON" as its now available from the title menu * settings - remove "Edit as JSON" as its now available from the title menu * update hover fixes * terminal fixes * terminal improvements * Sessions: fix auth scopes of gh FSP * sessions customizations: make it easier to scan mcp/plugin marketplac… (#299636) sessions customizations: make it easier to scan mcp/plugin marketplace list * sessions: add built-in prompt files with override support (#299629) * sessions: add built-in prompt files with override support Ship bundled .prompt.md files with the Sessions app that appear as slash commands out of the box. Built-in prompts use a BUILTIN_STORAGE constant (cast as PromptsStorage) defined in the aiCustomization layer, avoiding changes to the core PromptsStorage enum and prompt service types. - AgenticPromptsService discovers prompts from vs/sessions/prompts/ at runtime via FileAccess and injects them into the listing pipeline - Override logic: user/workspace prompts with matching names take precedence over built-in ones - Built-in prompts open as read-only in the management editor - Sessions tree view, workspace service, and counts handle BUILTIN_STORAGE - Add /create-pr as the first built-in prompt - Bundle prompt files via gulpfile resource includes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Update src/vs/workbench/contrib/chat/browser/aiCustomization/aiCustomizationManagement.ts Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * sessions: use AICustomizationPromptsStorage type for builtin storage Adopt the new AICustomizationPromptsStorage union type in the sessions tree view method signature. Use string-keyed Records and targeted casts at the PromptsStorage boundary to stay type-safe. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: remove PromptsStorage casts, widen IStorageSourceFilter Use AICustomizationPromptsStorage in sessions-local interfaces (IAICustomizationGroupItem, IAICustomizationFileItem) and widen IStorageSourceFilter.sources to readonly string[] so BUILTIN_STORAGE flows through without casts. The only remaining cast is at the IPromptPath creation boundary in AgenticPromptsService. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: move BUILTIN_STORAGE to sessions common layer Move AICustomizationPromptsStorage type and BUILTIN_STORAGE constant from the workbench browser UI module to sessions/contrib/chat/common so that AgenticPromptsService (a service) does not depend on UI code. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * sessions: fix ESLint dangerous type assertion in builtin prompts (#299663) Replace the `as IPromptPath` cast in discoverBuiltinPrompts with a createBuiltinPromptPath factory function that contains the type narrowing in one place, satisfying the code-no-dangerous-type-assertions ESLint rule. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Enhance Agent Sessions Control and Renderer with observable active session resource * fix terminal * Enable model management in NewChatWidget * review feedback * different competion settings for copilot markdown and plaintext --------- Co-authored-by: Benjamin Pasero <benjamin.pasero@gmail.com> Co-authored-by: Benjamin Pasero <benjamin.pasero@microsoft.com> Co-authored-by: Johannes Rieken <johannes.rieken@gmail.com> Co-authored-by: BeniBenj <besimmonds@microsoft.com> Co-authored-by: Osvaldo Ortega <osortega@microsoft.com> Co-authored-by: Josh Spicer <23246594+joshspicer@users.noreply.github.com> Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>Sandeep Somavarapu · 2b32258b · 2026-03-06
- 3.4ETVFix Copilot AH plugin sync errors on reconnection (#320193) * Fix Copilot AH plugin sync errors on reconnection (#319744) Two-part fix for #319744: 1. AHPFileSystemProvider gets a brief reconnection grace window. Per- authority entries keep a stack of connections (newest = active) and hold open requests across a transient disconnect. Watchers auto-reattach across reconnects via a class-level connection-change event. New tests cover reconnect grace, fallback to prior connection, immediate reject for never-registered authorities, and watch reattach across disconnect / late attach. 2. Plugin controller is split into two: - PluginController (shared, process-wide): host customizations, parsing helpers, and the IAgentPluginManager. - SessionPluginController (per CopilotAgentSession): client customizations, session-discovered on-disk customizations, and per-session enablement overrides. Publishes SessionActions directly via onDidPublish — no more clientId-based cross-session routing. ActiveClient is now Disposable, owns its SessionPluginController, and forwards publish events into the session's progress stream. setCustomizationEnabled fans out to every session controller, matching Claude's per-session model. sendMessage retries any previously-failed client customization sync so a transient connection drop during reconnection doesn't pin the error. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address Copilot review feedback - agentHostFileSystemProvider: fix _getConnection race by re-checking state after subscribing - agentHostFileSystemProvider: explicit void on fire-and-forget reattach() calls in watch() - copilotAgent: remove duplicate JSDoc block on PluginController Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Use timeout(0) instead of setImmediate in browser-runnable tests setImmediate is not available in WebKit, causing macOS / Browser CI unit tests to fail. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>Connor Peet · bad33e15 · 2026-06-06
- 3.3ETVsessions: single-pane detail-panel layout for the Agents window (#324257) * sessions: single-pane detail-panel layout for the Agents window Add an experimental `sessions.layout.singlePaneDetailPanel` setting (default off) that docks the detail panel (auxiliary bar) inside the editor part, so a single editor tab bar spans the editor content and the docked panel. Introduces a custom Changes (multi-diff) editor, Files/Browser tabs, and a "+" add-tab menu, with the Changes view and diff-stats split into standard vs single-pane subclasses chosen at startup. The redesign uses a mode-based architecture: all single-pane parts, editors, serializers, actions and views are registered/gated behind the setting via `IAgentWorkbenchLayoutService.isSinglePaneLayoutEnabled` (the single source of truth), so the standard Agents-window layout is unchanged when the setting is off. Core editor support: `EditorPart.setContentRightInset` (concrete class, not the public `IEditorPart` interface) insets only right-edge groups so the tab bar stays full-width; a generic `MenuId.EditorTabsBarAddTab` renders a core-owned "+" dropdown at the end of the tab strip. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: address CCR feedback on single-pane layout - empty-file editor: register a touch Gesture target and handle Tap (iOS) in addition to click, and set `touch-action: manipulation` to avoid the tap delay. - docked detail panel border: use `var(--vscode-strokeThickness)` instead of a hardcoded 1px. - drop the internal `[Option A]` design-discussion marker from comments across workbench.ts / style.css / sessionConfig.ts. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: fix use-before-init in DetailPanelController The _activeEditorObs / _auxBarVisibleObs field initializers referenced the constructor-injected _editorService / _layoutService, which run before the parameter properties are assigned (TS2729, caught by tsc in CI but not by the tsgo typechecker). Move their initialization into the constructor body. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: update blocks-ci screenshot hashes Refresh the committed blocks-ci-screenshots.md to the current CI-rendered image hashes (CodeEditor / InlineChatZoneWidget fixtures). These are bare editor-widget fixtures not affected by this PR's editor-tab changes; the drift is from the screenshot service re-render. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: make SessionChangesService resolvable without the workbench layout service SessionChangesService is a DI singleton also instantiated in component fixtures / unit tests, which do not register IAgentWorkbenchLayoutService. Read the single-pane setting via IConfigurationService (available everywhere) instead, so resolving ISessionChangesService no longer fails with 'depends on layoutService which is NOT registered'. The layout service remains the single source of truth for contributions that run only in the real Agents window. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * test: re-sync blocks-ci screenshot hashes Update the committed hashes to the current CI render (the 6 CodeEditor / InlineChatZoneWidget fixtures shifted with the merged upstream editor changes). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>Sandeep Somavarapu · 7317e60f · 2026-07-04
- 3.3ETVci and PR review comments in agent feedbackBeniBenj · f316d9db · 2026-03-10
- 3.3ETVManage language models editor (#274207) * copilot management editor * fix command id * fix command id * fix commands * more feedback * clean up * more enhancements * add unit tests * only keep it in insiders * cleanup * copilot feedback * fix smoke testsSandeep Somavarapu · ef37dc63 · 2025-10-30
- 3.2ETVupdate to latest vscode sources (#3118)Ulugbek Abdullaev · 311d7fab · 2026-01-26
- 3.2ETVagentHost: fix orphaned client tool calls after window reload - A window reload reconnects with a new clientId but an identical tool list. The cached SDK session was reused with the dead window's clientId baked in, so every later client tool call was stamped with that dead id, routed to passive render, and hung forever with nobody to invoke it. - Introduces a live, shared ActiveClientState so the owning clientId is read at tool-call stamp time instead of being frozen at session creation, and makes the staleness check restart only on structural tool/plugin changes — a clientId-only change no longer needlessly restarts (Copilot) or yield-rebinds (Claude) the session. - Adds a server-side safety net so a client tool call stamped for a client that is not connected (including one that disconnected before the call was even issued) fails after a grace window rather than hanging, with the grace measured from when that client was last seen. - Lets a completion that races ahead of the SDK tool handler resolve via a buffered result, preserving the previous out-of-order tolerance. Fixes #319641 (Commit message generated by Copilot)Connor Peet · 216f88de · 2026-06-09
- 3.1ETVAgent host: run `!`-prefixed chat messages as terminal commands (#324270) - Add a "bang command" feature: in any chat agent, a message starting with `!` runs as a terminal command (via the existing agent-host terminal/shell integration) instead of being sent to the model. The host emits a transcript-only tool-call response for the command. - Persist host-injected "local turns" (`!command` and `/rename`) so they survive reload; fork/truncate/rename resolve them to the preceding concrete SDK turn. Handled uniformly per-chat (default, peer and subagent chats). - Refactor local command handling into a pluggable `LocalChatCommandRegistry` with self-contained `AgentHostLocalCommands` dispatcher, extracting the logic out of `AgentSideEffects`. Add `renameLocalCommand` and `bangLocalCommand`. - Extract shared helpers: `shellCommandExecution` (agent-agnostic shell exec core) and `persistSessionMetadata`. - Fix peer-chat truncation routing: `truncateSession` now takes the chat URI and routes peer chats to their own backing session. - Fix truncate no-op after forking into a second peer chat: `SessionDataService` keyed every peer chat of a session onto one data dir/DB (chat id lives in the URI authority, which `AgentSession.id` dropped), so a second fork's `vacuumInto` failed with "output file already exists" and the forked chat never inherited its turn event IDs. Key now includes the authority; both fork copy sites also clear any stale target DB first. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>Connor Peet · 710b8c0c · 2026-07-04
- 3.1ETVAgents web: Host filtering improvements and mobile improvements (#313062) * sessions: mobile UI improvements — filter chips, terminal view, diff view, tool cards - Feature 1: Add horizontally scrollable filter chips below session list header on phone layout. Chips for Completed, In Progress, and Failed status filters; active state highlights chip. - Feature 2: Improve touch targets for collapsible tool cards in chat on mobile. Minimum 44px height for tool card toggle buttons and always-visible chevron. - Feature 3: Add dedicated full-screen mobile terminal view overlay. Tapping a terminal tool invocation on phone opens a full-screen output view with back navigation, monospace output, and copy/search footer actions. - Feature 4: Add dedicated full-screen mobile diff view overlay. Tapping a file change on phone opens a Diff/File segmented control view with inline unified diff (colored +/- gutters) and full file content tab. All features are phone-only (IsPhoneLayoutContext). Desktop behavior is unchanged. Layer rules preserved: sessions/browser imports only vs/workbench/services; contrib-layer command handlers bridge to local-interface view functions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * MVP Co-authored-by: Copilot <copilot@github.com> * Review * Clean up * Filter fixes * Search fix Co-authored-by: Copilot <copilot@github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: Copilot <copilot@github.com>Osvaldo Ortega · 4701612e · 2026-04-28