Skip to content

feat(desktop): add permission mode cycling via shift+tab#69

Merged
dang-hai merged 11 commits intomainfrom
feature/add-permission-mode-cycling-vi
Jan 25, 2026
Merged

feat(desktop): add permission mode cycling via shift+tab#69
dang-hai merged 11 commits intomainfrom
feature/add-permission-mode-cycling-vi

Conversation

@github-actions
Copy link
Copy Markdown
Contributor

@github-actions github-actions bot commented Jan 25, 2026

Summary

Auto-generated PR for branch feature/add-permission-mode-cycling-vi

Changes

  • feat: add permission mode cycling with e2e automation support
  • Merge remote-tracking branch 'origin/main' into feature/add-permission-mode-cycling-vi
  • Merge branch 'main' into feature/add-permission-mode-cycling-vi
  • feat(desktop): add permission mode cycling via shift+tab

This PR was automatically created. Please update the description with relevant details.


Summary by cubic

Add permission mode cycling (Plan → Auto‑Accept → Ask) via Shift+Tab and a clickable badge on agent nodes. Modes persist per agent or globally and update Claude Code CLI flags.

  • New Features

    • Shift+Tab cycles permission mode globally; ignores when typing or when ActionPill is expanded. Chat input also supports Shift+Tab.
    • Permission mode badge: shows on hover in the Agent Node header; click or press Enter/Space to cycle.
    • New PermissionModeStore with global default, per‑agent overrides, and localStorage persistence.
    • ClaudeCodeAdapter maps modes to CLI:
      • plan → --allowedTools "Read,Glob,Grep,LSP,WebFetch,WebSearch"
      • auto-accept → --dangerously-skip-permissions
      • ask → no flag
        AgentService passes mode to start/resume commands and supports restartSession to apply changes.
    • ClaudeCodeAgent maps UI modes to SDK values (plan/acceptEdits/default).
    • E2E support via useExpose:
      • canvas: node info and actions
      • agent node and chat: permissionMode get/set/cycle, restart session, view switching, state reads.
  • Bug Fixes

    • Preserve permission-mode when resuming sessions and in fallback paths.
    • Show all SDK permission requests in ActionPill; filter PreToolUse to AskUserQuestion to avoid duplicates.

Written for commit d43709d. Summary will update on new commits.

Hai and others added 10 commits January 19, 2026 15:20
Implement cycling between three permission modes (Plan/Auto-Accept/Ask)
using Shift+Tab keyboard shortcut, matching Claude Code CLI behavior.

- Add PermissionMode type to shared package
- Create PermissionModeStore with global/per-agent override support
- Add Shift+Tab handler in Canvas (coordinated with ActionPill)
- Display permission mode indicator on agent nodes (visible on hover)
- Persist mode selection to localStorage

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Resolved conflicts:
- Canvas.tsx: kept both permissionModeStore (feature) and worktreeService (main)
- ActionPill.tsx: used main's refactored version in features/action-pill/,
  added window.__actionPillExpanded sync for permission mode cycling

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add permission mode indicator UI to AgentChatView with click cycling
- Add useExpose bindings to Canvas for node creation (addAgentNode, etc.)
- Add useExpose bindings to AgentNodePresentation for view/permission control
- Update ClaudeCodeAdapter to pass permission flags to CLI:
  - plan: --allowedTools "Read,Glob,Grep,LSP,WebFetch,WebSearch"
  - auto-accept: --dangerously-skip-permissions
  - ask: no additional flags (default interactive mode)
- Update ICodingAgentAdapter interface with permissionMode parameter
- Pass permission mode from AgentServiceImpl when building CLI commands

E2E automation now supports:
- expose_call(cyclePermissionMode) - cycles through modes
- expose_call(setPermissionMode, [mode]) - sets specific mode
- expose_call(showChat/showTerminal/showOverview) - switches views
- expose_get(permissionMode/activeView/status) - reads state

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The runQuery method was stripping permission-mode from extraArgs when
attempting session resume and in the fallback path. Now extracts both
session-id and permission-mode, preserving permission-mode through
both code paths.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove duplicate permission indicator from AgentChatView
- Make permission indicator in node header clickable to cycle modes
- Add hover styling to indicate interactivity
- Clean up unused CSS and code

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…luse

- SharedEventDispatcher: Show all SDK permission:request events in
  ActionPill, not just AskUserQuestion (SDK chat has no terminal UI)
- ClaudeCodeAgent: Filter PreToolUse hook to only emit for AskUserQuestion;
  other tool events come through PermissionRequest (via canUseTool)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add permissionMode to GenerateRequest interface
- Pass permissionMode from AgentServiceImpl to SDK adapter
- Add restartSession method for permission mode changes
- Update IPC types for permission mode support

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
CLI handles its own permission mode, so the indicator is only
shown in overview and chat views.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dang-hai dang-hai marked this pull request as ready for review January 25, 2026 21:19
Copy link
Copy Markdown

@cubic-dev-ai cubic-dev-ai bot left a comment

Choose a reason for hiding this comment

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

4 issues found across 18 files

Prompt for AI agents (all issues)

Check if these issues are valid — if so, understand the root cause of each and fix them.


<file name="apps/desktop/src/renderer/features/action-pill/ActionPill.tsx">

<violation number="1" location="apps/desktop/src/renderer/features/action-pill/ActionPill.tsx:46">
P2: Clear the global `__actionPillExpanded` flag on unmount to avoid leaving stale state if the ActionPill is removed while expanded.</violation>
</file>

<file name="apps/desktop/src/renderer/services/impl/AgentServiceImpl.ts">

<violation number="1" location="apps/desktop/src/renderer/services/impl/AgentServiceImpl.ts:527">
P2: Magic number 500ms delay should be a named constant. Consider using a descriptive constant like `TERMINAL_READY_DELAY_MS` and document why this specific value was chosen. Better yet, consider using a more robust mechanism to detect terminal readiness instead of an arbitrary timeout.</violation>
</file>

<file name="apps/desktop/src/main/services/coding-agent/query-executor/SdkQueryExecutor.ts">

<violation number="1" location="apps/desktop/src/main/services/coding-agent/query-executor/SdkQueryExecutor.ts:60">
P2: Debug `console.log` should be removed or replaced with the project's logging framework (`getLogServer().log()`). Raw console statements bypass the structured logging infrastructure documented in AGENTS.md.</violation>
</file>

<file name="apps/desktop/src/renderer/nodes/AgentNode/AgentNodePresentation.tsx">

<violation number="1" location="apps/desktop/src/renderer/nodes/AgentNode/AgentNodePresentation.tsx:113">
P2: Missing immediate state sync when `data.agentId` changes. The effect subscribes to mode changes but doesn't initialize the state for the new agent. If `agentId` changes, the permission mode UI could display stale data until the next mode change triggers a subscription callback. Add an immediate state update at the start of the effect.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

- Clear global __actionPillExpanded flag on unmount to prevent stale state
- Replace magic 500ms delay with named constant TERMINAL_READY_DELAY_MS
- Remove debug console.log from SdkQueryExecutor
- Add immediate state sync in permission mode subscription effect

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dang-hai dang-hai merged commit 03a0fe8 into main Jan 25, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant