Skip to content

Polish Claude agent's permission label, descriptions, icons#321673

Open
anthonykim1 wants to merge 7 commits into
mainfrom
anthonykim1/ehAhClaudeNotDistinguishablePicker
Open

Polish Claude agent's permission label, descriptions, icons#321673
anthonykim1 wants to merge 7 commits into
mainfrom
anthonykim1/ehAhClaudeNotDistinguishablePicker

Conversation

@anthonykim1

@anthonykim1 anthonykim1 commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

Resolves: #321675 and issue regarding reducing + polishing claude agent's permission.

  • Align Claude Agent Host permissionMode labels with Claude Code's VS Code-facing names: Ask Before Edits, Edit Automatically, Plan Mode, Auto Mode, and Bypass Permissions.
  • Remove dontAsk from the visible picker list while keeping SDK/session compatibility for existing or externally-created dontAsk values.
  • Add distinct Claude permission-mode icons in both Agent Sessions and workbench chat: shield, edit, lightbulb, sparkle, and warning.
  • Register the dedicated Claude permission-mode picker for new-session UI, and skip the generic enum chip for well-known Claude permissionMode schemas to avoid duplicate or generic rendering.
  • Extend focused tests for hidden Don't Ask, exact labels, distinct icons, Learn More behavior, and schema compatibility.
