dsh-input-traffic 0.2.7 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/README.en.md +47 -6
  2. package/README.md +60 -9
  3. package/lib/client.js +158 -104
  4. package/lib/client.js.map +1 -1
  5. package/lib/types/client/auto-continue-core.d.ts +103 -0
  6. package/lib/types/client/auto-continue-core.d.ts.map +1 -0
  7. package/lib/types/client/auto-continue-core.js +131 -0
  8. package/lib/types/client/auto-continue-core.js.map +1 -0
  9. package/lib/types/client/auto-continue-store.d.ts +41 -0
  10. package/lib/types/client/auto-continue-store.d.ts.map +1 -0
  11. package/lib/types/client/auto-continue-store.js +93 -0
  12. package/lib/types/client/auto-continue-store.js.map +1 -0
  13. package/lib/types/client/freeze-button.d.ts +1 -1
  14. package/lib/types/client/freeze-button.d.ts.map +1 -1
  15. package/lib/types/client/freeze-button.js +30 -6
  16. package/lib/types/client/freeze-button.js.map +1 -1
  17. package/lib/types/client/freeze-store.d.ts +17 -10
  18. package/lib/types/client/freeze-store.d.ts.map +1 -1
  19. package/lib/types/client/freeze-store.js +54 -38
  20. package/lib/types/client/freeze-store.js.map +1 -1
  21. package/lib/types/client/index.d.ts.map +1 -1
  22. package/lib/types/client/index.js +15 -12
  23. package/lib/types/client/index.js.map +1 -1
  24. package/lib/types/client/locales.d.ts +1 -0
  25. package/lib/types/client/locales.d.ts.map +1 -1
  26. package/lib/types/client/locales.js +2 -0
  27. package/lib/types/client/locales.js.map +1 -1
  28. package/lib/types/client/session-guard-bridge.d.ts +18 -0
  29. package/lib/types/client/session-guard-bridge.d.ts.map +1 -0
  30. package/lib/types/client/session-guard-bridge.js +42 -0
  31. package/lib/types/client/session-guard-bridge.js.map +1 -0
  32. package/lib/types/client/steer-queue-dock.d.ts +9 -3
  33. package/lib/types/client/steer-queue-dock.d.ts.map +1 -1
  34. package/lib/types/client/steer-queue-dock.js +6 -5
  35. package/lib/types/client/steer-queue-dock.js.map +1 -1
  36. package/package.json +104 -104
package/README.en.md CHANGED
@@ -31,6 +31,7 @@ A cordis client plugin assembled via the `dsh plugin` command and a bundle patch
31
31
  - **Edits are never lost**: if saving an edit fails (the agent already claimed the message), the edited content automatically moves back to the composer; an occupied draft is never overwritten.
32
32
  - **Peak-hour freeze**: a "Freeze session" button on the composer's right — near DeepSeek peak pricing hours (09:00-12:00, 14:00-18:00) it pauses API consumption: the current turn finishes naturally, then the unsent queue is frozen; "Resume session" continues during off-peak hours.
33
33
  - **Official behavior takeover**: while the plugin is mounted, the official "busy-Enter behavior" settings row is hidden (Enter stays queue-later).
34
+ - **Day/night auto-adapt**: the dock and the freeze button use dsh's official semantic tokens (`--dsw-alias-*`) exclusively, so they follow the system dark mode / dsh dark theme automatically — in dark mode they switch to a **dark-gray surface with inverted (white) text**, with no configuration (see "Day/night mode").
34
35
 
35
36
  ## UI preview
36
37
 
@@ -69,9 +70,22 @@ The "Freeze session / Resume session" button on the composer's right (beside the
69
70
 
70
71
  - **Freeze**: the current turn is **not interrupted** — it finishes naturally, then consumption pauses. The queue is fully **decoupled from freezing**: freezing only stops the agent from consuming (executing / inserting / appending), while the waiting area stays visible and **fully operable** — reorder, edit, remove and set the red/yellow/green insertion tier, just like when not frozen;
71
72
  - **Resume**: the (possibly edited) queue is re-submitted and **each entry executes with its planned tier** (red = interrupt and process immediately, yellow = interject, green = queue); the agent continues in FIFO order;
