sessions: add a context key gating the classic-window actions - #336910
Roi Dayan (roidayan1) wants to merge 4 commits into
Conversation
The Agents window can be the only window a product ships, but four actions reach for a classic VS Code window with no way to gate them: - `OpenVSCodeWindowAction` is `f1: true` and bound to Cmd/Ctrl+Shift+A with no precondition and no when clause at all - `ReturnToVSCodeEditorAction` has no precondition - `OpenInVSCodeAction` and `OpenSessionInVSCodeAction` gate only on `IsAuxiliaryWindowContext` and `SessionsWelcomeVisibleContext` Adds `SessionsClassicWindowAvailableContext`, defaulting to `true` so VS Code's own behaviour is unchanged, and includes it in all four. A product that cannot open a classic window sets it to `false` once and the actions stop offering themselves, instead of each embedder finding its own way to suppress a command it cannot fulfil. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
@microsoft-github-policy-service agree |
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The key is never initialized, disabling actions by default, while the sign-in dialog bypasses its precondition.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 1
Open (2)
What changed in this PR
Adds an opt-out context key for actions that open classic VS Code windows from the Agents window.
Changes:
- Adds
sessionsClassicWindowAvailable. - Applies it to four actions and two title-bar menu entries.
| File | Description |
|---|---|
src/vs/sessions/common/contextkeys.ts |
Defines the availability context key. |
src/vs/sessions/browser/actions/vscodeActions.ts |
Gates web “Open in Editor” UI. |
src/vs/sessions/electron-browser/actions/vscodeActions.ts |
Gates desktop window actions. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Two fixes from review. A `RawContextKey`'s default is written only by `bindTo()`, and nothing binds this key -- so it reads as `undefined` and every positive check evaluated false, disabling the actions by default rather than leaving them alone. Consumers now test `notEqualsTo(false)`, so unset and `true` both mean available and stock VS Code is genuinely unchanged. `ReturnToVSCodeEditorAction` has no `f1` and no menu, so a precondition on it gates nothing: the sign-in dialog renders its footer button from `agents.shouldShowReturnToVSCodeEditor` and then executes the command directly, and `Action2` handlers do not enforce preconditions. The decorative precondition is removed and the availability check moves into the decision command, which is what the button is rendered from. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The Boolean expression canonicalization disables the gated actions when the new key is unset.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 2
Open (3)
Resolved since last review (1)
`notEqualsTo(false)` did not fix the previous round: `ContextKeyNotEqualsExpr.create` canonicalizes a boolean `false` comparison straight back to `ContextKeyDefinedExpr` (contextkey.ts:1046-1052), so the expression was identical to the one it replaced and an unbound key still evaluated false. Inverted instead. `sessionsClassicWindowUnavailable` defaults to `false` and every consumer negates it, so `ContextKeyNotExpr` evaluates `!undefined` -- unset means available, no binding and no ordering between a binder and a product that opts out. Adds a regression test over unset, `true` and `false`, against the real preconditions of `OpenVSCodeWindowAction` and `OpenSessionInVSCodeAction` -- bare and inside a conjunction, since `and()` canonicalizes too. Also condenses the guard comment in `ShouldShowReturnToVSCodeEditorAction`. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The sign-in-dialog gating branch needs focused regression coverage, and added comments exceed repository limits.
Get a fresh assessment by requesting another Copilot review.
Review effort: Balanced
Findings: 2
Open (5)
Resolved since last review (1)
|
|
||
| override async run(accessor: ServicesAccessor): Promise<boolean> { | ||
| // The sign-in dialog invokes the command directly, which no precondition can gate. | ||
| if (SessionsClassicWindowUnavailableContext.getValue(accessor.get(IContextKeyService)) === true) { |
There was a problem hiding this comment.
Good catch, and it is the sharpest of the three: the test would have passed with that guard deleted. Covered in e67dc0f over unset, false and true, against ShouldShowReturnToVSCodeEditorAction.run() itself rather than a reconstruction — and the true case asserts queriedWindows === false, so the short-circuit before INativeHostService is pinned as you asked rather than implied by the return value.
The regression test only evaluated action preconditions, so removing the guard in `ShouldShowReturnToVSCodeEditorAction.run()` would still have passed while the Return button stayed visible in an opted-out product. It is now covered over unset, `false` and `true`, including that opting out short-circuits before the native host is asked for windows. Trims the context key's JSDoc to the opt-out invariant -- the canonicalization history it carried is what the test protects -- and the two-line narration in the test to one line. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>



The Agents window is usable as the only window a product ships, but four actions reach for a classic VS Code window and there is currently no supported way to gate them:
OpenVSCodeWindowActionf1: true, bound to Cmd/Ctrl+Shift+A, nopreconditionand nowhenclause at allReturnToVSCodeEditorActionprecondition, and invoked directly by the sign-in dialogOpenInVSCodeActionIsAuxiliaryWindowContext/SessionsWelcomeVisibleContextonlyOpenSessionInVSCodeActionThe first is the awkward one: it is in the command palette and on a keybinding, with nothing to hang a condition on.
What this does
Adds
SessionsClassicWindowUnavailableContext(sessionsClassicWindowUnavailable) insessions/common/contextkeys.tsand negates it at every use.It is stated as an opt-out on purpose. Nothing binds the key, and a
RawContextKey's default is written only bybindTo()— so an expression that is false when the key is unset would hide these actions in stock VS Code. Negating a default-falsekey gives the intended behaviour with no binder to run and no ordering between that binder and a product that opts out: unset means available, and a product that cannot open a classic window sets it totrue.It is applied in two places:
preconditionofOpenVSCodeWindowAction,OpenInVSCodeActionandOpenSessionInVSCodeAction, and thewhenof the two title-bar menu items;ShouldShowReturnToVSCodeEditorAction.run(), because the sign-in dialog renders its footer button from that answer and then executesRETURN_TO_VSCODE_EDITOR_COMMAND_IDdirectly —Action2handlers do not enforce preconditions, so a precondition there would gate nothing.ReturnToVSCodeEditorActionhas nof1and no menu, so it carries no precondition: the real gate is the decision command above.Test
vscodeActions.test.tscovers unset,trueandfalseagainst the realdesc.preconditionofOpenVSCodeWindowActionandOpenSessionInVSCodeAction— bare and inside a conjunction, sinceContextKeyExprcanonicalizes.Notes
//#region, since it describes neither the welcome overlay nor the editor area.🤖 Generated with Claude Code