Implementation references
  • Claude Code documents the permission mode indicator labels used by IDE UI here: https://code.claude.com/docs/en/permission-modes#switch-permission-modes.
  • The visible enum and descriptions in claudeAgent.ts are based on Claude's official mode behavior docs: https://code.claude.com/docs/en/permission-modes#available-modes.
  • Hiding dontAsk from the interactive picker comes from Claude docs saying dontAsk is for pre-approved tools / locked-down CI and scripts, and never appears in the cycle: https://code.claude.com/docs/en/permission-modes#allow-only-pre-approved-tools-with-dontask-mode.
  • Keeping bypassPermissions visible but danger-coded comes from Claude docs saying it skips prompts/checks and should only be used in isolated containers/VMs: https://code.claude.com/docs/en/permission-modes#skip-all-checks-with-bypasspermissions-mode.
  • Claude schema label/description changes:
    const sessionSchema = createSchema({
    [ClaudeSessionConfigKey.PermissionMode]: schemaProperty<ClaudePermissionMode>({
    type: 'string',
    title: localize('claude.sessionConfig.permissionMode', "Approvals"),
    description: localize('claude.sessionConfig.permissionModeDescription', "How Claude handles tool approvals."),
    enum: ['default', 'acceptEdits', 'plan', 'auto', 'bypassPermissions'],
    enumLabels: [
    localize('claude.sessionConfig.permissionMode.default', "Ask Before Edits"),
    localize('claude.sessionConfig.permissionMode.acceptEdits', "Edit Automatically"),
    localize('claude.sessionConfig.permissionMode.plan', "Plan Mode"),
    localize('claude.sessionConfig.permissionMode.auto', "Auto Mode"),
    localize('claude.sessionConfig.permissionMode.bypassPermissions', "Bypass Permissions"),
    ],
    enumDescriptions: [
    localize('claude.sessionConfig.permissionMode.defaultDescription', "Claude asks before editing files."),
    localize('claude.sessionConfig.permissionMode.acceptEditsDescription', "Claude edits files without asking, and asks before using other tools."),
    localize('claude.sessionConfig.permissionMode.planDescription', "Claude creates a plan before making changes."),
    localize('claude.sessionConfig.permissionMode.autoDescription', "Claude decides whether to ask for each tool operation."),
    localize('claude.sessionConfig.permissionMode.bypassPermissionsDescription', "Claude runs all tools without asking."),
    ],
    default: 'default',
    sessionMutable: true,
    }),
    .
  • Agent Sessions Claude icon mapping:
    const CLAUDE_PERMISSION_MODE_LEARN_MORE_URL = 'https://code.claude.com/docs/en/permission-modes#available-modes';
    const LEARN_MORE_VALUE = '__agentHostClaudePermissionModePicker.learnMore__';
    const claudePermissionModeIcons: Record<string, ThemeIcon> = {
    default: Codicon.shield,
    acceptEdits: Codicon.edit,
    plan: Codicon.lightbulb,
    auto: Codicon.sparkle,
    bypassPermissions: Codicon.warning,
    };
    function getClaudePermissionModeIcon(value: string | undefined): ThemeIcon | undefined {
    return value ? claudePermissionModeIcons[value] : undefined;
    }
    export class AgentHostClaudePermissionModePicker extends AgentHostSessionEnumPicker {
    protected readonly _property = ClaudeSessionConfigKey.PermissionMode;
    protected readonly _pickerId = 'agentHostClaudePermissionModePicker';
    protected readonly _telemetryId = 'NewChatAgentHostClaudePermissionModePicker';
    constructor(
    session: IObservable<IActiveSession | undefined>,
    @IActionWidgetService actionWidgetService: IActionWidgetService,
    @ISessionsProvidersService sessionsProvidersService: ISessionsProvidersService,
    @ITelemetryService telemetryService: ITelemetryService,
    @IHoverService hoverService: IHoverService,
    @IOpenerService private readonly _openerService: IOpenerService,
    ) {
    super(session, actionWidgetService, sessionsProvidersService, telemetryService, hoverService);
    }
    protected _isWellKnownSchema(schema: SessionConfigPropertySchema): boolean {
    return isWellKnownClaudePermissionModeSchema(schema);
    }
    protected _getTriggerIcon(value: string | undefined): ThemeIcon | undefined {
    return getClaudePermissionModeIcon(value);
    }
    protected _getActionItemIcon(item: IAgentHostSessionEnumPickerItem): ThemeIcon | undefined {
    return getClaudePermissionModeIcon(item.value);
    }
    .
  • Generic config picker skip follows the existing dedicated-picker pattern for autoApprove and mode:
    // When the autoApprove property uses the well-known schema, the
    // workbench `PermissionPickerActionItem` (registered separately for
    // `Menus.NewSessionControl`) handles it — skip it here to avoid
    // double-rendering. Non-conforming schemas still fall through to
    // the generic per-property picker below.
    if (property === SessionConfigKey.AutoApprove && isWellKnownAutoApproveSchema(schema)) {
    continue;
    }
    // When the mode property uses the well-known schema, the dedicated
    // {@link AgentHostModePicker} (registered separately for
    // `Menus.NewSessionConfig`) handles it. Non-conforming schemas
    // still fall through to the generic per-property picker below.
    if (property === SessionConfigKey.Mode && isWellKnownModeSchema(schema)) {
    continue;
    }
    // Claude's permissionMode has a dedicated Claude-native picker so
    // it doesn't render as a generic enum chip.
    if (property === ClaudeSessionConfigKey.PermissionMode && isWellKnownClaudePermissionModeSchema(schema)) {
    continue;
    }
    .
  • New-session picker registration follows the existing action/view-item pattern:
    this._register(actionViewItemService.register(
    Menus.NewSessionControl,
    NEW_SESSION_PERMISSION_MODE_PICKER_ID,
    (_action, _options, scopedInstantiationService) => {
    const { session } = scopedInstantiationService.invokeFunction(accessor => accessor.get(ISessionInputContext));
    return new PickerActionViewItem(scopedInstantiationService.createInstance(AgentHostClaudePermissionModePicker, session));
    },
    ));
    this._register(actionViewItemService.register(
    MenuId.ChatInputSecondary,
    RUNNING_SESSION_CONFIG_PICKER_ID,
    this._createRunningSessionPermissionPickerFactory(),
    ));
    this._register(actionViewItemService.register(
    MenuId.ChatInputSecondary,
    RUNNING_SESSION_PERMISSION_MODE_PICKER_ID,
    (_action, _options, scopedInstantiationService) => {
    const { session } = scopedInstantiationService.invokeFunction(accessor => accessor.get(ISessionInputContext));
    return new PickerActionViewItem(scopedInstantiationService.createInstance(AgentHostClaudePermissionModePicker, session));
    and
    const NEW_SESSION_PERMISSION_MODE_PICKER_ID = 'sessions.agentHost.newSessionPermissionModePicker';
    registerAction2(class extends Action2 {
    constructor() {
    super({
    id: NEW_SESSION_PERMISSION_MODE_PICKER_ID,
    title: localize2('agentHostNewSessionPermissionModePicker', "Approvals"),
    f1: false,
    menu: [{
    id: Menus.NewSessionControl,
    group: 'navigation',
    order: 2,
    when: ContextKeyExpr.or(IsActiveSessionLocalAgentHost, IsActiveSessionRemoteAgentHost),
    }],
    });
    }
    override async run(): Promise<void> { }
    });
    .
  • Workbench chat needed its own Claude icon mapping because the Extension Host window uses agentHostChatInputPicker.ts, not the Agent Sessions picker:
    const claudePermissionModeIcons: Record<string, ThemeIcon> = {
    default: Codicon.shield,
    acceptEdits: Codicon.edit,
    plan: Codicon.lightbulb,
    auto: Codicon.sparkle,
    bypassPermissions: Codicon.warning,
    };
    interface IConfigPickerItem {
    readonly value: string;
    readonly label: string;
    readonly description?: string;
    }
    function getConfigIcon(property: string, value: unknown | undefined): ThemeIcon | undefined {
    if (property === SessionConfigKey.Mode) {
    switch (value) {
    case 'plan': return Codicon.checklist;
    case 'autopilot': return Codicon.rocket;
    case 'interactive': return Codicon.comment;
    }
    }
    if (property === SessionConfigKey.AutoApprove) {
    if (value === 'autopilot') {
    return Codicon.rocket;
    }
    if (value === 'autoApprove') {
    return Codicon.warning;
    }
    return Codicon.shield;
    }
    if (property === ClaudeSessionConfigKey.PermissionMode && typeof value === 'string') {
    return claudePermissionModeIcons[value];
    }
    return undefined;
    .

Agents window with agent host claude:
Screenshot 2026-06-16 at 2 21 13 PM

Editor window with agent host claude:
Screenshot 2026-06-16 at 2 20 40 PM

Compare with what Claude Code does themselves via their own VS Code extension:
Screenshot 2026-06-16 at 2 37 10 PM

Copilot AI review requested due to automatic review settings June 16, 2026 21:24
@anthonykim1 anthonykim1 self-assigned this Jun 16, 2026
@anthonykim1 anthonykim1 added this to the 1.126.0 milestone Jun 16, 2026
@anthonykim1 anthonykim1 moved this to In Progress in Agent Host Protocol Jun 16, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates Claude agent-host “permissionMode” presentation to use clearer labels/descriptions and consistent, distinct icons across the workbench and Agents (sessions) UI, and adjusts related tests/schema detection to match the updated mode set.

Changes:

  • Add Claude permission-mode icon mappings (including new auto icon) for session config pickers.
  • Update Claude permissionMode schema labels/descriptions and remove the “Don’t Ask” option from the advertised enum.
  • Refactor/expand sessions-side tests to cover the updated modes and schema compatibility checks.
Show a summary per file
File Description
src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatInputPicker.ts Adds Claude permission-mode icon mapping for the workbench chat-input config picker.
src/vs/sessions/contrib/providers/agentHost/test/browser/agentHostClaudePermissionModePicker.test.ts Updates tests to validate the new Claude-native mode labels and distinct icons; refactors setup.
src/vs/sessions/contrib/providers/agentHost/test/browser/agentHost/agentHostPermissionPickerDelegate.test.ts Adjusts schema “well-known” detection tests and ensures dontAsk-inclusive schemas remain accepted.
src/vs/sessions/contrib/providers/agentHost/browser/agentHostSessionConfigPicker.ts Skips generic enum chip for Claude permissionMode and wires a dedicated picker action into the new-session controls.
src/vs/sessions/contrib/providers/agentHost/browser/agentHostClaudePermissionModePicker.ts Adds icon mapping for Claude permission modes (including auto).
src/vs/platform/agentHost/node/claude/claudeAgent.ts Updates Claude session-config schema enum/labels/descriptions for permission modes.

Copilot's findings

  • Files reviewed: 6/6 changed files
  • Comments generated: 3

Comment thread src/vs/platform/agentHost/node/claude/claudeAgent.ts
@anthonykim1 anthonykim1 marked this pull request as ready for review June 16, 2026 22:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: In Progress

Development

Successfully merging this pull request may close these issues.

Update claude agent's icon

2 participants