# dsh-session-allow > English: [README.md](README.md) DSH(DeepSeek Harness)Web GUI 插件:在权限确认弹窗中新增「**本次会话允许**」选项。 点击后,按**权限级别**记录一条会话级授权(localStorage 持久化,按会话 ID 隔离)。本会话内后续**同级别**的越权请求(`sandbox_permissions` 升级)会自动放行,不再反复弹窗确认;不同级别仍会正常弹窗。 ## 效果 | 场景 | 行为 | |---|---| | 工具请求升级到 `danger-full-access` | 弹窗:**拒绝 / 允许一次 / 本次会话允许 danger-full-access** | | 点击「本次会话允许」 | 当前请求放行 + 该级别记入本会话授权,弹窗消失 | | 本会话内再次请求 `danger-full-access` | **静默自动放行,不再弹窗** | | 本会话内请求 `workspace-write`(未授权级别) | 仍正常弹窗 | | 弹窗底部 | 展示本会话已授权的级别 chips,可点 × 撤销 | | 刷新页面 / 新会话 | 授权按会话 ID 保留 / 隔离,互不影响 | ## 原理(不修改任何核心包) 核心的审批面板注册在 `conversation.composer` 链式 slot(priority 1)。本插件以 **priority 0** 注册同名 slot、select 逻辑相同——链式 slot 按优先级取第一个命中的 entry,因此插件面板完整接管弹窗。授权记录在 `localStorage["dsh.sessionAllow.v1"]`,匹配到授权时在客户端直接代答 `allowed-once`(服务端审计照常记录 `approval/asked` + `approval/decided`)。 授权键:`mode:<权限级别>`(从 reason `escalate sandbox to : ...` 解析);非越权格式兜底为 `tool:<工具名>:`。 ## 安装 ### 方式一:`dsh plugin` 安装(推荐) ```bash dsh plugin --profile web add https://github.com/AnakinCao/dsh-session-allow.git ``` `dsh` 会把本包加入 `~/.dsh/profiles/web/package.json` 的 `dsh.profile.bundles`,启动时由包内 `cordis.patch.yml` 自动插入 loader entry 并挂载客户端 bundle。 ### 方式二:手动安装 1. 把仓库内容放到 `~/.dsh/profiles/web/node_modules/dsh-session-allow/`(或 `pnpm add`)。 2. 在 `~/.dsh/profiles/web/cordis.patch.yml` 末尾追加: ```yaml - insert: - id: dsh-session-allow name: 'dsh-session-allow' ``` > 两种方式**二选一**,勿重复注册(loader 会报 duplicate entry)。 ### 生效 重启 dsh(或重载 profile)并刷新 Web GUI。触发一次越权请求(如让 agent 用 `sandbox_permissions` 重试被拒绝的命令),弹窗应出现三个按钮。 ## 验证 1. 弹窗出现「拒绝 / 允许一次 / 本次会话允许 …」三个按钮。 2. 点击「本次会话允许」→ 当前请求放行。 3. 再次触发同级别越权 → 无弹窗,直接执行。 4. 弹窗底部 chips 显示已放行级别,点 × 撤销后同级别恢复弹窗。 5. 打开另一个会话 → 该级别仍然弹窗(授权按会话隔离)。 ## 卸载 ```bash dsh plugin --profile web remove dsh-session-allow ``` 或在 profile 的 `cordis.patch.yml` 中删除对应 insert,并删除 `node_modules/dsh-session-allow`。授权数据位于浏览器 `localStorage["dsh.sessionAllow.v1"]`,可手动清除。 ## 文件结构 ``` dsh-session-allow/ ├── package.json # dsh.client / dsh.bundle 声明 ├── cordis.patch.yml # loader entry 注册 ├── lib/ │ ├── index.js # host 侧空插件(占位) │ └── client.js # 客户端 bundle(弹窗接管 + 会话授权) ├── test/ │ └── behavior.test.mjs # 授权/自动放行/撤销回归测试 └── README.md ``` ## License MIT