Osvaldo Ortega
90d · built 2026-08-09
90-day totals
- Commits
- 49
- Grow
- 19.7
- Maintenance
- 4.2
- Fixes
- 2.7
- Total ETV
- 26.5
Where this dev ranks
Percentile against the global top-100 leaderboard (all-time totals).
- By commits
- Top 70 %
- By Growth share
- Top 0.1 %
30-day trajectory
Last 30 days vs. the 30 days before. Up arrows on Growth and ETV mean improvement; up arrow on Fixes share means more time on fixes (worse).
↑+72.7 %
vs 11 prior
↑+3.8 pp
recent vs prior
↑+9.3 pp
recent vs prior
Daily performance
Daily ETV, stacked by Growth, Maintenance and Fixes.
Work-mix over time
Share of Growth / Maintenance / Fixes over a rolling 7-day window. Reads as 'where is effort flowing right now'.
Repository spread
Where this developer's commits land. Concentrated work (top1 > 80%) vs polymath spread (top1 < 30%).
Most impactful commits
Top 20 by ETV in the 90-day window.
- 3.4ETVCopilot cloud sandbox sessions over a live Agent Host Protocol relay (#328097) * Add Copilot cloud sandbox sessions over a live AHP relay Copilot cloud sessions whose tasks run in a Mission Control sandbox (agent slug `copilot-developer-cli`) are rendered by polling REST logs today, so they have no slash commands and no steering. Connect to the sandbox instead: `copilotd` runs inside it and speaks the Agent Host Protocol, so once a relay is open the existing agent-host stack renders the session natively — history, live output, steering and slash commands. The sandbox is not directly addressable, so both sides connect outward to an Azure Web PubSub relay brokered by Mission Control. Credentials are minted per connection, and the user's GitHub token is forwarded only as a sealed envelope the relay cannot read. Everything runs in the renderer, so this also works in VS Code Web, where no Copilot extension host is available. Mission Control is reached over the Copilot API host: `api.github.com/agents/*` omits CORS headers on authenticated responses, so a renderer fetch receives the reply and then discards it. The AHP `initialize` now advertises every protocol version this client can negotiate rather than only the newest, so a sandbox running an older `copilotd` can negotiate down instead of being rejected. Gated behind `chat.agentHost.cloudSandbox.enabled`, off by default. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review feedback for cloud sandbox sessions - Subscribe to host state by the backend URI. Session output, changesets and last-turn changes still rebuilt the URI from the UI scheme, so an aliased sandbox session subscribed to a URI the host's registry does not know. - Apply the session-scheme alias on the live `SessionAdded` path too. Only the refresh and persistence paths adopted, so a session created while connected kept the host's scheme and never routed to a content provider. - Report discovery completeness instead of a bare list. A failed or partial scan read as "these sessions no longer exist", so a transient request failure could tear down live providers and cancel the auth retry. Only a complete scan is reconciled against. - Cancel in-flight work when the feature is disabled. Discovery and connect ran with `CancellationToken.None` and did not recheck enablement after their awaits, so either could commit state — including a live relay — after teardown. - Document why publish acks are not tracked, and why the feature is gated on a setting: sandbox tasks carry a slug the Copilot extension's cloud provider does not list today, but that is expected to change. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Reuse the shared Copilot API host constant The cloud sandbox service declared its own copy of `https://api.githubcopilot.com` alongside the one in `githubEndpoints.ts`. Export the existing constant and use it, noting that it is distinct from `IGitHubEndpoints.apiBaseUri` (`api.github.com`). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 99f129b2 · 2026-07-29
- 2.1ETVPrompt timeline rail for the Agents window (#324131) * Add prompt timeline rail to the Agents window Introduce a right-edge "prompt timeline" rail in the Agents window that lets users scan and jump between the prompts they have sent in a chat session, adapted from GitHub's "jump to your messages" affordance. - Self-contained contrib under src/vs/sessions/contrib/promptTimeline, attached per-widget via IChatWidgetContrib (no vs/workbench changes). - Recency-bucketed ticks (pure, unit-tested budgetBucketPrompts) capped so each tick keeps a >=24px hit target (WCAG 2.5.8). - Dense marks at rest that expand on hover/focus, with green/red per-turn diff magnitude and a solid-blue active mark. - Interactive hover card: prompt text, clickable +/- diff stats that open the per-request diff, and per-file drill-down rows. - Per-request diffs via provider-agnostic IChatResponseFileChangesService (agent-host server-computed turn changeset) with editing-session fallback; diff sides are probed so missing checkpoint blobs render as a pure add/delete instead of crashing the multi-diff editor. - Keyboard-first commands: Go to Next/Previous Prompt, Go to Prompt... (quick pick), Review Changes for Prompt, with ARIA announcements. - Gated behind the new sessions.promptTimeline.enabled setting and ChatContextKeys.enabled; rail is created/disposed reactively. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: quiet gray-dense rail with single-mark accordion Replace the whole-rail expand-on-engage behavior with a per-mark accordion. The rail now stays quiet, gray and dense at all times; only the mark under the pointer (or keyboard focus) expands to a >=24px pill and reveals its green/red diff, so the rail no longer becomes a column of slim pills with large gaps when interacted with. - CSS: drop the `.engaged` whole-rail slot expansion and the transform fisheye; expand only `:hover`/`:focus-visible` marks (8px -> 24px slot, fat pill, diff colors). Active mark stays solid blue in every state. - Rail: remove the fisheye magnify, the engaged-state tracking, and the magnitude width buckets; capacity now reserves headroom for a single expanded mark over the dense 8px rhythm, so more prompts fit. - Drop the now-unused --tick-scale/--tick-scale-y custom properties. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: open per-file diff inside the multi-diff, revealed at that file Clicking a file row in the hover card previously opened a standalone single-file diff. Route it through the same multi-file diff we already build for "Review Changes", passing viewState.revealData so it opens revealed at the clicked file. Per-file and whole-prompt review now share one multi-diff experience (and open in the modal editor when enabled), reusing the existing MultiDiffEditorInput without any new UI. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: show per-turn diffs against the frozen after-turn snapshot The per-prompt diff was rendering before-turn vs the live working file, so it showed the combined changes of all later turns. The per-turn changeset already carries a frozen "after" snapshot; surface it and diff against it. - Add optional `modifiedContentURI` to IEditSessionEntryDiff: the frozen after-state RHS content, distinct from `modifiedURI` (the live file used for identity / go-to-file). Opt-in, so existing consumers (e.g. the chat "Changed N files" summary) keep their current behavior unchanged. - Populate it in AgentHostResponseFileChangesProvider from the changeset's after-content; extend its test to assert the mapping. - PromptTimelineModel now diffs originalURI (frozen before) against the frozen after snapshot, so review shows only that turn's changes, while go-to-file still opens the live working file. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: add an overview-ruler style selectable by setting Introduce a second rail style and let users choose via the new sessions.promptTimeline.style setting ('compact' | 'overview'). - Extract IPromptTimelineRail as the seam the contrib consumes, and a shared PromptTimelineCard (hover preview) used by both styles. - Rename the existing rail to PromptTimelinePillRail (dense pills). - Add PromptTimelineRulerRail: the session compressed into the rail like the editor overview ruler — proportional marks at their transcript scroll positions, a scrollbar-slider you-are-here thumb, one green "changed code" signal (editorOverviewRuler.addedForeground), focusBorder active, >=24px hit targets. Detail stays in the shared hover card. - Model exposes getScrollLayout()/onDidChangeScrollLayout for proportional positions (per-request offsets via currentRenderedHeight + scrollTop). - Contrib picks the rail class reactively and reuses the enablement swap pattern, wiring setScrollLayout only for rails that support it. All colors come from real theme tokens. Validated: typecheck, eslint, layers, hygiene, unit tests (12 passing). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: position overview-ruler marks from the list layout model The overview-ruler rail placed each mark by accumulating chat items' `currentRenderedHeight`, which the virtualized tree only sets for rows it has actually rendered. Off-screen prompts reported `undefined` (treated as 0), so every not-yet-rendered mark collapsed onto the same position and only spread out as the user scrolled and rows rendered. Read each prompt's top from the list's layout height model instead, the same virtualization-safe source the scrollbar uses (all items have a height via the delegate's `currentRenderedHeight ?? defaultElementHeight`). Threaded a read-only accessor through the layers, all in the list's content-pixel space so the viewport thumb stays aligned: - AbstractTree.getElementTop(location): absolute top (works off-screen), sibling of getRelativeTop. - ChatListWidget.getElementTop / ChatWidget.getElementTop + ChatWidget.scrollHeight. - PromptTimelineModel.getScrollLayout() and _updateActive() now use these instead of accumulating currentRenderedHeight. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: color ruler marks by the turn's add/remove split Ruler marks were a single green "edited" signal, so a delete-heavy turn still showed green. Render the mark as a two-tone bar instead (a green added segment and a red removed segment sized by flexGrow from the turn's diff stat), reusing the pill rail's seg-add/seg-del pattern. Only the non-zero side is appended, so a pure-add turn is fully green and a pure-delete turn fully red, and a 1px min-width keeps the minority color visible on a lopsided split. Segments go transparent while the mark is active so the focusBorder you-are-here color wins. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: fall back to the live file when a turn snapshot is unreadable Per-turn review diffed the frozen before/after turn-checkpoint snapshots so only that turn's changes show. But those checkpoint blobs can be absent (an added file's original, or a pruned/restored session where whole turn checkpoints are gone). When both sides were unreadable every item was dropped and reviewChanges opened nothing at all. _readableSides now still prefers the frozen snapshots but falls back to the live working file for the modified side when the checkpoint blob is unreadable, so review always opens with the best available fidelity. An unreadable side is still dropped so the file renders as a clean add/delete instead of crashing the diff editor. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: drop the pill style, keep only the overview ruler The rail shipped with two selectable styles (dense pills vs overview ruler) behind sessions.promptTimeline.style. We're standardizing on the overview-ruler UX, so remove the pill style and the setting entirely (the on/off sessions.promptTimeline.enabled setting stays). - Delete promptTimelinePillRail.ts and the PROMPT_TIMELINE_STYLE_SETTING / PromptTimelineStyle enum. - The contribution always builds the ruler rail; drop the style-based swap, the capacity->display-budget wiring, and the optional setScrollLayout indirection (now required on the interface). - Model no longer tracks a dynamic display budget; ticks bucket against the constant MAX_TICKS (still caps very long sessions). - Remove the pill-only CSS; the overflow rule now hides the ruler marks. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: address review feedback on grouped-tick diffs and read probes Two fixes from a council review: - getRequestFiles: when a grouped tick edits the same file in more than one prompt, advance the merged entry's diffModifiedURI to the later prompt's after-snapshot (keeping the earliest originalURI) so the opened multi-diff spans the whole tick instead of only the first edit. - _canRead: probe availability with readFile(resource, { length: 1 }) instead of reading whole (potentially large) file contents just to test whether a diff side is readable. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: refresh comments left over from earlier iterations Comment-only cleanup after removing the pill style and the display-budget mechanism: drop the stale "or budget", "(like the pill rail)", and "visual density" references so the docs match the single overview-ruler implementation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: gate the enabled setting behind an experiment Put sessions.promptTimeline.enabled behind the experimentation service via the `experiment: { mode: 'startup' }` property (the sanctioned way for core TS-registered settings; the registry auto-adds the onExP tag). Default is now false so the rail is off until the experiment (or the user) turns it on. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: address PR review feedback and fix class-field init order Review fixes: - Remove the redundant GoToNext/GoToPrevious commands: they duplicated and collided with the built-in chat nextUserPrompt/previousUserPrompt keybindings (same chord, weight, when). Drop the two actions, their command ids, contrib.navigate(), and model.getSiblingTick(). GoToPrompt and ReviewChanges stay. - Fix the active-mark fallback: when scrolled above the oldest prompt, highlight the oldest tick (ticks.at(0)), not the newest (ticks.at(-1)). - Replace the getComputedStyle probe + unreverted host `position` mutation with a lifecycle-scoped `.prompt-timeline-host` class removed on teardown. - Give the overview-ruler toolbar a proper keyboard model: aria-orientation, roving tabindex (a single Tab stop) and Arrow/Home/End navigation between marks. Also assign `_sessionResource` in the constructor instead of a field initializer: it reads `this.widget`, which under useDefineForClassFields is not yet assigned when field initializers run (fixes the define-class-fields-check / TS2729). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: stop showing the unreliable per-prompt timestamp Agent-host sessions don't record per-turn timestamps; the transcript is reconstructed via ChatModel.addRequest(), which stamps Date.now(), so every prompt showed ~the current time. Since the real send times aren't available to recover, drop the absolute time from the hover card and the "Go to Prompt" picker. Grouped ticks still show their prompt count; the prompt text and diff stats (both reliable) are unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: act on PR review (remove ReviewChanges action; rename modifiedContentURI) - Remove the ReviewPromptChangesAction command: per-prompt review is already available from the hover card, so the palette/keyboard entry point was redundant. Drops the command id and the now-unused contrib.getActiveTick() / contrib.reviewChanges() bridge (model.reviewChanges stays, wired to the card). - Rename IEditSessionEntryDiff.modifiedContentURI -> modifiedSnapshotURI: it's the frozen after-turn snapshot content, and "snapshot" reads clearer next to modifiedURI (the live file) than "content". - Clarify in comments that this field is distinct from the agent-host checkpoint- ref readability fix (#323932): that made the snapshot blobs readable; this carries which snapshot to diff against so a per-turn review shows only that turn's changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 04c9ab57 · 2026-07-07
- 1.5ETVServe cloud sandbox history when the environment is gone (#329292) * sessions: serve cloud sandbox history when the environment is gone A managed sandbox's compute can be deleted, and once it is the AHP relay to it is gone for good. Opening such a session refused to open at all: the only path to its history ran over that relay, so the user was left with a session that would not load and no stated reason. Mission Control mirrors every ActionEnvelope it relays, so the same history can be rebuilt from `GET /agents/tasks/<id>/events` without the sandbox. `taskEventReplay` folds those frames back into session and chat state using the very same reducers the live subscriptions use, so a replayed session and a live one cannot drift. Opening a session no longer waits for `/connect` to give up before it can render. Mission Control blocks on the compute resume before replying, so that call can occupy its whole budget — measured at ~9s of waiting on a deleted sandbox while the transcript already sat ready. The connect and the history fetch now overlap, and whichever lands first decides what the user sees: the session renders as soon as history arrives (~500ms) and is settled read-only only once the connect has actually failed. Read-only is an observable, so a session already on screen loses its composer in place rather than needing a reopen. `/connect` is also no longer retried. Mission Control's answer already reflects the resume it just attempted, so re-asking only repeats the wait; `202 waking` remains the one polled case, against its own Retry-After. `ICloudSandboxCredentialsService` is renamed to `ICloudSandboxApiService`: it now also reads environment and task records, discovers sessions, and replays history, so "credentials" no longer described it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: address review feedback on cloud sandbox history - Guard against registering a second content provider for a session type. The connect can register the live handler at any await between starting it and observing its outcome, so the history race could resume after that registration and throw, failing the open entirely. The check and the registration are synchronous, so nothing can interleave. - `_settleReadOnly` now no-ops unless we actually own the stand-in, so it cannot force a live host read-only. - Preserve truncation across a mirror restart: replacing the reassembler discarded the knowledge that the previous epoch ended mid-action, so a lost action reported `truncated: false`. Covered by a test that fails without the fix. - Surface truncation in the conversation itself rather than only in the log, so a partial transcript cannot read as a complete one. - Document the provider-level read-only producer in SESSIONS.md, which previously described subagent chats as the only one. - Fix a test comment describing retry behaviour that no longer exists. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · e43e8013 · 2026-08-06
- 1.3ETVFix new cloud session disappearing and misgrouping after commit (#326230) * Fix new cloud session disappearing and misgrouping after commit The Agents window (vs/sessions) drove a new cloud (RemoteNewSession) agent session through the wrong commit path, causing it to disappear ~5s after delegating, and then group under "Unknown" / flip its repo label once it did appear. Three related fixes: 1. Wait for the committed resource on cloud sessions. A cloud session commits a new resource mid-request (untitled -> /task/<id>), like Copilot CLI, so _sendFirstChat now routes RemoteNewSession through _waitForCommittedSession instead of waiting on the stale untitled resource (which timed out and removed the session). The wait is also deferred (skips the response-complete race, longer timeout) because the cloud commit is delayed by a confirmation round-trip and network delegation. 2. Attach owner/name metadata to PR-less task cards so a freshly created task groups under its repo instead of "Unknown"/"Other" until a PR resolves. Repo identity is hoisted from PullArtifactRef.repo to CloudSessionData.repo (a task has a repo regardless of a pull artifact); resolvePullArtifact now takes repo as an explicit argument. 3. Consolidate the repo label. Both the new-session workspace and the committed session adapter now derive an owner/repo label via a shared githubRemoteRepoLabel helper, so a cloud session stays in the same group before and after commit (no more microsoft/vscode -> vscode flip). Adds a regression test for the cloud commit-swap. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Comments --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · b12476e6 · 2026-07-17
- 1.2ETVImplement cloud sandbox retry count and telemetry tracking (#328290)github.com-microsoft-vscode · 667ea723 · 2026-07-31
- 1.1ETVsessions: prompt timeline UX improvements (#326023) * sessions: prompt timeline rail becomes one scrollbar that fans in on scroll/hover Reshape the prompt timeline into a single scrollbar lane instead of a pill column sitting next to the transcript's native scrollbar. At rest it is a plain scrollbar (the rail draws its own thumb and the transcript's native vertical slider is hidden while the rail is active). On a deliberate gesture the thumb recedes and the prompt pills fan in over the same lane with a macOS-dock style fisheye: - Hard/fast scroll (wheel-velocity gated, capture phase so it works mid-content not just at the scroll limits) blooms the fan centred on where you are, and it glides continuously with the viewport as you keep scrolling. The reveal is gated on a real scrollTop change, so flicking against the top/bottom limit - or programmatic virtualization nudges - never opens it. - Hovering the lane blooms the fan and lets it follow the cursor; dragging the lane scrubs the transcript; clicking a pill still jumps; keyboard focus reveals the pills. It quietly collapses back to a plain scrollbar after a short linger once you stop scrolling and are not hovering. - Pills are laid out as an evenly-spaced dock centred in the lane (stable under virtualization) rather than scattered by content position; the two-tone green/red diff decoration and the hover card are preserved. Also reduces forced reflows on the hover/scroll paths (position the card and lane from cached geometry instead of getBoundingClientRect) and avoids churning the linger timer every scroll frame. Reduced-motion disables the fisheye but still reveals the calm dock. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: address prompt timeline PR feedback - normalize wheel deltas via StandardWheelEvent so line-mode devices trigger the fan - keep the native scrollbar when the rail is too narrow (below MIN_HOST_WIDTH) to replace it - use generic mouse listeners for lane scrub + mark guard so touch/iOS works - track keyboard focus: reveal a calm dock (:focus-within) with the fisheye suppressed - scale scrollTop into the estimated coordinate space before interpolating the fan focus - map the thumb/scrub math onto the list viewport height (ScrollbarState-style) - use --vscode-cornerRadius-circle for the thumb radius - extract the hard-wheel detector into a named helper Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * distance update --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · c54ca24a · 2026-07-15
- 1.1ETVCloud agent: Create/Open pull request toolbar actions for settled tasks (#321520) * Cloud agent: Create/Open pull request toolbar actions for settled tasks Adds chat-input toolbar actions for v2 (Task API) cloud agent sessions: - "Create pull request" for a settled, PR-less task; the backend resolves the repo from the task (html_url, falling back to a GitHub repo-by-id lookup) and creates the PR, then re-applies the toolbar gates in place. - "Open pull request" (icon-only) once the task has a PR, opening it in the browser; resolves both task- and PR-keyed session resources. Also: compare-based changed files for settled PR-less tasks, reactive gate re-evaluation on task settle / PR creation, and resolver-path telemetry. Core: icon-only rendering for the open-PR action in the session changes toolbar. * Address review: fix create-PR response test shape, stale wording, telemetry name - Test FakeTaskApiClient now returns the real AgentTaskCreatePullRequestResponse shape ({ id, number, repository_id }) instead of the stale { pull_request }. - Reword the no-reflect warning and create-handler doc that wrongly implied a refresh (the handler updates the toolbar gates in place). - Rename the resolver telemetry event back to copilotcloud.pullArtifactResolve. - Drop the 'browser-open glyph' wording now that the open-PR icon is git-pull-request.github.com-microsoft-vscode · 7f0b0dea · 2026-06-16
- 1.1ETVCloud Agent: Tasks API experimental setting and backend (#317206) * Cloud Agent: Tasks API experimental setting and backend Introduces a CloudAgentBackend seam with two implementations: - JobsApiBackend wraps the existing sweagentd Jobs API (default, no behavior change). - TaskApiBackend implements the new Mission Control Task API and currently uses a StubTaskApiClient pending CAPI routing. Selection is controlled by the new 'github.copilot.chat.cloudAgentBackend.version' setting ('v1' = Jobs API, 'v2' = Task API). The setting is tagged experimental and defaults to 'v1', preserving existing behavior for legacy users. * Review comments * Address PR review feedback - TaskArtifactPullData: add optional 'number' field separate from db id - Add ListTaskEventsOptions for event-specific pagination/filters - Relax sendFollowUp success check (only undefined is failure) - Drop unused _configurationService field; read config locally in ctor - Document that cloudAgentBackend.version requires reloadgithub.com-microsoft-vscode · c96dc550 · 2026-05-19
- 1.0ETVCloud agents on task API - Initial part (#317659) * Update * Review comments * Refactor * lock revert * Update * cleanupgithub.com-microsoft-vscode · b700ecb3 · 2026-05-21
- 1.0ETVSessions: chat timeline variant (#327065) * Agent Host changes for osortega/agents/chat-session-timeline-ui-proposal * sessions: add dock rail variant to prompt timeline Adds a 'dock' style to sessions.promptTimeline.rail: a minimal left-edge handle (one dot per prompt, capped at 50 with an overflow marker) that opens an accessible flyout listing every prompt. Changes the setting to a string enum (off|ruler|dock), feeds the dock an unbucketed per-prompt list so entries are individually selectable, and wires the handle as a touch/keyboard disclosure (Gesture + click/tap, aria-haspopup/expanded/ controls) that closes on activation or Escape and restores focus. Adds aria-current to the active row, pairs the selection colours, snaps to design-system radius/spacing tokens, and documents the surface in the Sessions chat accessibility help. The sticky header label now navigates to the pinned prompt instead of opening Go to Symbol. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 27385137 · 2026-07-23
- 0.9ETVLive streaming for Task API cloud agent sessions (#319077) * Live streaming for Task API cloud agent sessions Adds TaskTurnStreamer to incrementally push v2 Task API events into vscode.ChatResponseStream for both initial open (mode: 'current') and follow-up sends (mode: 'next'), mirroring the v1 JobsApiBackend SSE flow. Key design (modelled after github-ui/agent-sessions): - Eager tool rendering from assistant.message.toolRequests, since tool.execution_complete does not fire for many agent-host-synthesised setup ops (run_setup, run_custom_setup_step). - Per-messageId content dedup: Task API sends progressive snapshots, not deltas; only the suffix is fed to the renderer. - Intermediate assistant.message.content (content + toolRequests in the same event) is suppressed; only pure-text assistant messages (the final reply of the turn) are rendered as markdown. - Default 'Working...' progress label until the first assistant.intent arrives. - Bounded poll loop: exits on terminal state, cancellation, or MAX_CONSECUTIVE_FETCH_FAILURES. - Follow-up (mode: 'next') only advances when task.sessions.length grows, to avoid premature exit when trailing prior-turn events arrive between the snapshot and sendFollowUpToTask resolving. ChatSessionContentBuilder updates: - buildTaskHistory: single-pass turn split + bootstrap event suppression. - buildTaskResponseTurn: mirrors the live rules (eager tool rendering, intermediate-narration suppression, dedup with live cards) so the refresh() after streaming is idempotent. - parseToolCallDetails: friendly cards for run_setup, run_custom_setup_step, report_intent. - toFileLabel: handles v1 (/home/runner/work/...) and v2 (/tmp/workspace/..., /workspace/...) layouts. * Address PR review: parallelize fetches, fix stale comment, add Task API history tests - Parallelize fetchTask/fetchEvents with Promise.all in both the main poll loop and _waitForTurnStart so each poll only pays the slower of the two requests. - Update StreamBaseline JSDoc to reflect that phase 1 (mode: 'next') unblocks only on turnCount > priorTurnCount, not 'any unseen event'. - Add unit tests covering the new Task API history rules: bootstrap suppression, turn-boundary split, eager tool rendering with execution_complete dedup, intermediate-narration suppression, and the synthesised-turn fallback when no user.message has arrived. * Readme updategithub.com-microsoft-vscode · ab926524 · 2026-05-30
- 0.9ETVInstrument Cloud Agent backend v1/v2 rollout behind an experiment (#321818) * Instrument Cloud Agent backend v1/v2 rollout Put the `chat.cloudAgentBackend.version` toggle (v1 = Jobs API, v2 = Task API) behind an experiment so the rollout can be ramped and rolled back remotely via ExP, and add an arm-tagged telemetry surface so the two backends emit identical funnel and guardrail signals for apples-to-apples monitoring. Previously v1 was partly instrumented and v2 emitted nothing, making any A/B comparison impossible. A shared `ICloudBackendInstrumentation` is now injected into both backends and stamps every event with `backendVersion`, covering session creation, activation, follow-up, and per-operation errors, plus matching OTel metrics. v2's silent catch sites now report through it, and `TaskApiError` carries the HTTP status for error classification. Legacy v1 backend events are consolidated into the shared surface and kept for dashboard continuity. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Rename "arm" to "backend version" in cloud telemetry comments "arm" is A/B-experiment jargon not used elsewhere in the codebase. Swap it for "backend version" in comments, docstrings, and GDPR comment text to match the existing `backendVersion` / v1 / v2 vocabulary. Comment-only change; no identifiers or behavior affected. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address cloud backend rollout PR review comments - Move backend_version attribute to the canonical github.copilot.* namespace - Derive numeric HTTP status inside operationFailed so the status measurement is populated - Carry HTTP status on v1 (Jobs API) invalid-job errors via JobsApiError so v1 create failures classify by status - Only emit cloud pr_ready.count for v1 (Task API activation is a first turn, not a PR) - Add unit tests for the new cloud metrics - Document the new cloud operation/error metrics and backend_version attribute Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix TaskApiBackend construction in fetchSessionList specs Three fetchSessionList test cases constructed TaskApiBackend without the required instrumentation argument, failing the CI typecheck (TS2554). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · d8716e01 · 2026-06-17
- 0.8ETVSupport Go to Symbol (⇧⌘O) for chat sessions (#326739) * Support Go to Symbol (⇧⌘O) for chat sessions Adds a chat outline so "Go to Symbol in Editor" lists each user request as a navigable symbol, jumping to it in the chat. Works for chat editors (via IOutlineService) and for a focused chat widget including the Agents window. - New ChatOutline / ChatOutlineCreator registered with IOutlineService so chat editors light up Go to Symbol, the Outline pane and Breadcrumbs. - GotoSymbolQuickAccessProvider prioritizes a focused chat widget in provide() so it wins over an active file editor opened side by side, and detects focus via isAncestorOfActiveElement. - Request labels are derived like the chat list renders them (followup message, else parsed request parts), not messageText which agent-host sessions leave empty. Codicons are embedded inline in the quick pick label (iconClasses can't render codicons in this path). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR feedback for chat Go to Symbol - Fall back to an attachment summary (matching the chat list) for attachment-only requests before the numbered label. - Move ChatOutlineCreator into its own file and re-export ChatOutline through chat.ts so codeEditor consumes the contribution's API file instead of importing chatOutline.ts directly. - Only refresh the outline when request entries actually change, so streamed response updates don't rebuild it repeatedly. - Add a chatOutline unit test suite (label derivation incl. empty text and attachment-only requests, icon escaping, change detection, reveal/preview). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · a76d1d0d · 2026-07-21
- 0.7ETVAdd inline 'Create pull request' confirmation for completed tasks without PRs (#319629) * Add inline "Create pull request" confirmation for completed tasks without PRs * Update * Revert monaco change * Review comments * Fix * Revertgithub.com-microsoft-vscode · 373aead7 · 2026-06-05
- 0.6ETVPrompt timeline: reduce scroll jitter and polish the rail (selection, spacing, performance) (#325041) * Prompt timeline: reduce ruler scroll jitter with adaptive height estimate The ruler positioned marks from the chat list's height model, where every un-rendered row is guessed at a flat 200px default. Real turns vary widely (short prompts, tall/variable responses), so as rows render and get measured the list's tops snap around and the marks visibly drift while scrolling a fresh session. Compute the marks' positions from our own per-item height model instead: measured rows use their real currentRenderedHeight; un-measured rows use a running average of measured heights of the same kind (prompt vs response, seeded with priors). Marks land near their final position immediately and barely move, converging exactly with the list once every row is measured. Keep the viewport thumb in the list's own scrollTop/scrollHeight space so it stays aligned with the native scrollbar (the marks' estimated space would separate from it while heights settle and look like a second scrollbar). Add a short 'glide' transition, enabled one frame after each structural rebuild, so any residual drift animates smoothly without new marks sliding in from the top; disabled under prefers-reduced-motion. Also improve the keyboard focus indicator: grow the focused mark to a rounded pill hugged by the focus ring instead of a bare outline on the 2px bar. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: polish rail selection, spacing, and scroll performance Builds on the scroll-jitter work with a round of UX and performance fixes: - Selection: replace the glowy box-shadow/backing-lane with a crisp border on the pill, and give keyboard focus a distinct dashed ring so a focused mark is never mistaken for a second selection. There is only ever one selected mark (it follows the viewport and click-reveal). - No !important: the workbench outlines any focused [tabindex=0] button, which boxed the mark; suppress it by qualifying our rule through the marks container to win on specificity instead. - Scrollbar: reserve a gutter (derived from the real scrollbar width) so the marks sit left of the native scrollbar and it stays grabbable. - Spacing: reserve room on the transcript's right edge so message content keeps a guaranteed minimum gap from the marks, derived from the rail width via CSS variables rather than a magic number. - De-cluster marks: prompts that sit close in content space could let the 24px hit targets overlap; space adjacent mark centres apart (new pure promptTimelineLayout.ts, unit-tested). - Performance: the rail relayout read clientHeight on every scroll event (a forced reflow -> ~19% of active CPU while scrolling). Cache the height (refreshed only on resize) and coalesce scroll relayouts to one per animation frame; a re-profile shows relayout self-time drop from ~968ms to ~2ms. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: define the scrollbar gutter in CSS instead of JS Review feedback: the gutter was set from JS (DEFAULT_SCROLLBAR_SIZE + gap), but the list scrollbar is a stable 10px and the rail's other geometry already lives as CSS variables on .prompt-timeline-host. Move it there as --prompt-timeline-scrollbar-gutter and drop the runtime setProperty, the constant, and the base import. Not related to the focus-outline specificity fix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Prompt timeline: simplify spaceMarkCenters even-distribution branch Review feedback: the even-distribution branch is only reached when (n - 1) * minGap > hi - lo, and hi > lo is already guaranteed, so n >= 2 there. The n === 1 guards were dead code; remove them. Single-mark inputs go through the forward/backward clamp pass, which the unit tests still cover. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 078671da · 2026-07-08
- 0.6ETVImprove Copilot Cloud Sessions error handling and messaging (#325196) Agent Host changes for osortega/agents/copilot-cloud-sessions-v2-backendgithub.com-microsoft-vscode · ce5e0c65 · 2026-07-10
- 0.6ETVMobile chat (1/10): infra primitives — bottom sheet body, visualViewport, longPress, pulldown, edge-swipe (#318647) * Mobile infra: bottom-sheet body, visualViewport, longPress, pulldown, edge-swipe Foundation primitives used by the rest of the mobile-chat stack: - mobilePickerSheet.ts: extract shared sheet shell + add showMobileContentSheet for arbitrary-body overlays (used by confirmation/plan-review/anchor-peek/code-block sheets in follow-ups). - mobileVisualViewport.ts: IMobileVisualViewport service publishing keyboardHeight observable + --vscode-keyboard-height CSS var + KeyboardVisibleContext. Replaces the inline visualViewport block in workbench.ts. - longPress.ts: reusable installLongPress helper (powers chat-row action sheets in a follow-up). - mobilePulldownDismiss.ts: pull-down-to-dismiss gesture used by the mobile diff/changes/code-block overlays in follow-ups. - mobileEdgeSwipe.ts: left-edge swipe gesture that opens the sidebar drawer; integration with workbench.ts ships in the overlays PR. - vscode-known-variables.json: register --vscode-keyboard-height so stylelint accepts CSS that consumes it. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix long-press click suppression and restore session-view stylelint vars * Restore activeSessionView/inactiveSessionView stylelint vars * Address PR review: pointer capture for gestures, fix keyboard-height comment * Use const shell with forward reference in mobile sheet helpers --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · a51c7371 · 2026-06-02
- 0.5ETVchat: bring the sticky prompt header to the regular window (#327889) * chat: bring the sticky prompt header to the regular window The prompt timeline's sticky header — the band that pins the prompt you have scrolled past to the top of the transcript, with previous/next navigation — only existed in the Agents window, because it lived in vs/sessions and only that layer loaded it. Move the feature to vs/workbench/contrib/chat and register it from chat.shared.contribution, which both windows import, so the chat view and chat editor get the same header from one implementation. The rail (ruler and dock) stays Agents-window only: its layout and content reservation are built for the centered session view, so it is now gated on IWorkbenchEnvironmentService.isSessionsWindow. Replace sessions.promptTimeline.stickyHeader with chat.promptTimeline.stickyHeader, defaulting to on outside stable, and migrate an existing opt-in over. Mount the header only on widgets that render their input below the transcript (new IChatWidget.rendersInputOnTop), which excludes quick chat and the new-session composer. The band now composites the request-bubble tint over the widget's own list background so it stays opaque over scrolling rows in either host, with the Agents window's box model kept as an override. Also document the header in the chat accessibility help, and stop scanning the whole transcript on every scroll now that the header is on by default. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * chat: only describe the sticky prompt header where it is mounted The accessibility help derived the sticky-header text from the setting alone, with a 'not quick chat' proxy for the host check. The new-session composer (agentSessionsWelcome) is a ChatAgentLocation.Chat widget with renderInputOnTop, and AgentChatAccessibilityHelp's when clause does not exclude it, so its help could announce a header and Previous/Next buttons that are not there. Export the contribution's own predicate as isStickyPromptHeaderShown and use it for the help text, so the two cannot drift. Cover the predicate and the help branch with tests. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · b89d0ac8 · 2026-07-29
- 0.5ETVsessions: add prompt timeline sticky header (#326080) * sessions: add prompt timeline sticky header Adds a flat, opaque "sticky prompt header" to the Agents window chat transcript, modelled on the editor's sticky scroll: while you scroll it pins the current prompt to the top, names it with an N/M position, and opens the prompt picker when selected so you can jump anywhere. The timeline is now split into two independently toggleable surfaces, each backed by the experimentation service and off by default: - sessions.promptTimeline.rail — the scrollbar that fans into prompt pills on scroll/hover - sessions.promptTimeline.stickyHeader — the sticky prompt header Both reuse the shared PromptTimelineModel (new activeTick + activePinned observables) and the existing "Go to Prompt..." picker. The former single sessions.promptTimeline.enabled setting is removed in favour of the two surface settings, so rail-only, header-only, both, or neither all work. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: simplify prompt timeline setting descriptions Tighten both setting descriptions to a single "Controls whether…" sentence matching the house style, dropping the implementation detail. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: address prompt timeline sticky header review feedback - derive the sticky label and N/M position from the unbucketed active prompt so long chats (over the rail's tick cap) report the real prompt and total, not a bucket representative - rely on the native button for Enter/Space activation instead of a hand-rolled key handler - fall back to the localized "(empty prompt)" label for attachment-only prompts - suppress the band's drop shadow in high-contrast themes Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>github.com-microsoft-vscode · 58b94adf · 2026-07-16
- 0.4ETVRender cloud task history from typed session events (#318646) * CAPI package update * Missindg updates * Missing lock * Render cloud task history from typed events - Extract shared session-event-to-chat-parts renderer into chatSessions/common/sessionEventRenderer.ts so both the Copilot CLI and Cloud Tasks providers produce identical tool/text formatting. - Render Task API history via the shared renderer, remapping custom_agent.* to the equivalent subagent.* names so tool cards, bash terminal output, edits, search results, MCP results and subagent groups all render the same way they do in the CLI. - Match github.com/github/github-ui presentation by suppressing intermediate assistant.message events that echo tool input/output and only rendering the final summary message per turn. * Address review: break circular dep & restore flush timing - Inject CLI tool-event handlers (processStart/processComplete/ enrichSubagent/isEditToolCall/getEditedUris) into the shared renderer via a ToolEventHandlers<T> bundle, so common/sessionEventRenderer no longer imports from copilotcli/. Layering now only flows one way. - Flush buffered assistant.message_delta chunks at the top of the CLI loop for non-message events so the session.model_change / assistant.usage guards see streamed text exactly the way the pre-extraction code did. * Missing lock changes * Revert unintended copilot package manifest edits * Revert unintended root package manifest edits * remote package revert * lock --------- Co-authored-by: Dmitriy Vasyura <dmitriv@microsoft.com>github.com-microsoft-vscode · d53d5057 · 2026-05-28