72
- - Engine: freeze = detach every queued row via `updateQueue(remove)` (copies with their tiers kept in the plugin store); the driver stops naturally once the current turn ends with no pending work; edits made while frozen (text / order / tier) write back to the store in real time; resume = re-submit via `send(text)`, waking the driver (red-tier entries are preceded by `cancel()`);
73
+ - **Session isolation**: freeze state and the detached queue are keyed **by sessionId** (`src/client/freeze-store.ts`'s `Map<string, FreezeState>`) freezing session A never affects session B's banner/button/queue; editing only re-renders the owning session's consumers;
74
+ - **Engine**: freeze = detach every queued row via `updateQueue(remove)` (copies with their tiers kept in the plugin store, keyed by session); the driver stops naturally once the current turn ends with no pending work; edits made while frozen (text / order / tier) write back to the store in real time; resume = first `await sessionGuard.resume(sessionId)` (so the interrupted turn's natural next step happens first), then re-submit via `send(text)`, waking the driver (red-tier entries are preceded by `cancel()`);
73
75
  - Note: queued messages containing non-text content (images) cannot be re-sent and are released by the freeze (they do not come back).
74
76
 
77
+ ### Session-level locking via dsh-session-guard
78
+
79
+ The freeze button hands off to a **sessionGuard bridge** (`src/client/session-guard-bridge.ts` → `POST /session-guard/rpc { action: stopNextTurn|resume, sessionId }`) for **per-session locking** on the server side, while raising a composer block (`conversation.blocks.set`) so the input box turns inert and Enter can no longer leak into the conversation:
80
+
81
+ - **Component references**:
82
+ - `src/client/freeze-button.tsx` — freeze/resume control (slot `conversation.input.right`);
83
+ - `src/client/steer-queue-dock.tsx` — three-tier planning dock + frozen banner/list (slot `conversation.input.dock` id `queue`);
84
+ - `src/client/freeze-store.ts` — session-scoped freeze state (`Map<sessionId, {frozen, pending}>`, shared by button ↔ dock);
85
+ - `src/client/session-guard-bridge.ts` — session-guard RPC bridge (fail-open, silently skipped when session-guard is absent);
86
+ - `src/client/index.ts` — slot registration + composer-block injection (`conversation.blocks.set`).
87
+ - **Scope comparison**: this plugin's freeze button = **per-session** (locks that one session by id); session-guard's **auto peak gate = global** (pauses all running sessions on peak entry, resumes all on exit). They complement each other — the gate handles the global case, the button the single-session case.
88
+
75
89
  ## Queue management
76
90
 
77
91
  Each waiting-area message (while not frozen) offers:
@@ -95,16 +109,28 @@ When editing a queued message (inline):
95
109
  - **Shortcuts**: `Enter` saves, `Shift+Enter` inserts a newline, `Esc` cancels (composition input is protected from accidental saves);
96
110
  - **Failure fallback**: if the save fails because the agent already claimed the message (e.g. "started sending"), the edited content automatically moves back to the composer with a notice — **nothing is lost**; the back-fill only happens when the composer is empty, so an existing draft is never overwritten.
97
111
 
112
+ ## Day/night mode (automatic dark adaptation)
113
+
114
+ The dock and the freeze button **no longer use hand-drawn colors** — they reference dsh's official semantic tokens (`--dsw-alias-*`: `bg-layer-*` / `border-l*` / `label-*` / `interactive-bg-hover` / `state-success|warn|error-primary`) maintained by the dsh theme system:
115
+
116
+ - **Automatic follow**: dsh's default theme preference is "system" — when the OS switches to dark mode (or you pick a dark theme in dsh settings), `body[data-ds-dark-theme]` takes effect and the tokens switch to the dark palette, so the dock becomes a **dark-gray surface with inverted (white) text** and the tier colors use the official dark-adapted values (contrast is guaranteed by dsh);
117
+ - **No configuration**: the plugin does not watch the system and adds no settings — light/dark is fully delegated to the dsh theme; the day appearance is unchanged;
118
+ - **Scope**: the waiting-area dock (including the frozen banner / frozen list) and the "Freeze session" button on the composer's right.
119
+
98
120
  ## Installation
99
121
 
100
122
  ```sh
101
- # Option 1: install from npm (recommended)
123
+ # Option 1: install from npm (recommended, stable release)
102
124
  # (the profile is a pnpm workspace root, so -w is required)
103
125
  dsh plugin --profile web add dsh-input-traffic -w
104
126
 
105
- # Option 2: assemble from git or a local path
127
+ # Option 2: install directly from GitHub (drscrewdriver fork trial new features first)
128
+ # (lib/ is not committed; after install build in the profile:
129
+ # cd ~/.dsh/profiles/web/node_modules/dsh-input-traffic && npm install --legacy-peer-deps && npm run build)
130
+ dsh plugin --profile web add github:drscrewdriver/dsh-input-traffic#main
131
+
132
+ # Option 3: assemble from a local path
106
133
  # dsh plugin --profile web add /absolute/path/to/dsh-input-traffic -w
107
- # (after git install, build in the profile's node_modules: npm install --legacy-peer-deps && npm run build)
108
134
 
109
135
  # Confirm the composed tree contains the new row
110
136
  dsh web --dump-config | grep -B1 -A2 'input-traffic'
@@ -113,6 +139,8 @@ dsh web --dump-config | grep -B1 -A2 'input-traffic'
113
139
  dsh web
114
140
  ```
115
141
 
142
+ > ⚠️ **GitHub reachability**: installing via github: requires access to github.com; if your network is restricted, set up a working proxy or mirror first, otherwise add may stall while fetching.
143
+
116
144
  Local build and tests:
117
145
 
118
146
  ```sh
@@ -175,7 +203,7 @@ Expected — the plugin hides it and pins Enter to green queue; a stale preferen
175
203
 
176
204
  ### Queued messages disappeared after freezing
177
205
 
178
- Expected — the freeze detaches the queue into the plugin store (removed from the waiting area); they return on resume. Refreshing the page loses the frozen queue; avoid refreshing while frozen.
206
+ Expected — the freeze detaches the queue into the plugin store (keyed by session, removed from the waiting area); they return on resume. Refreshing the page loses the frozen queue; avoid refreshing while frozen.
179
207
 
180
208
  ### Move up/down is disabled
181
209
 
@@ -211,7 +239,7 @@ src/
211
239
  ├── index.ts # browser half apply: busyEnter pinned to queue + three slot registrations
212
240
  ├── steer-queue-dock.tsx # three-tier planning dock (shadows conversation.input.dock id queue)
213
241
  ├── freeze-button.tsx # freeze/resume button (conversation.input.right)
214
- ├── freeze-store.ts # shared freeze state (composer button ↔ dock banner)
242
+ ├── freeze-store.ts # session-scoped freeze state (Map<sessionId, {frozen, pending}>)
215
243
  ├── hide-enter-row.tsx # settings-row hiding (shadows settings.general.item id composer-enter)
216
244
  ├── locales.ts # steer dictionaries (zh/en)
217
245
  └── *.module.css
@@ -241,6 +269,19 @@ End-to-end browser verification on a live `dsh web`, zero application console er
241
269
  - Semantics reference: [dsh-traffic-light](https://github.com/yimeng-dev/dsh-traffic-light) (desktop session-status traffic light)
242
270
  - Harness anchors: `packages/client/AGENTS.md`, `packages/client/tsdown.client.ts`, `packages/client/web/src/platform.ts`, `packages/bundle/web-app/cordis.patch.yml`, `packages/client/ui-conversation/src/client/queue/QueueDock.tsx`, `packages/host/apiproxy/src/api-proxy.ts`
243
271
 
272
+ ## drscrewdriver DSH Plugin Family
273
+
274
+ This project is one of the DSH plugins maintained by [drscrewdriver](https://github.com/drscrewdriver). If this one helps you, the others likely will too:
275
+
276
+ | Plugin | One-liner |
277
+ |---|---|
278
+ | **[dsh-input-traffic](https://github.com/drscrewdriver/dsh-input-traffic)** | Busy-time input queue: three-tier traffic control, drag-to-reorder, session freeze |
279
+ | **[dsh-session-guard](https://github.com/drscrewdriver/dsh-session-guard)** | Peak auto session gate: weekend mode + peak auto-pause + session-level lock + backend auto-retry (pairs with this plugin's button) |
280
+ | [dsh-thinking-levels](https://github.com/drscrewdriver/dsh-thinking-levels) | Per-round reasoning_effort control: Auto scheduling or manual wire level |
281
+ | [dsh-seatbelt-sandbox](https://github.com/drscrewdriver/dsh-seatbelt-sandbox) | macOS Seatbelt sandbox adapter: native libsandbox loader replacing deprecated sandbox-exec |
282
+ | [dsh-switch-search](https://github.com/drscrewdriver/dsh-switch-search) | Session content search sidebar: title/content toggle, type-filter by user/reply/tool |
283
+
244
284
  ## License
245
285
 
246
286
  MIT
287
+
package/README.md CHANGED
@@ -6,7 +6,9 @@
6
6
  </p>
7
7
  <p align="center">
8
8
  <a href="LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-263146?style=flat-square"></a>
9
+ <img src="https://camo.githubusercontent.com/2c11fb2e0e14bb9985c5acbe61123a7441c5ee63aa27fa6e04e2a707ebfd6022/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6473682d2d706c7567696e2d72656164792d3437384342463f6c6f676f3d646565707365656b266c6f676f436f6c6f723d7768697465" alt="dsh-plugin" data-canonical-src="https://img.shields.io/badge/dsh--plugin-ready-478CBF?logo=deepseek&amp;logoColor=white" style="max-width: 100%;">
9
10
  <img alt="Public beta" src="https://img.shields.io/badge/status-public%20beta-7da1de?style=flat-square">
11
+ <a href="https://dshfind.com/zh/plugins/drscrewdriver/dsh-input-traffic?ref=badge"><img alt="dsh-input-traffic" src="https://dshfind.com/api/badge/drscrewdriver/dsh-input-traffic?lang=zh"></a>
10
12
  </p>
11
13
 
12
14
  # dsh-input-traffic
@@ -20,6 +22,8 @@
20
22
  > **目前建议搭配**:配合**一般提醒**插件(如 [dsh-notify](https://github.com/zhengjy01/dsh-notify),到点桌面提醒「该冻结/该恢复」)与**计费统计**插件(如 [dsh-deepseek-usage](https://github.com/yyb16yyb-hub/dsh-deepseek-usage)、[dsh-cost-tracker](https://github.com/yflmq001/dsh-cost-tracker)、[dsh-billing-balance](https://github.com/YZz-S/dsh-billing-balance),核对冻结前后的实际花费),形成「提醒 → 冻结 → 错峰恢复 → 对账」的省钱闭环。
21
23
 
22
24
  ## 它能做什么
25
+ <img width="1809" height="547" alt="image" src="https://github.com/user-attachments/assets/4a89687b-5444-4538-b1b2-f0fd093cdd10" />
26
+ <img width="1051" height="302" alt="image" src="https://github.com/user-attachments/assets/710a101e-9ba1-41f0-b74d-bb0ccca77928" />
23
27
 
24
28
  - **三档插入并存**:智能体忙碌时,每一条输入都先进入等待区,再按需选择何时进入对话——不再只有一个"打断"或只有一个"排队":
25
29
  - 🔴 **红色(now)**:打断当前轮次并立即输入——当前生成停止,消息作为新输入被 agent 立刻处理并回复;
@@ -30,7 +34,9 @@
30
34
  - **队列管理**:等待区的消息可以**上移 / 下移调整顺序**、删除,以及队列级「取消并清空」。
31
35
  - **编辑不丢内容**:编辑保存失败(消息已被 agent 认领)时,编辑内容自动退回主输入框,不会丢失;主输入框已有内容时不覆盖。
32
36
  - **高峰期冻结**:输入框右侧「冻结会话」按钮——邻近 DeepSeek 高峰收费时段(9:00-12:00、14:00-18:00)时主动暂停 API 消耗:当前轮次自然完成后暂停,未发送队列冻结保存;「恢复会话」后在非高价时间继续处理。
37
+ - **会话隔离冻结**:冻结队列按 **sessionId 隔离**——冻结一个会话不影响其他会话(各自独立的 frozen 标志与 detached 队列),多会话并行时互不串台(见「会话冻结 / 恢复」)。
33
38
  - **接管官方行为**:插件生效时,官方设置面板的「繁忙时 Enter 键行为」设置行不再显示(Enter 行为固定为绿色排队)。
39
+ - **日夜自动适配**:队列框与冻结按钮全部改用 dsh 官方语义 token(`--dsw-alias-*`),自动跟随系统深色模式 / dsh 暗色主题——深色下自动变为**深灰底 + 白色反色字**,无需任何设置(见「日夜模式」)。
34
40
 
35
41
  ## 界面预览
36
42
 
@@ -69,9 +75,22 @@
69
75
 
70
76
  - **冻结**:当前轮次**不打断**、自然完成后暂停;**队列与冻结解耦**——冻结只停止 agent 消费(执行/插入/追加),等待队列保持可见且**完全可操作**(排序、编辑、删除、设定红/黄/绿插入档位),与未冻结无明显区别;
71
77
  - **恢复**:按修改后的队列重新入队,**按每条预定的档位执行**(红=打断并立即处理,黄=插话,绿=排队),agent 按 FIFO 继续处理;
72
- - 引擎实现:冻结 = 逐条 `updateQueue(remove)` 分离队列(含档位的副本存于插件 store),当前轮次完成后 driver 因无 pending 自然停止;冻结期间对队列的修改(文本/顺序/档位)实时写回 store;恢复 = 逐条 `send(text)` 重新提交并唤醒 driver(红色档位的条目先 `cancel()` 再发送);
78
+ - **会话隔离**:冻结状态与 detached 队列按 **sessionId 键控**(`src/client/freeze-store.ts` `Map<string, FreezeState>`)——A 会话冻结不影响 B 会话的 banner/按钮/队列;编辑只重渲染对应会话的消费者;
79
+ - **引擎实现**:冻结 = 逐条 `updateQueue(remove)` 分离队列(含档位的副本存于插件 store,按 sessionId 隔离),当前轮次完成后 driver 因无 pending 自然停止;冻结期间对队列的修改(文本/顺序/档位)实时写回 store;恢复 = 先 `await sessionGuard.resume(sessionId)`(被打断回合的自然下一步先发生),再逐条 `send(text)` 重新提交并唤醒 driver(红色档位的条目先 `cancel()` 再发送);
73
80
  - 注意:含非文本内容(图片)的排队消息无法重发,冻结时会随队列释放(不会恢复)。
74
81
 
82
+ ### 借助 dsh-session-guard 实现会话级锁定
83
+
84
+ 冻结按钮触发时经 **sessionGuard 桥**(`src/client/session-guard-bridge.ts` → `POST /session-guard/rpc { action: stopNextTurn|resume, sessionId }`)透传服务端做**会话级锁定**;同时在前端 raise composer block(`conversation.blocks.set`),输入框变 inert、回车不再漏进对话:
85
+
86
+ - **引用组件指向**:
87
+ - `src/client/freeze-button.tsx` — 冻结/恢复控制(slot `conversation.input.right`);
88
+ - `src/client/steer-queue-dock.tsx` — 三档规划等待区 + 冻结横幅/冻结列表(slot `conversation.input.dock` id `queue`);
89
+ - `src/client/freeze-store.ts` — 会话级冻结状态 store(`Map<sessionId, {frozen, pending}>`,供按钮 ↔ dock 共享);
90
+ - `src/client/session-guard-bridge.ts` — session-guard RPC 透传(fail-open,未装则静默);
91
+ - `src/client/index.ts` — slot 注册 + composer block 注入(`conversation.blocks.set`)。
92
+ - **作用域对比**:本插件冻结按钮 = **会话级**(按 sessionId 锁那一个会话);session-guard **自动高峰门 = 全局**(入峰暂停全部、退峰自动恢复全部)。两者互补——自动门管全局、按钮管单会话。
93
+
75
94
  ## 队列管理
76
95
 
77
96
  等待区每条消息(未冻结时)提供:
@@ -95,16 +114,28 @@
95
114
  - **快捷键**:`Enter` 保存,`Shift+Enter` 换行,`Esc` 取消(中文输入法组合期间不会误保存);
96
115
  - **失败兜底**:保存时若消息已被 agent 认领(如「已经开始发送」),编辑内容自动退回主输入框并提示,**不会丢失**;仅当主输入框为空时回填,已有草稿不被覆盖。
97
116
 
117
+ ## 日夜模式(自动适配深色)
118
+
119
+ 队列框与冻结按钮的配色**不再使用自绘颜色**,全部改为引用 dsh 官方语义 token(`--dsw-alias-*`:`bg-layer-*` / `border-l*` / `label-*` / `interactive-bg-hover` / `state-success|warn|error-primary`)。这些 token 由 dsh 主题系统统一维护:
120
+
121
+ - **自动跟随**:dsh 默认主题偏好为「跟随系统」——系统切到深色模式(或在 dsh 设置里手动选暗色主题)时,`body[data-ds-dark-theme]` 生效,token 自动切换为深色盘,队列框变为**深灰底 + 白色反色字**,三档色用官方暗色适配值(对比度由 dsh 保证);
122
+ - **无需配置**:插件本身不监听系统、不新增设置项——深浅完全交给 dsh 主题,白天外观保持不变;
123
+ - **范围**:等待区 dock(含冻结横幅 / 冻结列表)与输入框右侧「冻结会话」按钮。
124
+
98
125
  ## 安装
99
126
 
100
127
  ```sh
101
- # 方式一:从 npm 安装(推荐)
128
+ # 方式一:从 npm 安装(推荐,稳定发布)
102
129
  # (profile 是 pnpm workspace root,add 需带 -w 参数)
103
130
  dsh plugin --profile web add dsh-input-traffic -w
104
131
 
105
- # 方式二:git 或本地路径组装
132
+ # 方式二:GitHub 直装(drscrewdriver fork 专属,先试用新功能)
133
+ # (本仓库未提交 lib/,装后需在 profile 内现场构建:
134
+ # cd ~/.dsh/profiles/web/node_modules/dsh-input-traffic && npm install --legacy-peer-deps && npm run build)
135
+ dsh plugin --profile web add github:drscrewdriver/dsh-input-traffic#main
136
+
137
+ # 方式三:本地路径组装
106
138
  # dsh plugin --profile web add /absolute/path/to/dsh-input-traffic -w
107
- # (git 安装后需在 profile 的 node_modules 内现场构建:npm install --legacy-peer-deps && npm run build)
108
139
 
109
140
  # 确认组合树包含新行
110
141
  dsh web --dump-config | grep -B1 -A2 'input-traffic'
@@ -113,13 +144,15 @@ dsh web --dump-config | grep -B1 -A2 'input-traffic'
113
144
  dsh web
114
145
  ```
115
146
 
147
+ > ⚠️ **GitHub 网络可达性**:github: 直装需要能连通 github.com;网络受限时请先配置可用代理或镜像加速,否则 add 会在拉取阶段卡住。
148
+
116
149
  本地构建与测试:
117
150
 
118
151
  ```sh
119
152
  npm install --legacy-peer-deps # @deepseek-ai client 包链在 npm 上不完整,仅装工具链
120
153
  npm run build # tsc(lib/types)+ tsdown(lib/index.js + lib/client.js)
121
154
  node examples/verify-assembly.mjs # 12 项装配断言
122
- npm test # 45 项 vitest 组件测试
155
+ npm test # 50 项 vitest 组件测试
123
156
  npm run lint # ESLint(src + tests,flat config)
124
157
  npm run verify # 一体化门禁:lint + test + build + verify-assembly
125
158
  ```
@@ -137,7 +170,7 @@ npm run tdd # vitest watch:改动即重跑,红→绿闭环
137
170
  1. 在 `tests/` 新增/修改用例(红:确认新行为尚未实现);
138
171
  2. `npm run tdd` 观察失败;
139
172
  3. 在 `src/` 最小实现(绿);
140
- 4. `npm run verify` 全绿后提交(lint + 36 测试 + 构建 + 12 项装配断言)。
173
+ 4. `npm run verify` 全绿后提交(lint + 50 测试 + 构建 + 12 项装配断言)。
141
174
 
142
175
  Lint 说明:
143
176
 
@@ -175,7 +208,11 @@ npm run lint:fix # 自动修复可修复项
175
208
 
176
209
  ### 冻结后排队消息消失了
177
210
 
178
- 正常——冻结会把队列保存到插件内存(从等待区移除),恢复后重新出现。刷新页面会丢失冻结队列,请避免冻结后刷新。
211
+ 正常——冻结会把队列保存到插件 store(按 sessionId 隔离,从等待区移入冻结列表),恢复后重新出现。**刷新页面会丢失冻结队列**,请避免冻结后刷新。
212
+
213
+ ### 冻结一个会话会影响其他会话吗
214
+
215
+ 不会。冻结队列按 **sessionId 隔离**(`freeze-store.ts` 的 `Map<sessionId, …>`)——冻结 A 会话不影响 B 会话的冻结按钮/横幅/队列;编辑 A 的冻结队列只重渲染 A 的消费者。
179
216
 
180
217
  ### 上移/下移按钮不可用
181
218
 
@@ -211,7 +248,8 @@ src/
211
248
  ├── index.ts # browser half apply:busyEnter 固定 queue + 三处 slot 注册
212
249
  ├── steer-queue-dock.tsx # 三档规划等待区(shadowing conversation.input.dock id queue)
213
250
  ├── freeze-button.tsx # 冻结/恢复按钮(conversation.input.right)
214
- ├── freeze-store.ts # 冻结状态共享 store(composer 按钮 ↔ dock 横幅)
251
+ ├── freeze-store.ts # 会话级冻结状态 store(Map<sessionId, {frozen, pending}>)
252
+ ├── session-guard-bridge.ts # session-guard RPC 透传(会话级锁定,fail-open)
215
253
  ├── hide-enter-row.tsx # 设置行隐藏(shadowing settings.general.item id composer-enter)
216
254
  ├── locales.ts # steer 字典(zh/en)
217
255
  └── *.module.css
@@ -233,7 +271,7 @@ src/
233
271
  | 红色 now | 打断后消息立即被处理:agent 明确回复被打断消息并继续;无滞留中间态 |
234
272
  | 黄色 next + 绿色撤回 | 插话后点绿收回排队,消息回到等待区 |
235
273
  | 冻结 / 恢复 | 当前轮次自然完成不打断、队列冻结保存、横幅提示;恢复后 FIFO 全部处理完成 |
236
- | 队列编辑(多行 / 失败退回) | 组件测试覆盖(32 项全绿);真实环境复核待做 |
274
+ | 队列编辑(多行 / 失败退回) | 组件测试覆盖(50 项全绿);真实环境复核待做 |
237
275
 
238
276
  ## 参考
239
277
 
@@ -241,6 +279,19 @@ src/
241
279
  - 语义参考:[dsh-traffic-light](https://github.com/yimeng-dev/dsh-traffic-light)(Session 运行状态红绿灯提示)
242
280
  - harness 锚点:`packages/client/AGENTS.md`、`packages/client/tsdown.client.ts`、`packages/client/web/src/platform.ts`、`packages/bundle/web-app/cordis.patch.yml`、`packages/client/ui-conversation/src/client/queue/QueueDock.tsx`、`packages/host/apiproxy/src/api-proxy.ts`
243
281
 
282
+ ## drscrewdriver DSH Plugin Family
283
+
284
+ 本项目是 [drscrewdriver](https://github.com/drscrewdriver) 维护的 DSH 插件系列之一。如果这个对你有用,其他插件多半也有用:
285
+
286
+ | 插件 | 一句话描述 |
287
+ |---|---|
288
+ | **[dsh-input-traffic](https://github.com/drscrewdriver/dsh-input-traffic)** | DSH Web GUI 忙时输入队列:三档交通管制,拖拽重排,会话冻结 |
289
+ | **[dsh-session-guard](https://github.com/drscrewdriver/dsh-session-guard)** | 高峰自动会话门:周末模式 + 高峰自动暂停 + 会话级锁定 + 后端自动重试(配本插件按钮) |
290
+ | [dsh-thinking-levels](https://github.com/drscrewdriver/dsh-thinking-levels) | 逐轮 reasoning_effort 控制:Auto 智能调度或手动固定档位 |
291
+ | [dsh-seatbelt-sandbox](https://github.com/drscrewdriver/dsh-seatbelt-sandbox) | macOS Seatbelt 沙箱适配器:libsandbox 原生 loader,接替弃用的 sandbox-exec |
292
+ | [dsh-switch-search](https://github.com/drscrewdriver/dsh-switch-search) | 侧边栏会话搜索增强:标题/内容切换,按用户/回复/工具筛选 |
293
+
244
294
  ## License
245
295
 
246
296
  MIT
297
+