Repository navigation
Fix customization marketplace sign-in - #341648
Conversation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
🟡 Changes recommended
Enterprise resource handling and fallback credential revocation on sign-out need correction.
2 open findings
What changed in this PR
Adds fallback Copilot authentication for customization marketplace recovery when the host advertises no protected resources.
Changes:
- Selects an authentication resource for marketplace sign-in.
- Adds regression coverage through the registered marketplace provider.
| File | Description |
|---|---|
| src/vs/workbench/contrib/chat/test/browser/agentSessions/agentHostChatContribution.test.ts | Tests recovery with empty protected resources. |
| src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatContribution.ts | Adds fallback authentication resource selection. |
🧠 Review effort: Balanced
💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
Closing this draft after reproducing the exact workspace flow: the proposed protected-resource fallback does not fix the issue. A direct SDK differential across @github/copilot-sdk 1.0.18-preview.4/runtime 1.0.94-4 through 1.0.22-preview.2/runtime 1.0.98-2 produced the same result under VS Code’s hidden policy-session options: session.gitHubAuth.getStatus reports authenticated=true, but bound catalog.search returns authentication-required/no-credential. Omitting enableManagedSettings/managedSettings changes the result away from authentication-required. This is therefore not a new SDK version regression; it is a latent incompatibility between the hidden managed-settings policy session and bound catalog credential lookup. If the flow worked previously, it was likely using a live materialized chat session instead of the hidden fallback session. The exact UI click also starts GitHub Authentication’s device-code flow when no account exists, so the apparent no-op has a second UX issue: that pending sign-in is not surfaced clearly over the customization modal. |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
UI validation on macOS arm64 with Code OSS Dev 1.143.0: opened Agent Customizations for the Copilot harness in customizations-marketplace-sign-in-fix.mp4 |
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Deep-review follow-up:
|
…ession While a Copilot chat was open, the customization marketplace failed to load installation receipts and the renderer logged, many times per second: Unable to load session-bound SDK installation receipts The SDK could not list installed MCP servers. (refused: policy-context-unavailable) Root cause: CopilotCustomizationInstallations preferred the visible chat's SDK session as `policySessionId` for list, recover, search, and install/uninstall planning, and used the hidden policy session only when no chat was open. The Copilot runtime admits installation and inventory requests only when the policy session's GitHub credential is verified (a github.com login backed by a resolved Copilot user record; see mcp_installation `authority()` -> `installation_account_fingerprint()`). A credential supplied at createSession (`gitHubToken`/`gitHubTokenProvider`) is never verified. Only `session.rpc.gitHubAuth.setCredentials` verifies it. #341648 added that call to the hidden policy session, but chat sessions get it only when the token changes while they are live. Chats created after the last token change, and provider-backed chats, were never verified, so every request bound to them was refused. Fix: always use the hidden, credential-verified policy session (`getOrCreatePolicySessionId`) for catalog search, inventory, recovery, and install/uninstall planning. None of these operations needs the chat's identity: - Installation receipts are scoped by the runtime's Copilot home plus the account and host fingerprints, not by session or working directory. - The hidden session enables the same catalog-installation feature flags and managed settings as chat sessions. - The client-level `installationConfirmationHandler` matches on the `policySessionId` that planned the operation. Plan and apply now always use the same hidden session, so confirmation matching is unchanged. - Catalog cursors and selections stay keyed by `policySessionId`. They are now invalidated when the hidden session is replaced (auth change, client restart, idle disposal) rather than when switching between chats. Replacement goes through the existing re-search recovery path. The visible-session getter and the no-factory path ("Start a Copilot agent session before managing SDK installations." / `unavailable: session`) are removed. The only production construction (CopilotAgent) always provides the hidden-session factory, so that path was reachable only from tests. The factory is now required. `releasePolicySession` behavior and the 10-minute idle disposal are unchanged. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ession (#342613) <!-- Thank you for submitting a Pull Request. Please: * Read our Pull Request guidelines: https://github.com/microsoft/vscode/wiki/How-to-Contribute#pull-requests * Associate an issue with the Pull Request. * Ensure that the code is up-to-date with the `main` branch. * Include a description of the proposed changes and how to test them. --> ## Problem While a Copilot chat is open, the customization marketplace can't load installation receipts. The renderer logs this many times per second: ``` [AgentHostCustomizationMarketplace] Unable to load session-bound SDK installation receipts The SDK could not list installed MCP servers. (refused: policy-context-unavailable) ``` ## Root cause `CopilotCustomizationInstallations` used the open chat's SDK session as `policySessionId` for `list`, `recover`, `search`, and install/uninstall planning. It used the hidden policy session only when no chat was open. The Copilot runtime admits installation and inventory requests only when the policy session's GitHub credential is **verified**: a github.com login backed by a resolved Copilot user record (`mcp_installation` `authority()` → `installation_account_fingerprint()`). A credential passed at `createSession` (`gitHubToken` / `gitHubTokenProvider`) is never verified. Only `session.rpc.gitHubAuth.setCredentials` verifies it. A standalone SDK repro against runtimes 1.0.92-0 through 1.0.100-1 showed `refused: policy-context-unavailable` with the createSession token, even after a chat turn, and `listed` right after `setCredentials` on the same session. #341648 added `setCredentials` to the hidden policy session. Chat sessions get it only when the token changes while they're live. Chats created after the last token change, and provider-backed chats, are never verified. ## Fix Search, inventory, recovery, and install/uninstall planning now always use the hidden policy session (`getOrCreatePolicySessionId`). None of these operations needs the chat's identity: - **Receipts:** the runtime scopes them by Copilot home plus account and host fingerprints, not by session or working directory, so results are the same. - **Feature flags and managed settings:** the hidden session has the same catalog-installation feature flags and managed settings as chat sessions. - **Confirmation:** the client-level `installationConfirmationHandler` matches on the `policySessionId` that planned the operation. Plan and apply now always use the same hidden session, so matching is unchanged. - **Cursors and selections:** they stay keyed by `policySessionId`. They're now invalidated when the hidden session is replaced (auth change, client restart, idle disposal) rather than when you switch chats. The existing re-search recovery path handles that. The visible-session getter and the no-factory path are removed. That path produced "Start a Copilot agent session before managing SDK installations." and `unavailable: session`. The only production caller (`CopilotAgent`) always provides the hidden-session factory, so only tests could reach it. The factory is now required. `releasePolicySession` and the 10-minute idle disposal are unchanged. `AI_CUSTOMIZATIONS.md` is updated. ## Tests - `copilotCustomizationInstallations.test.ts`: tests that relied on a fixed chat session ID now use a `TestPolicySessions` helper that records created sessions. A new test checks that search, list, recover, and prepare all bind to one hidden session. - `copilotAgent.test.ts`: a new test opens a live chat and checks that `listCustomizationInstallations` goes to the hidden session, which received `setCredentials`, and not to the chat's session. ## Validation - `npm run typecheck-client`: passed - `npm run eslint -- <changed files>`: passed - `./scripts/test.sh --run src/vs/platform/agentHost/test/node/copilotCustomizationInstallations.test.ts --run src/vs/platform/agentHost/test/node/copilotSessionLauncher.test.ts --run src/vs/platform/agentHost/test/node/copilotAgent.test.ts`: 1012 passing, 1 pending, 1 failing. The failure is `isolates peer runtimes, preserves local adoption identity and refuses revoked prepared work`, which also fails on unmodified `main` (`e1a22a1ad40`).
…ified policy session (#342629) Cherry-pick of #342613 from `main`. <!-- Thank you for submitting a Pull Request. Please: * Read our Pull Request guidelines: https://github.com/microsoft/vscode/wiki/How-to-Contribute#pull-requests * Associate an issue with the Pull Request. * Ensure that the code is up-to-date with the `main` branch. * Include a description of the proposed changes and how to test them. --> ## Problem While a Copilot chat is open, the customization marketplace can't load installation receipts. The renderer logs this many times per second: ``` [AgentHostCustomizationMarketplace] Unable to load session-bound SDK installation receipts The SDK could not list installed MCP servers. (refused: policy-context-unavailable) ``` ## Root cause `CopilotCustomizationInstallations` used the open chat's SDK session as `policySessionId` for `list`, `recover`, `search`, and install/uninstall planning. It used the hidden policy session only when no chat was open. The Copilot runtime admits installation and inventory requests only when the policy session's GitHub credential is **verified**: a github.com login backed by a resolved Copilot user record (`mcp_installation` `authority()` → `installation_account_fingerprint()`). A credential passed at `createSession` (`gitHubToken` / `gitHubTokenProvider`) is never verified. Only `session.rpc.gitHubAuth.setCredentials` verifies it. A standalone SDK repro against runtimes 1.0.92-0 through 1.0.100-1 showed `refused: policy-context-unavailable` with the createSession token, even after a chat turn, and `listed` right after `setCredentials` on the same session. #341648 added `setCredentials` to the hidden policy session. Chat sessions get it only when the token changes while they're live. Chats created after the last token change, and provider-backed chats, are never verified. ## Fix Search, inventory, recovery, and install/uninstall planning now always use the hidden policy session (`getOrCreatePolicySessionId`). None of these operations needs the chat's identity: - **Receipts:** the runtime scopes them by Copilot home plus account and host fingerprints, not by session or working directory, so results are the same. - **Feature flags and managed settings:** the hidden session has the same catalog-installation feature flags and managed settings as chat sessions. - **Confirmation:** the client-level `installationConfirmationHandler` matches on the `policySessionId` that planned the operation. Plan and apply now always use the same hidden session, so matching is unchanged. - **Cursors and selections:** they stay keyed by `policySessionId`. They're now invalidated when the hidden session is replaced (auth change, client restart, idle disposal) rather than when you switch chats. The existing re-search recovery path handles that. The visible-session getter and the no-factory path are removed. That path produced "Start a Copilot agent session before managing SDK installations." and `unavailable: session`. The only production caller (`CopilotAgent`) always provides the hidden-session factory, so only tests could reach it. The factory is now required. `releasePolicySession` and the 10-minute idle disposal are unchanged. `AI_CUSTOMIZATIONS.md` is updated. ## Tests - `copilotCustomizationInstallations.test.ts`: tests that relied on a fixed chat session ID now use a `TestPolicySessions` helper that records created sessions. A new test checks that search, list, recover, and prepare all bind to one hidden session. - `copilotAgent.test.ts`: a new test opens a live chat and checks that `listCustomizationInstallations` goes to the hidden session, which received `setCredentials`, and not to the chat's session. ## Validation - `npm run typecheck-client`: passed - `npm run eslint -- <changed files>`: passed - `./scripts/test.sh --run src/vs/platform/agentHost/test/node/copilotCustomizationInstallations.test.ts --run src/vs/platform/agentHost/test/node/copilotSessionLauncher.test.ts --run src/vs/platform/agentHost/test/node/copilotAgent.test.ts`: 1012 passing, 1 pending, 1 failing. The failure is `isolates peer runtimes, preserves local adoption identity and refuses revoked prepared work`, which also fails on unmodified `main` (`e1a22a1ad40`).



Summary
session.gitHubAuth.setCredentialsAPIruntimeOverrideis usedThe hidden session could report authenticated metadata while the SDK catalog auth manager still had no selected session credential. Catalog search therefore returned
authentication-required / no-credential, and the recovery button appeared inert. Installing the session-owned credential after session creation selects it for SDK catalog operations.Validation
npm run build-fast -- --client-only— passed./scripts/test.sh --run src/vs/platform/agentHost/test/node/copilotSessionLauncher.test.ts— passed (134 tests)npm run typecheck-client— passednpm run eslint -- src/vs/platform/agentHost/node/copilot/copilotAgent.ts src/vs/platform/agentHost/node/copilot/copilotSessionLauncher.ts src/vs/platform/agentHost/test/node/copilotSessionLauncher.test.ts— passedgit diff --check— passed/Users/paulwang/Desktop/shared/code/vscode-sdk-skill-installusing the normal signed-in profile, checked-in SDK/runtime, no injected token, no synthetic response, and no runtime override. Searchingfigmareturned sixSkill · GitHub Feedresults with no Sign In prompt.How to Test
figma.