mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-08 07:44:33 +01:00
anthonykim1/copilotToLocalNotPossibleInEditChat
1384 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
94c155c4d9 |
sessions: single-pane layout controller cleanup (#324410)
* sessions: single-pane layout controller cleanup (no workbench.ts) Base/single-pane layout controller changes assembled without the workbench.ts side-pane Strategy extraction: - R1: remove the base-controller single-pane leak via Template Method hooks and override them in SinglePaneDesktopSessionLayoutController. - Additional single-pane controller / editor contribution refinements and spec updates (LAYOUT.md, SINGLE_PANE_SCENARIOS.md, sessions SKILL.md). Excludes workbench.ts, sidePaneLayoutStrategy.ts and workbench.test.ts by design. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: capture editor-part hidden state eagerly to fix side-pane restore race The per-session editor-part hidden state was captured lazily in _saveWorkingSet by reading live editor visibility at switch-away time. That races the switch derive (activeSessionForWorkingSet lags the raw active session), so the incoming session's layout could flip the outgoing session's recorded state to visible — reopening a side pane the user had closed when switching back to it. Capture it eagerly via a [B2] onDidChangePartVisibility(EDITOR_PART) listener (mirroring the [B1] panel capture), guarded by single-session and not-restoring, and drop the racy lazy read. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
5cfa71584e |
sessions: 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> |
||
|
|
7317e60fe4 |
sessions: 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> |
||
|
|
f6a4e0843f |
updates rspack
* reduces memory usage * loads fixtures from source instead of out |
||
|
|
6e0b2e9398 |
Guard node_modules cache against missing native optional-dep packages
Some deps ship their native binary in a per-platform package declared as an *optional* dependency of a small base package (e.g. `@openai/codex` -> `@openai/codex-<platform>-<arch>`, `@anthropic-ai/claude-agent-sdk` -> `@anthropic-ai/claude-agent-sdk-<platform>-<arch>`). npm does not fail when an optional dependency can't be installed, so a transient hiccup can leave the base package present but the per-platform package missing — and that broken tree then gets frozen into the shared node_modules cache and served to every consumer (see #323881). Add build/azure-pipelines/common/checkNativeOptionalDeps.ts and run it after `npm ci` in the linux, macOS and windows cache-build jobs (before the cache is saved). For each configured base package that is installed, it asserts the matching `<base>-<platform>-<arch>` package exists, and fails the job otherwise so a poisoned cache is never saved. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
4090e86ce8 |
sessions: show file icons in Session Files changes list (#324053)
The Session Files list in the Changes view did not render per-file-type icons because its list was placed outside the file-icon themeable scope. Add a file-icon themeable scope to the SessionFilesWidget root node and align its resource label rendering with ChangesTreeRenderer (strikethrough for deleted files). Also document the show-file-icons requirement in best-practices. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
6162ed61f7 |
sessions: tweak session files widget in changes view (#324034)
* sessions: tweak session files widget in changes view - Use default ResourceLabels (no supportIcons) so file icons render - Drop the resource path from the file description - Only open a diff for modified files when the original has content - Show A/M/D change decoration badges like the changes view - Remove strikethrough for deleted files - Add an Open File action to the row toolbar matching the changes view Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: remove file count from session files header Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
e63efae792 |
sessions: 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> |
||
|
|
90b81ef265 | Fix issues with chat perf pipeline (#323917) | ||
|
|
5a270e6dbd |
policy: resolve managed settings per-key across delivery channels (#323780)
* policy: resolve managed settings per-key across delivery channels Managed settings previously used a single authoritative source: the first non-empty delivery channel (native MDM > server > file) won wholesale and the others were ignored entirely. Switch to per-key precedence: the same order is honored, but resolved key-by-key. A key locked by a higher-precedence channel still cannot be overwritten, while keys a higher channel leaves unset are now filled in by a lower channel. Centralize the resolution in a new pickManagedSettings() (replacing selectManagedSettings) that returns the merged bag, per-key provenance, and the active sources, so policy evaluation and the Policy Diagnostics report share one implementation. Build the merged bag with Object.fromEntries so an untrusted __proto__ key cannot corrupt its prototype chain. Rework the Policy Diagnostics report to show every contributing source, a per-key Resolution table (effective value, winning source, and struck-through overrides), and per-key policy attribution. Add unit coverage for the per-key merge (provenance, fill-down, falsy values, ordering, prototype-pollution guard) plus an end-to-end test proving two keys can win from two different channels and both reach policy evaluation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: iterate managed-settings bags with Object.keys over own props Address PR feedback: switch pickManagedSettings from `for...in` to a guarded `Object.keys` loop so only own enumerable properties are visited (managed-settings bags are untrusted input) and absent channels are skipped explicitly. Note: `for...in` over an undefined bag was already a no-op (never threw), so this is a robustness/clarity improvement rather than a crash fix. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: tidy pickManagedSettings unit suite Drop two redundant cases (distinct-keys and standalone activeSources ordering, both already covered by the headline and empty/absent tests) and fold the non-contributing-middle-channel ordering check into the empty/absent snapshot. Verified against the live node unit runner (all green). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
b10844efce |
sessions: 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> |
||
|
|
84bf6e2e10 |
Add agent skill for integrated browser work (#323788)
* Add agent skill for integrated browser work * update * update * update |
||
|
|
ece376a4db |
sessions: persist main chat rename across restore for agent host (#323785)
* sessions: persist main chat rename across restore for agent host For agent host multichat sessions, renaming the default/main chat sets an independent title persisted on the host as customChatTitle:<defaultChatUri>. However restoreSession always re-seeded the default chat with an empty title (inherit the session title), so after a process restart or idle eviction the main chat tab reverted to the session title. Peer chats were already restored via _restorePeerChats. Read the persisted default-chat title on restore and seed it back through restoreSession/_ensureDefaultChat, mirroring the peer-chat restore path. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: clarify _readPersistedChatTitle doc comment Addresses CCR feedback: the helper now reads the default chat's title too, not only peer chats. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
6d52b5c5da |
policy: let native MDM win over server for managed settings (#323615)
* policy: let native MDM win over server for managed settings Flip the managed-settings precedence so native MDM takes priority over the GitHub server endpoint. selectManagedSettings now resolves native MDM first, then server, then the on-disk file, and the Policy Diagnostics report lists the channels in that same precedence order. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: update accountPolicyService tests, comment, and docs for MDM precedence Flip the AccountPolicyService precedence unit tests so native MDM wins over the server channel, fix the stale getPolicyData() comment, and update the add-policy skill docs to describe native MDM > server > file. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: reorder selectManagedSettings params to match precedence Address PR review: make the parameter order (nativeMdm, server, file) match the resolution precedence so same-typed call sites are self-documenting and harder to transpose. Update both call sites, the unit tests, and the skill docs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
b86f454a6f |
sessions: fix chat tab ordering in the Agents window (#323597)
Chat tabs reordered for two reasons. (1) The renderer partitioned chats by status, pushing in-composer Untitled chats to the end, so committing a draft out of creation order made its tab jump. (2) restoreSession seeded peer chats in Promise.all resolution order rather than getChats() order, scrambling the catalog on reload. Render the provider's stable creation order as-is, and restore peer chats in getChats() order while still loading their data in parallel. Update the sessions skill pitfall to match. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
884913d065 |
build: avoid per-section Electron re-download in PR test runs (#323341)
The GitHub Actions PR test workflows run integration/smoke tests out of sources, so each test section launches scripts/code.bat, which runs build/lib/preLaunch.ts. Unlike the Azure Pipelines product builds, the GitHub workflows did not set VSCODE_SKIP_PRELAUNCH, so preLaunch ran on every section and getElectron() unconditionally deleted and re-downloaded .build/electron each time. On Windows this races with file locks held by the just-exited Electron process and intermittently fails the whole job with the bare 'The system cannot find the path specified.' error. - Set VSCODE_SKIP_PRELAUNCH=1 on the unit/integration/remote test steps of the win32, linux and darwin PR workflows, matching Azure Pipelines (the workflows already prepare node_modules, out, built-in extensions and Electron in dedicated steps before the tests run). - Make getElectron() version-aware: skip the destructive re-download when the installed Electron already matches the expected version, falling back to a download on any detection failure. - Make scripts/code.bat fail fast with a clear message when preLaunch.ts fails instead of falling through to launch a missing executable. - Retry rimraf on EBUSY/EPERM (Windows file-lock codes), not just ENOTEMPTY. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
b83c011c4c |
Merge pull request #323223 from microsoft/connor/agent-host-chat-channels
agentHost: route session state through chat channels |
||
|
|
997c3786fa |
docs(add-policy): warn that policyData must be regenerated in a clean env
A plain 'npm run export-policy-data' loads dev-profile extensions, injecting referencedSettings the fixture-based PolicyExport integration test won't produce — failing CI in a way that is not reproducible locally. Document the isolated regeneration command. |
||
|
|
45448a01ca |
Merge origin/main into agent host chat channels
Resolve upstream conflicts while preserving strict AHP chat-channel routing and the PR feedback fixes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
e4a80816a3 |
Agent host: route session state through chat channels
Move turn state and tool confirmations onto AHP chat channels so peer chats and subagents do not cross-talk. Persist draft/config metadata through side effects, harden malformed chat-channel handling, and keep subscription hydration from hanging on errors. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
9372f5dba6 |
Merge remote-tracking branch 'origin/main' into connor4312/ahp-flattened-session-today
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
4b8cddfa50 |
Agent host: persist chat drafts
Store chat drafts in the per-session database and restore draft text, attachments, model, and agent selection into the chat input. Rebuild restored Copilot turns with best-effort model and attachment metadata while avoiding unresolved subagent names as agent URIs. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
ebe1112161 |
best-practices: discourage getComputedStyle (#323091)
* best-practices: discourage getComputedStyle Add guidance to avoid getComputedStyle and prefer hardcoding style values in TypeScript or setting a CSS variable via setProperty when shared across CSS rules. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * best-practices: clarify setProperty guidance Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
ba2a3ee737 |
ci: pre-initialize fontconfig to fix Pango threaded-FcInit crash in smoke tests (#323015)
Symbolizing the intermittent Electron-startup SIGSEGV crash dumps (Ubuntu debug
symbols + frame-pointer walk) shows the fault is an upstream Pango concurrency
bug, not a VS Code bug:
pango: fc_thread_func -> init_in_thread -> FcInit() (pangofc-fontmap.c)
fontconfig: FcInit -> FcConfigParseAndLoadFromMemory -> _FcConfigParse
libexpat: XML_ParseBuffer -> libc (NULL deref, SIGSEGV)
Pango >= 1.52's pango_fc_font_map_init() unconditionally spawns a
"[pango] fontconfig" thread that runs FcInit(); that races with the
Electron/Chromium main thread's own fontconfig use during startup and corrupts
fontconfig's global config while it is being parsed. The threaded design is a
known-bad area upstream (pango#784 "single fontconfig thread introduces a hang
... seems to be due to a race condition", pango#872), and there is no env var to
disable it (still present in Pango 1.56).
It only manifests in our CI because the race window is microscopic: it needs a
cold process, two threads hitting first-time FcInit() simultaneously, and a slow
machine. Our smoke job is a near-perfect trigger — fresh contended runners, a
wiped fontconfig cache + custom FONTCONFIG_FILE (so FcInit re-parses cold), and
~25 cold Electron starts per run. (This also explains why the expat version was
irrelevant and why dropping the config DOCTYPE made it worse: it is pure timing,
not parser/content.)
Fix: initialize fontconfig once, single-threaded, from an ELF constructor that
runs before main() (and thus before any thread exists), via a tiny LD_PRELOAD
shim. Pango's later threaded FcInit() then finds fontconfig already initialized
and returns immediately, so the concurrent parse never happens and the race is
eliminated.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
||
|
|
84e743a053 |
Revert "ci: drop external DTD from minimal fontconfig to avoid expat NULL-deref crash" (#323009)
Revert "ci: drop external DTD from minimal fontconfig to avoid expat NULL-der…"
This reverts commit
|
||
|
|
c740f81b31 | feat: add MSRC trailer check (#322988) | ||
|
|
1c80314e3b | Engineering - update code owners (#322944) | ||
|
|
70c0a5de8e |
ci: drop external DTD from minimal fontconfig to avoid expat NULL-deref crash (#322909)
The Linux smoke-test job works around the expat 2.6.1 fontconfig NULL-deref
CVEs by pointing FONTCONFIG_FILE at a minimal config with <include> removed.
However that config still declared an external DTD:
<!DOCTYPE fontconfig SYSTEM "urn:fontconfig:fonts.dtd">
fontconfig feeds that DTD to expat as an external *parameter* entity, which
still hits the not-yet-backported CVE-2026-32776 / CVE-2026-32778 crash paths
on expat 2.6.1 even with <include> gone. This was observed in CI as a SIGSEGV
inside libexpat (called from libfontconfig) during Chromium browser-process
font initialization, which crashed Electron at startup. Because the smoke-test
launch used no timeout, that crash surfaced only as an opaque 120s Mocha
"before all" hook timeout.
fontconfig does not require the DOCTYPE, so drop it to remove the last
external-entity codepath. The full workaround can be removed once the runner
ships libexpat >= 2.7.5 (the step already auto-disables itself in that case).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
||
|
|
865f5a0bc1 |
Load managed-settings.json from well-known disk path (#321870)
Add a file-based managed-settings delivery channel that reads managed-settings.json from a well-known per-OS disk path in the main process and exposes it to renderer windows over IPC. Mirrors the existing Copilot managed-settings (server / native MDM) channels. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
fa88bce44d | Document OSS NOTICE cutover (#322827) | ||
|
|
adc7ecf823 |
sessions: responsive auto-collapse of the sessions sidebar (D7) (#322819)
On a narrow Agents window, auto-hide the sessions sidebar while both the editor and the side panel (auxiliary bar) are open, and show it again once either closes or the window grows wide. A manual close suppresses auto-show until the user opens it again; suspended while the editor is maximized or multiple sessions are visible. Gated by the experimental setting `sessions.layout.autoCollapseSessionsSidebar` (default on in non-stable builds). Session navigation never auto-hides the sidebar: a base-controller restore epoch (`_withSessionLayoutRestore` / `_isRestoringSessionLayout`) wraps both the aux-bar restore and the editor working-set apply (`_applyWorkingSet`, which reveals the editor part after an await). The D7 autorun re-baselines instead of reacting while a restore is in flight. The epoch is a depth counter so the guard stays up across overlapping/independently-settling restores, and it decrements synchronously for void work so it never leaks for no-op restores. Layout-controller registration moves to a new `sessions.layout.contribution.ts` that picks the desktop or mobile controller per platform and registers the experimental setting. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
eacf067153 |
Cut over ThirdPartyNotices to the Component Governance generated notice (#322780)
* Cutover ThirdPartyNotices to CG-generated NOTICE Add downloadNotice.ts: pulls the CG-generated NOTICE from the parallel Quality stage notice_output artifact and overwrites repo-root ThirdPartyNotices.txt before gulp packages it, on the desktop-client platform stages (win32, linux, darwin). Clones the copilot VSIX background-download harness (deemon detach/attach) so added wall-clock is near-zero when the artifact is ready in time. Non-fatal with legacy fallback; gated on VSCODE_OVERWRITE_TPN. Alpine/Web (server/REH only) are out of scope. * Fix notice_output race: wait for Quality job completion before accepting artifact The notice_output artifact is populated in two phases (generated.txt+meta, then the shipping ThirdPartyNotices.new.txt seconds later). Build 450466 showed the downloader grabbing the artifact after phase 1 but before .new.txt landed, falling back to legacy. Gate acceptance on the Quality job being completed so both upload phases are done. Bump poll budget to 7.5min. * Bump notice poll budget to 20 attempts (10 min) Observed acceptance at ~attempt 10 (~4.5min) in builds 450470/450477; 20 attempts gives ~2x margin while staying well under copilot's 30min. Clarify in comments that this outer poll is distinct from retry.ts's inner per-API-call retry. * Accept CG NOTICE as soon as .new.txt lands in artifact Change the E-lite acceptance gate from a Quality-job-completed proxy to a direct check that ThirdPartyNotices.new.txt is present inside the notice_output container artifact. Container file uploads are atomic per file, so the file appears in the listing only after its upload finishes -- a race-free, earlier readiness signal. Observed ~80s wasted in build 450470 waiting for the whole Quality job after .new.txt was already available. Backstops kept: (a) if Quality completes and .new.txt is still absent, give up and fall back to legacy (do not burn the full poll budget); (b) post-download >1KB size guard on .new.txt. POLL_ATTEMPTS stays 20 (10 min budget). * Fix cache artifact mismatch: use DownloadBuildArtifacts + guard upload The cache download steps used DownloadPipelineArtifact@2 but the upload uses ##vso[artifact.upload] (which creates build artifacts, not pipeline artifacts). These are different storage systems in ADO -- the download was looking in the wrong store, which is why cache misses on both branch and main. Changes: - Switch cache downloads to DownloadBuildArtifacts@1 (matches the upload) - Update file paths to include notice_output/ subfolder (task behavior) - Guard upload with condition eq(CG_NOTICE_OK, 'true') -- never upload a cached copy, only fresh CG output - Remove NOTICE_FROM_CACHE branching in upload (redundant with guard) - Always write notice-meta.txt sidecar when uploading (step only runs on fresh generation now) * Validate extracted NOTICE content before accepting, re-poll on mid-upload miss The accept-gate decided based on the container LISTING showing ThirdPartyNotices.new.txt, but a listing entry can appear before the file's content has finished committing. The consumer then downloaded+extracted and, when .new.txt was not yet in the extract, terminally fell back to the legacy notice. On a fast-compiling platform (e.g. linux armhf) this raced and shipped MIXED notices across architectures in a single build. Move download+extract+validation into the poll loop: accept only when .new.txt is present AND non-empty (>1KB) in the extracted output. A listing-hit that does not yet yield a valid extracted file is treated as still-uploading and re-polls (consuming an attempt) rather than falling back. Fallback now only triggers on genuine budget exhaustion, or when .new.txt never appears in the listing and the Quality job has completed. Size guard, non-fatal exit 0, and the fresh/fallback/disabled RESULT markers are unchanged. * Add "Use legacy OSS Tool" pipeline parameter to bypass CG notice Surfaces a queue-time checkbox (default off) that, when checked, keeps the legacy mixin ThirdPartyNotices.txt instead of overwriting it with the Component Governance notice. Mirrors the VSCODE_STEP_ON_IT plumbing andderives VSCODE_OVERWRITE_TPN as an explicit lowercase string literal so downloadNotice.ts's case-sensitive check matches. The derived variable is threaded into the detached Pull CG NOTICE step env on win32/linux/darwin. * Use 'definition' input alias for DownloadBuildArtifacts@1 NOTICE cache download * Guard notice unzip against zip-slip and handle write-stream errors Validate each extracted entry path stays within the output directory before writing, and reject on write-stream errors so extraction failures surface instead of hanging the poll. * Rename legacy notice param displayName to 'Use legacy OSS Notice' * Harden CG NOTICE feature flag plumbing Make the VSCODE_OVERWRITE_TPN check case-insensitive and empty-safe so YAML casing can't silently disable the rollback lever, and pass the flag to the Apply (--attach) steps as well as Pull (--detach) so the legacy notice is honored even if the script ever runs from the attach step. |
||
|
|
6a8aa19cac |
sessions: fork into a new chat for multi-chat agent host sessions (#322799)
* sessions: fork into a new chat for multi-chat agent host sessions Forking a conversation in an agent host session that supports multiple chats now creates a new peer chat in the same session instead of a brand new session. Single-chat and non-agent-host sessions keep the existing fork-into-a-new-session behavior. - Add a `fork` option to chat creation and plumb it through the AHP protocol, state manager, agent service and the Copilot agent SDK fork. - Add required `forkChat`/`forkChatInSession` operations (return the new chat or throw; never return undefined). Capability gating happens in the caller before invoking the service. - Fork before the selected request (turnId is the last turn to keep), matching the new-session fork boundary. - Drop the fork when the requested turn is unknown so the provider does not inherit the whole backend conversation while the UI is seeded with no turns. - Generate a content-derived title for forked chats/sessions via the utility model, with a short framing note that the conversation was branched from the source chat. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: use isEqual for chat/session URI comparison Address CCR feedback: compare URIs with the standard `isEqual` helper instead of `toString()` so equality is robust to normalization. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
479a4986c9 | CONTEXT KEYS CLEANUP | ||
|
|
3e7b249a06 |
💄 correct command capitalization in /causedByExtension response (#298925)
Co-authored-by: Dmitriy Vasyura <dmitriv@microsoft.com> |
||
|
|
ea3a084767 |
sessions: support background send for a new chat in an existing session (#322642)
* sessions: support background send for a new chat in an existing session Add background-send (Alt+Enter) support for a new chat created inside an existing multi-chat session, mirroring the new-session composer behavior. - Plumb a `background` flag and `forceNew` option through the new-chat composer, sessions service, and management service so a background send resets the composer before dispatching (avoiding a shared chat-session state race) and runs fire-and-forget without navigating the visible slot. - Keep tab order in the renderer: move in-composer `Untitled` chats to the end so a just-completed background chat never jumps last. - Agent host: present a freshly created peer chat as `Untitled` until its first request is sent (the host commits it eagerly as `Completed`), so the sessions view shows the composer that owns the Alt+Enter handler. Add a committed-chat branch to `sendRequest` and revert the chat to its real status once sent. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: update remote provider not-found assertion Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: partition chat tabs instead of sort for stable status tracking Address CCR feedback: read each chat status exactly once inside the autorun so dependency tracking is complete, and preserve provider order by partition. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
27725b9a63 |
sessions: resolve ${workspaceFolder} in agent-host tasks (#322629)
* sessions: resolve ${workspaceFolder} in agent-host tasks via IConfigurationResolverService
Agent-host worktree sessions build their task command line through
AgentHostSessionTaskRunner/resolveTaskCommand, which bypassed variable
resolution and sent ${workspaceFolder} to the terminal verbatim (causing
EROFS errors writing to a literal "${workspaceFolder}" path).
Expand variables using the workbench IConfigurationResolverService (already
registered in the Agents window), passing the session's worktree folder so
${workspaceFolder} resolves to the worktree rather than the Agents window's
own workspace. The resolver API is async, so the resolveTaskCommand pipeline
is now async; the hook is attached only when a cwd is known so variables are
left untouched otherwise.
Also adds the Agents-window worktree dev tasks (Install & Watch Client,
Run Client, Install & Watch) to .vscode/tasks.json, and tightens the
over-commenting guidance in the coding guidelines and sessions skill.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* sessions: address CCR feedback on agent-host variable resolution
- Resolve ${workspaceFolder} for remote hosts using the POSIX URI path
instead of IConfigurationResolverService.resolveAsync (whose fsPath uses
renderer-OS separators, wrong for a differently-OS'd remote host).
- Wrap the local resolveAsync call in try/catch so an unresolvable variable
(e.g. ${command:}/${input:}) leaves the string unchanged rather than
failing task dispatch.
- Fix the _getCwd comment to reference the real scheme (vscode-agent-host).
- Add a remote-host test asserting POSIX-path expansion and that the
renderer resolver is not consulted.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* sessions: make agent-host task runner test platform-independent
The expansion test asserted against the resolver substituting URI.fsPath,
which on Windows yields backslash separators. Backslash is in
POSIX_NEEDS_QUOTING, so the expanded arg was strong-quoted on Windows and
the unquoted assertion failed. Substitute the POSIX URI path instead so the
test is deterministic across platforms.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
||
|
|
a4ce08f735 |
Refactor Copilot managed-settings for maintainability (#322439)
* Refactor Copilot managed-settings for maintainability
Centralize structured (object/array) managed-setting handling behind a
single descriptor table so adding a key touches one place, consolidate the
duplicated equality helpers onto `equals`, and add shared
`hasManagedSettingsDefinitions` and `managedSettingValue` helpers. Strictly
behavior-preserving.
Incorporates a 3-model maintainability review:
- `adaptManagedSettings` builds the scalar remainder via `{ ...response }`
plus delete (CopyDataProperties) instead of for..in + assignment, so a
server-sent own `__proto__` key cannot trigger the inherited setter. This
matches the original `...rest` semantics; adds a regression test.
- `managedSettingValue` is memoized per key so its policy-definition
reference identity is real rather than incidental to the call site.
- Corrected JSDoc and skill docs that overstated `responseField` as
compiler-checked; it is a hand-maintained union backstopped by tests.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Clarify why structured managed-settings keys must declare type: 'string'
The bag-carrying `type` is load-bearing, not cosmetic: `projectManagedSettings`
gates each value with `typeof value === type` and drops mismatches, and the
native MDM watcher reads the registry/plist value as that type. Spell out that
omitting it (or declaring the object/array type) makes a structured key fail
projection and silently never apply.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address PR review: allocation-free empty check, __proto__ test, doc accuracy
- hasManagedSettingsDefinitions: reuse the allocation-free isEmptyObject
helper instead of Object.keys(...).length (the bot's only valid nit).
- Add a primitive `__proto__` regression test proving a server-sent
`{"__proto__": true}` scalar is dropped, never pollutes the result
(disproves the reviewer's prototype-pollution concern).
- Fix github-managed-settings.md: omitting `type` or declaring
`'object'`/`'array'` is a compile error (the field is required and
constrained to `'string' | 'number' | 'boolean'`), not a runtime drop;
only `'number'`/`'boolean'` compile-but-drop-at-runtime.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Surface managed-settings source in Policy Diagnostics
Centralize the server-over-MDM precedence into a shared selectManagedSettings
helper (plus a ManagedSettingsSource union) and reuse it in both
AccountPolicyService and the Policy Diagnostics report, so the report can never
drift from the source that policy evaluation actually applies.
Rewrite the diagnostics "Managed Settings" section to:
- show the Active source (GitHub Server API / Native MDM / None)
- break down each channel (server fetch status + raw response, native MDM bag)
- label the raw response as the last *successful* fetch, so a later failed
fetch (e.g. a 404) no longer looks like it contradicts an empty effective bag
- compute the true effective bag via the shared projectManagedSettings
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix mock policy server "Generate example" not persisting
The "Generate example" button filled the editor and the localStorage draft but
never called debouncedSave(), so the generated body was never POSTed to
/api/state and the endpoint kept serving the empty preset. Add the missing
debouncedSave() to match applyPreset() and the editor input handler.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Strip prose from Policy Diagnostics and collect managed-settings parse errors
The Developer: Policy Diagnostics "Managed Settings" section now renders
data only (tables and JSON blocks, no explanatory paragraphs).
It also collects non-fatal parsing/normalization warnings from every stage
of the managed-settings pipeline, jsonc-style (accumulate, never throw), and
surfaces them in a new "Parse Errors" section:
- adapt: re-runs adaptManagedSettings on the raw server response
- project: re-runs projectManagedSettings against the declared policy keys
- parse: re-parses JSON-payload string values with the jsonc parser
This explains why a key is silently dropped. For example a server
extraKnownMarketplaces entry with source "github" but no "repo" now shows
the "requires \"repo\"" warning instead of just vanishing from the bag.
Adds a focused test for that github-without-repo normalization case.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Tighten Policy Diagnostics managed-settings rendering (review follow-up)
Code-quality pass on the managed-settings diagnostics section:
- Extract a jsonBlock() helper for the repeated fenced-JSON rendering
(4 call sites collapsed).
- Parse only the known JSON-payload keys (enabledPlugins,
strictKnownMarketplaces, extraKnownMarketplaces) instead of a
leading-brace heuristic. This mirrors what PolicyConfiguration actually
parses, avoids mis-sniffing scalar values, and catches malformed payloads
that don't start with a brace.
- Unify the raw-response guard on isObject() so the printed raw response and
the adapt-stage warning harvest use one predicate.
- Drop the defensive object copy in projectManagedSettings(); it is read-only,
so normalize undefined with `?? {}` instead of spreading.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Fix native MDM availability in Policy Diagnostics; tidy table headers
The diagnostics report showed "Native MDM | Available | no (desktop only)"
even on desktop. ICopilotManagedSettingsService was registered only in the
electron-main process and hand-plumbed into AccountPolicyService, but never
placed in the renderer service collection, so the report's
accessor.get(ICopilotManagedSettingsService) always threw and mislabeled the
channel as unavailable.
Register the CopilotManagedSettingsChannelClient (the renderer's handle to the
main-process service) in the service collection in both desktop.main.ts and
sessions.main.ts. The diagnostics now resolves it on desktop and Agents windows
and reports real native MDM availability and values; web still has no native
channel and correctly reports unavailable.
Also tidy the report builder: extract a PROPERTY_VALUE_TABLE_HEADER constant for
the five repeated two-column table headers, and drop the now-misleading
"(desktop only)" annotation on the availability row.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
---------
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
||
|
|
fd396ed9a2 | OSS: Generate ThirdPartyNotices via Component Governance + Helper Scripts (#322410) | ||
|
|
7a9cd87b8b | voice mode: enable transcript scrolling in chat input and aux window (#322390) | ||
|
|
a4f90ca16a | Fetch oidc token just before uploading | ||
|
|
98bf19c30c |
agent host: fix custom agent selection and per-chat agent/model changes (#322300)
* agent host: fix custom agent selection and per-chat agent/model changes Two fixes for Copilot CLI agent-host sessions: - The selected custom agent (e.g. a plugin/extension agent like "Inbox") failed with "Custom agent '<name>' not found". The SDK validates the session-start `agent:` option against `customAgents` by name and does not consult `pluginDirectories`, but file-dir plugin agents were excluded from `customAgents`. The new `toSdkSessionCustomAgents` helper force-includes the resolved selected agent while other file-dir agents still load via `pluginDirectories`. - An additional (peer) chat in a session did not respect agent/model changes. `SessionAgentChanged`/`SessionModelChanged` were dispatched to the session URI (the default chat) instead of the per-chat turn channel, and the `chatChannel` was dropped before reaching `changeAgent`/`changeModel`. These now route to the peer chat's backend conversation in `_chatSessions`. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * sessions: address Copilot code review feedback - Trim SDK custom-agent names to match parseAgentFile so a whitespace-padded frontmatter name still matches the resolved selected agent (CCR finding 3). - Dedup peer-chat agent/model side-channel dispatch against the last value sent for that chat (tracked on AgentHostChatSession) instead of the session summary, which only exists for the default chat (CCR findings 1 & 2). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
044134364a |
ci: split Electron PR test jobs into unit/integration and smoke (#322145)
* ci: split Electron test jobs into unit/integration and smoke The Linux, Windows and macOS Electron PR test jobs are the slowest in CI, dominated by the smoke test run. Split each into two parallel jobs - one running unit + integration tests, the other running smoke tests - to cut wall-clock time. Done via two new parameters on the reusable workflows (unit_and_integration_tests and smoke_tests, both defaulting to true) so Browser and Remote jobs are unchanged. Artifact names get a -smoke suffix on the smoke-only job to avoid upload collisions. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci: gate build and diagnostics to correct Electron test phase Follow-up to the Electron job split. Ensure each half only does the work it needs: - Gate "Build integration tests" on unit_and_integration_tests so the smoke-only job skips it. - Scope the before/after diagnostics steps to their phase (combined with always()) so they don't run in the wrong job. - Move the Copilot extension build into the smoke phase (gated on smoke_tests) instead of compiling it unconditionally; align Linux, Windows and macOS on the same ordering. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci: drop space and parens from Electron-Smoke job name The Windows 1ES runner builds its JobId label from job_name, producing "windows-test-Electron (Smoke)-...". The space and parentheses prevented the runner from picking up the job. Rename the smoke job to Electron-Smoke on all three platforms so the JobId is a plain slug. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fixes --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
3980424ce8 |
Refactor restore-node-modules action for lookup-only functionality (#322140)
refactor: update restore-node-modules action to support lookup-only functionality - Replaced 'extract' input with 'lookup-only' to allow cache entry checks without downloading or extracting. - Updated action logic to conditionally extract node_modules based on the new 'lookup-only' input. - Adjusted workflow files to utilize 'lookup-only' for cache-warming jobs on Linux, macOS, and Windows. |
||
|
|
37e7e85b10 |
Optimize node_modules caching for CI & PR checks (#322074)
* CI: speed up node_modules cache with zstd + shared scripts
Switch the Linux/macOS node_modules cache from single-threaded gzip
(tar -czf) to multi-threaded zstd. The "Create node_modules archive"
step was spending ~5min of single-core gzip on a multi-GB tree on every
cache miss; zstd -T0 uses all cores and decompresses much faster, so
cache-hit jobs benefit too. Windows stays on 7-Zip (already threaded).
Extract the archive/extract commands into shared per-platform scripts
under .github/workflows/node_modules_cache/ (cache.sh / cache.ps1, each
dispatching on an archive|extract argument) so the format and flags live
in one place instead of being duplicated across ~8 workflows. Bump
build/.cachesalt to invalidate existing gzip caches.
Also remove the obsolete extensions/copilot CI workflows
(copilot-setup-steps.yml, ensure-node-modules-cache.yml, pr.yml) and the
unused build/listBuildCacheFiles.js, and drop their now-stale entries
(plus lit-html and signals-core) from .eslint-allowed-javascript-files.
* ci: seed copilot node_modules cache on main and rename cache keys
Add copilot-linux and copilot-windows jobs to pr-node-modules.yml so the
copilot node_modules cache is populated on main. Rename the copilot cache
keys to copilot-node_modules-linux / copilot-node_modules-windows in pr.yml.
* ci: extract node_modules cache into composite actions
Factor the repeated node_modules cache plumbing into two local composite
actions, restore-node-modules and save-node-modules, and migrate all
workflows that used the cache.sh/cache.ps1 archive flow (pr, pr-node-modules,
pr-{linux,darwin,win32}-test, copilot-setup-steps, component-fixtures,
css-order-scan).
- restore-node-modules computes the key, restores the cache, optionally
extracts on a hit, and exports the resolved key via $GITHUB_ENV.
- save-node-modules archives node_modules and saves it to the cache, reusing
the key exported by restore so callers don't repeat the prefix.
- Bespoke install steps stay in the workflows, so per-job env/secrets never
cross the action boundary.
- Only seed the cache on branch pushes (component-fixtures skips PRs, whose
caches aren't shared).
* save the node_modules cache for now to test it
* ci: fix node_modules cache save dropping the archive
cache.sh wrote its archive as cache.tzst, but actions/cache reserves that
name for its own tarball and passes --exclude cache.tzst, so our archive was
excluded and an empty (~200 B) cache was saved on Linux/macOS. Rename the
archive to node-modules.tzst and bump build/.cachesalt to invalidate the
broken cache entries.
* empty commit
* Remove again saving to the node modules cache from PR steps
|
||
|
|
593c7f2366 |
policy: dev mock server for copilot_internal policy endpoints (#321871)
* policy: add dev mock server for copilot_internal policy endpoints Adds scripts/mock-policy-server, a standalone dev tool (npm run mock-policy-server) that mocks the Copilot policy endpoints DefaultAccountService calls: entitlements (/copilot_internal/user), token (/copilot_internal/v2/token), MCP registry (/copilot/mcp_registry) and managed settings (/copilot_internal/managed_settings). A small web GUI lets devs pick presets or edit each JSON response, and Wire/Unwire buttons point product.overrides.json at the local server (preserving the rest of defaultChatAgent, since bootstrap-meta merges overrides shallowly). The managed-settings JSON schema is loaded from --schema/MANAGED_SETTINGS_SCHEMA, defaulting to ./copilot-agent-runtime/schema/managed-settings-schema.json relative to the app cwd; web URLs and file URIs are accepted, and the GUI warns about keys not declared in the schema. The three browser/shared .js files are added to .eslint-allowed-javascript-files since the GUI loads them directly. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: address mock-policy-server review feedback - Scope permissive CORS to the mocked GET endpoints only; keep /api/* same-origin so a website can't drive /api/wire and rewrite product.overrides.json (CSRF). - Coerce an empty editor body to {} instead of "" so mocked responses stay JSON objects. - Build the endpoint meta line with textContent/DOM nodes instead of innerHTML. - Drop the misused tablist/tab ARIA roles; the nav now has an aria-label and the active item uses aria-current. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: document mock policy server in add-policy skill Add local-testing.md to the add-policy skill with basic steps for using the mock policy server (scripts/mock-policy-server) to exercise the account/managed-settings flow locally, and link it from SKILL.md and github-managed-settings.md. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: polish mock server GUI — schema validation, wiring backup, localStorage persistence * policy: auto-save, rename wiring to product.overrides.json, copy path button * mock-policy-server: convert server.js to TypeScript; add raw response diagnostics - Convert server.js → server.ts (runs via --experimental-strip-types) - Add endpoints.d.ts type declarations for the UMD endpoints module - Add managedSettingsRawResponse to IDefaultAccountProvider/IDefaultAccountService - Show raw response in Developer: Sync Account Policy output - Remove server.js from eslint allowed-javascript-files * mock-policy-server: convert all JS to TypeScript - endpoints.js → endpoints.ts with proper interfaces (replaces .d.ts) - public/app.js → public/app.ts with full type annotations - Server uses module.stripTypeScriptTypes() to serve .ts as plain JS to the browser — no build step needed - Remove all mock-policy-server entries from .eslint-allowed-javascript-files --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
49484d1c91 |
policy: server-delivered managed settings win over native MDM (#321970)
* policy: server-delivered managed settings win over native MDM Managed settings can arrive from two channels: the server `managed_settings` endpoint and native MDM (Windows registry / macOS plist). Previously the two were merged with native MDM winning. This changes the precedence so the two layers are never merged: at any point in time there is a single authoritative source. The server is harder to bypass than local MDM/file policies, so when the server delivers managed settings it wins outright and native MDM is ignored entirely. Native MDM applies only when the server provides no managed settings. Client-side merging still happens within the winning layer (e.g. enabledPlugins, extraKnownMarketplaces). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: move managed-settings precedence rationale into add-policy skill Trim the verbose inline comment in AccountPolicyService.getPolicyData() down to a one-line pointer; the full precedence rationale lives in the managed-settings section of the add-policy skill doc. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: drop code snippet from managed-settings precedence doc Keep the precedence explanation as prose; the code lives in AccountPolicyService.getPolicyData(). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * policy: add skill learning — prefer behavior/contract prose over copy-pasted code Skills should document behavior and business-logic expectations and reserve code blocks for the author-facing API contract, rather than reproducing internal implementation that rots when the source changes. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
ee44398a29 |
agent 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> |
||
|
|
35054242b4 |
Document GitHub Copilot managed settings in add-policy skill (#321808)
* Document GitHub Copilot managed settings in add-policy skill Add a github-managed-settings.md sub-file covering the new enterprise managed-settings modality (native MDM / file / GitHub server -> the canonical IPolicyData.managedSettings bag) and the policyReference mechanism (one policy governing many settings). Update SKILL.md to link the sub-file and refresh the policy-sources and key-files tables. Grounded in PRs #318623, #320991, #321218, #321515. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Tighten managed-settings skill after council fact-check Cross-checked every claim against the source and the four PRs: - Correct the channel count: VS Code feeds the bag from native MDM + server endpoint only; managed-settings.json is external-schema-only and not read by VS Code. - Fix "JSON.parse" -> PolicyConfiguration.parse() (lenient JSONC visitor). - Quote ManagedSettingValue verbatim (= PolicyValue). - Clarify native MDM is a separate input merged in getPolicyData, not on policyData; document MDM-wins merge order precisely. - Note schema is nested vs the flattened bag key; add the extraKnownMarketplaces github/git-only divergence alongside the strict boolean one. - Soften the catalog claim: referencedSettings only captures references loaded at export time (sessions Claude ref absent from policyData.jsonc). - Fix example file path (chat.shared.contribution.ts) and restore the chat_preview_features_enabled OR in the ChatToolsAutoApprove sample. - Make the main.ts wiring snippet match the real two-step structure. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Address PR review: annotate example minimumVersion values Mark the concrete minimumVersion values in example blocks as historical values transcribed from existing policies, with an inline note that new policies derive minimumVersion from package.json major.minor (Step 1). The file-based-channel and JSON.parse review comments were already resolved in the prior council-fix commit. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Clarify policy multiplexing in add-policy skill After another pass through the policy wiring, clarify that MultiplexPolicyService is used in two places: main-process OS/file policy reader multiplexing, and renderer/session multiplexing of the main policy channel with AccountPolicyService. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Promote policyReference guidance to main add-policy skill policyReference is a general policy mechanism, not specific to Copilot managed settings. Make the main SKILL.md section self-contained with the owner/reference model, validation rules, export behavior, IPC-safe serialization, and diagnostics notes. Keep the managed-settings sub-file as a cross-reference only for managed-settings-specific examples. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> |
||
|
|
7533927257 | improved cssOrderScan |