Skip to content

fix: 权限模式改为按 session 持久化,隔离多 tab 状态#365

Merged
ErlichLiu merged 2 commits intoErlichLiu:mainfrom
Andreaseszhang:fix/permission-mode-per-session-persistence
May 4, 2026
Merged

fix: 权限模式改为按 session 持久化,隔离多 tab 状态#365
ErlichLiu merged 2 commits intoErlichLiu:mainfrom
Andreaseszhang:fix/permission-mode-per-session-persistence

Conversation

@Andreaseszhang
Copy link
Copy Markdown
Contributor

@Andreaseszhang Andreaseszhang commented May 1, 2026

Overview

重构权限模式(自动 / 完全自动 / 计划)的存储与切换模型,解决两个现存问题:

  1. 跨窗口状态污染:旧实现下,在任意 tab 切换权限模式会广播到同工作区所有正在跑的 session,导致用户无意间影响了不相关的窗口。一个窗口开计划模式,另一个窗口也会进入计划模式
  2. 重启丢失状态:权限模式只存在 workspace config 的单值字段里,多 tab 的独立状态无法区分;重启后所有 tab 起始模式一样

改造后:每个 session 独立持久化自己的权限模式到 AgentSessionMeta.permissionMode;workspace config 字段降级为"该工作区新 session 的默认值";UI 侧每次发送消息都带 permissionModeOverride,渲染进程成为权威源。

Changes

commit 1 — c1aa356 fix: 权限模式隔离到 session 维度,兼顾持久化与中途热切换

  • apps/electron/src/main/ipc.ts
    • SET_PERMISSION_MODE handler 删除广播逻辑(不再强制同步同工作区其他 active session)
    • 新增 UPDATE_SESSION_PERMISSION_MODE handler:只更新指定 sessionId 的运行时权限模式
  • apps/electron/src/main/lib/agent-orchestrator.ts
    • 初始权限模式不再读 workspace config,改为 permissionModeOverride ?? appSettings.default
    • 初始模式为 plan 时主动 emit enter_plan_mode 事件,修复冷启动就是 plan 时横幅不展示的问题
  • apps/electron/src/preload/index.ts — 新增 updateSessionPermissionMode(sessionId, mode) 方法
  • apps/electron/src/renderer/components/agent/AgentView.tsx — 五个发送路径(auto-send / handleSend / /compact / retry / retryInNewSession)都带上 permissionModeOverride: permissionMode
  • apps/electron/src/renderer/components/agent/PermissionModeSelector.tsx
    • session 初始化时按 workspace config 读回,但只写入当前 sessionId 的 atom 条目,不污染全局 default
    • cycleMode 在持久化之外调用新 IPC 做运行时热切换(仅影响当前 session)
  • packages/shared/src/types/agent.ts — 新增 UPDATE_SESSION_PERMISSION_MODE IPC 常量

commit 2 — ea8e123 fix: 权限模式按 session 持久化,重启后各 tab 独立恢复

  • packages/shared/src/types/agent.tsAgentSessionMeta 新增 permissionMode?: PromaPermissionMode 字段
  • apps/electron/src/main/lib/agent-session-manager.tsupdateAgentSessionMeta Pick 白名单加入 permissionMode
  • apps/electron/src/main/ipc.ts
    • UPDATE_SESSION_PERMISSION_MODE handler:先写 session meta 持久化,active 时再热切换;session 不存在时直接抛错
    • EXIT_PLAN_MODE_RESPOND handler 补写 session meta,避免通过 ExitPlanMode 切到的模式重启后丢失
  • apps/electron/src/renderer/components/agent/PermissionModeSelector.tsx
    • 初始化读回优先级改为:session meta > workspace config > 全局 default
    • useMemo 派生 persistedSessionMode / sessionExistsInList,effect 依赖收窄到 permissionMode 字段值,避免流式中无关字段变化触发重跑
    • 处理冷启动时序:sessions 列表尚未加载时暂不 seed,加载完成后自动重跑

How to Test

  1. 多 tab 隔离:在同一工作区开两个 tab,tab A 切到"计划",tab B 切到"完全自动";确认两者互不影响
  2. 中途切模式:在 tab A 开始流式输出,中途切换模式;确认当前 session 的下一次 canUseTool 立刻使用新模式(不影响同工作区其他 session)
  3. 重启持久化:重启 App,确认每个 tab 恢复到上次保存的权限模式(而非统一默认值)
  4. ExitPlanMode 切换:session 进入计划模式后通过 ExitPlanMode 切到 bypass;重启 App 确认该 session 仍是 bypass
  5. 新 session 默认:在某工作区切换权限模式后,新建 session;确认新 session 继承该 workspace 的值
  6. 运行中的 session:active 状态下切换模式,确认 orchestrator 的 sessionPermissionModes Map 和 SDK 侧都立即生效

Notes

  • Workspace config 的 permissionMode 字段保留,含义从"全工作区共享状态"降级为"新 session 的默认模板",对老数据向前兼容
  • bypassPermissions 通过外部 override 进入的场景(bridge-command-handler、feishu-bridge)不受影响,override 仍然优先
  • typecheck 全部通过;ExitPlanMode → permission_mode_changed 事件和 enter_plan_mode 事件的渲染端 listener 本次未改动,延用现有实现

🤖 Generated with Claude Code

Andreaseszhang and others added 2 commits May 1, 2026 22:03
- 每次 send 带 permissionModeOverride,渲染进程成为权威源
- session 初始化时从 workspace config 读回持久化模式,只写入当前 session,避免跨会话污染
- 新增 UPDATE_SESSION_PERMISSION_MODE IPC,cycleMode 在持久化之外热切换当前 session,保留中途切模式即时生效
- 初始模式为 plan 时主进程主动 emit enter_plan_mode,修复 plan 横幅不展示

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- AgentSessionMeta 新增 permissionMode 字段,随 session index 落盘
- UPDATE_SESSION_PERMISSION_MODE handler:先写 session meta,active 时再热切换;session 不存在时抛明确错误
- EXIT_PLAN_MODE_RESPOND 补写 session meta,保持 meta 优先语义一致(之前只写 workspace config,ExitPlanMode 切换的模式重启后会丢)
- PermissionModeSelector 读回优先级:session meta → workspace config → 全局 default;用 useMemo 把 effect 依赖收窄到 permissionMode 字段本身,避免流式中无关字段变化触发重跑

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@ErlichLiu ErlichLiu merged commit 18fdecd into ErlichLiu:main May 4, 2026
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.

2 participants