dsh-input-traffic 0.3.1 → 0.4.1
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.
- package/CHANGELOG.md +10 -2
- package/README.en.md +15 -7
- package/README.md +13 -5
- package/dsh.plugin.json +2 -2
- package/lib/client.js +29 -29
- package/lib/client.js.map +1 -1
- package/lib/types/client/freeze-button.d.ts +4 -4
- package/lib/types/client/index.d.ts +14 -10
- package/lib/types/client/index.d.ts.map +1 -1
- package/lib/types/client/index.js +3 -3
- package/lib/types/client/index.js.map +1 -1
- package/lib/types/client/session-guard-bridge.d.ts.map +1 -1
- package/lib/types/client/session-guard-bridge.js.map +1 -1
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -2,17 +2,25 @@
|
|
|
2
2
|
|
|
3
3
|
所有重要变更与 bug 修复记录于此。版本遵循语义化版本(`dsh plugin --profile web add dsh-input-traffic` 安装)。
|
|
4
4
|
|
|
5
|
-
## 0.
|
|
5
|
+
## 0.4.1 — 2026-09-20
|
|
6
6
|
|
|
7
7
|
### 修复:等待队列尾部按钮被「调整对话宽度」把手抢走点击
|
|
8
8
|
|
|
9
9
|
- **现象**:队列卡片「取消并清空」与三档规划按钮(绿/黄/红)落在对话栏右侧的全高宽度把手(`div.wSkVaW_widthHandle[data-side="right"]`)覆盖范围内,点击被把手解释为拖拽,按钮无法操作。
|
|
10
10
|
- **根因**:把手位于 `.body`(`position: absolute`、`z-index: 8`),而 composer 座位 `.composerSeat` 是 `z-index: 7` 的层叠上下文;本插件的 `.dock` 原为 `width: 100%`(铺满 composer 栈),比输入卡片宽约 32px,尾部控件因此伸进把手的命中带。作为层叠上下文内的后代,dock 无法用 `z-index` 越出撤销层级,只能从几何上让位。
|
|
11
11
|
- **修复**:`.dock` 收敛到官方 `QueueDock` 同款卡片列——按「两侧 clearance + 两侧 dock inset」从栈宽扣除、上限为 composer 卡片宽减去 dock inners、`margin: 0 auto` 居中、inset 以 `padding` 返还,使面板仍与输入卡片对齐;并额外用 `min()` 叠加顶层 `--dsh-chat-content-width` 上限,让面板右缘距把手内缘稳定留出 24px 安全带(窄栏下该把手宽度为 0,`min()` 自动回落为卡片列宽)。离线 Chrome 几何探针:对齐场景把手到面板间距 24.5px → 48.5px,位移 16px 的错位场景 8.5px → 32.5px,四个按钮 `elementFromPoint` 命中自身。
|
|
12
|
-
- **跨线核对(本线专属)**:0.1.2 宿主几何与 0.1.5 线逐字一致,因此本条为 verbatim 移植而非改写——`dsh-v0.1.2-rc.1` 的 `ConversationRoot.module.css` 中 `.widthHandle` 为 `z-index: 8` / `width: min(40px, calc((100% - var(--dsh-chat-content-width)) / 2 - 24px - 24px))`,`[data-side='right']` 为 `left: calc(50% + var(--dsh-chat-content-width) / 2 + 24px)`,且 `--dsh-composer-card-max-width`(= 内容列宽 + 32px)/`--dsh-composer-side-clearance`(16px)/`--dsh-composer-dock-inset`(8px)取值与 0.1.5 线相同。修复注释中「条带内缘在内容列外 24px」的前提在 0.1.2 成立。
|
|
13
12
|
|
|
14
13
|
## Unreleased
|
|
15
14
|
|
|
15
|
+
### 变更:仅支持 DSH 0.1.5+,compat/0.1.5 线(0.2.12-beta.1)
|
|
16
|
+
|
|
17
|
+
- **`engines.dsh` 收窄为 `>=0.1.5-alpha.1 <0.2.0-0`**:0.1.5 引入 Session V3(surface node)、dockkit Sidebar 重写与 Lexical composer。核查确认本插件依赖的三个 slot 锚点(`conversation.input.dock` / `conversation.input.right` / `settings.general.item`)在 0.1.5 全部保留,`session.updateQueue` / `prompt` / `cancel` remote 无破坏记录,因此**代码零结构改动**,仅收窄支持分段。DSH 0.1.2/0.1.3 用户请留在 main 线(0.2.11-beta.1)。
|
|
18
|
+
- **全部 `@deepseek-ai/*` peer 区间同步收窄**到 `>=0.1.5-alpha.1 <0.2.0-0`(`@deepseek-ai/cordis` 保持 `^4.0.1`)。
|
|
19
|
+
- **类型契约锚点**:`src/types/contracts.d.ts` 的镜像锚点已于 2026-09-11 对照 `dsh-v0.1.5-rc.2` 验证,本版仅把头部 supported segment 更新为 0.1.5 分段。
|
|
20
|
+
- **注释现代化**:`src/client/index.ts` 与 `freeze-button.tsx` 中 0.1.1/0.1.2 双版本历史注释改写为 0.1.5 现状(含 0.1.5 新增相邻 slot `conversation.composer.dock` / `conversation.input.left` 说明)。无行为变更。
|
|
21
|
+
- **README 新增「0.1.5 已知回归」节**(宿主侧,非插件 bug):fork 继承排队 prompt(#6314/#6197)、Lexical composer IME(#6231/#6052)、阻塞等待期间 steer 无法抢占(#6030)、升级后 client combo 缓存陈旧需强制刷新(#5999/#6374)。
|
|
22
|
+
- ⚠️ **无实机验证声明**:本版在无 DSH 0.1.5 实机环境下发布(lint/test/build/assembly 通过 + 文档契约静态核对),`input.for(actx)` / `blocks.set` / dock 注入 props 三个未文档化面待实机回归(清单见仓库 checklist.md)。
|
|
23
|
+
|
|
16
24
|
### 破坏性:仅支持 DSH 0.1.2+,完成 `dsh-client-runtime` 移除替换(0.2.11-beta.1)
|
|
17
25
|
|
|
18
26
|
- **`engines.dsh` 收窄为 `>=0.1.2-alpha.1 <0.2.0-0`**:`@deepseek-ai/dsh-client-runtime` 在 0.1.2-alpha.1 被整体删除(commit `be531688f3`),该版本即为本插件的硬分段点。旧版线(≤0.2.10-beta.2)继续服务 DSH 0.1.0/0.1.1。
|
package/README.en.md
CHANGED
|
@@ -23,16 +23,24 @@
|
|
|
23
23
|
- [日本語 changelog](./CHANGELOG.ja.md)
|
|
24
24
|
- [한국어 changelog](./CHANGELOG.ko.md)
|
|
25
25
|
|
|
26
|
-
> **▼ DSH version support**
|
|
27
|
-
> | DSH version |
|
|
28
|
-
> | --- | --- | --- |
|
|
29
|
-
> | 0.1.
|
|
30
|
-
> | 0.1.
|
|
26
|
+
> **▼ DSH version support** (compat/0.1.5 line, since 0.2.12-beta.1)
|
|
27
|
+
> | DSH version | Status | Notes |
|
|
28
|
+
> | --- | --- | --- |
|
|
29
|
+
> | ≥ 0.1.5-alpha.1 | ✅ Supported | Verified against 0.1.5-rc.1 / rc.2 (type contracts mirrored from dsh-v0.1.5-rc.2) |
|
|
30
|
+
> | < 0.1.5-alpha.1 | ⚠️ Not supported | Stay on the `main` line (0.2.11-beta.1, DSH 0.1.2+) or older |
|
|
31
31
|
>
|
|
32
|
-
> - **
|
|
33
|
-
> - **Only the two-release intersection is consumed**: the queue strip lives in `conversation.input.dock` (owner `InputZone` in both releases, and `input.draft` exists in both); the freeze button lives in `conversation.input.right`, whose owner was removed in 0.1.2, so the component reads only `useSession` / `sessionId` — both present in `SessionStandardProps` on both releases.
|
|
32
|
+
> - **The boundary is 0.1.5**: Session V3 (surface nodes), the dockkit Sidebar rewrite, and the Lexical composer are 0.1.5's structural changes. All three slot anchors this plugin shadows (`conversation.input.dock` / `conversation.input.right` / `settings.general.item`) survive in 0.1.5, and the service face (`send` / `cancel` / `updateQueue` / `blocks.set`) has no recorded break — so the code needs zero structural changes; only the supported segment is narrowed.
|
|
34
33
|
> - **Queue strip position**: registered with `order: 1000`, so it sorts after every known contributor of the `conversation.input.dock` band (todo 0 / goal 10 / official queue 20 / dsh-perm-gate notice 30) and sits directly on top of the composer card. DSH has no "last" slot semantics, so this is a convention rather than a structural guarantee — a third-party plugin registering a larger `order` could still land below it.
|
|
35
34
|
|
|
35
|
+
> **▼ Known DSH 0.1.5 regressions (host-side, not plugin bugs)**
|
|
36
|
+
>
|
|
37
|
+
> | Issue | Impact on this plugin | Discussion |
|
|
38
|
+
> | --- | --- | --- |
|
|
39
|
+
> | Forking a session inherits the parent's queued-not-yet-run prompts and re-runs them | This is exactly the queue this plugin manages: a forked child may replay the parent's pending queue | [#6314](https://github.com/deepseek-ai/deepseek-harness/discussions/6314) / [#6197](https://github.com/deepseek-ai/deepseek-harness/discussions/6197) |
|
|
40
|
+
> | Lexical composer breaks under IME composition / browser translation | Affects the "pull back into composer" draft back-fill and send paths | [#6231](https://github.com/deepseek-ai/deepseek-harness/discussions/6231) / [#6052](https://github.com/deepseek-ai/deepseek-harness/discussions/6052) |
|
|
41
|
+
> | Steer cannot preempt during a blocking tool wait (up to ~10 min) | The yellow "insert at next turn" tier is inert during that window — users may misattribute it to the plugin | [#6030](https://github.com/deepseek-ai/deepseek-harness/discussions/6030) |
|
|
42
|
+
> | After upgrading an old profile, a stale client combo leaves the whole plugin tree inactive | First troubleshooting step: **hard-refresh the browser (clear cache)** | [#5999](https://github.com/deepseek-ai/deepseek-harness/discussions/5999) / [#6374](https://github.com/deepseek-ai/deepseek-harness/discussions/6374) |
|
|
43
|
+
|
|
36
44
|
> **Compatibility note:** v0.2.9 ships Japanese (`ja`) and Korean (`ko`) dictionaries, but the current official DSH releases expose only `zh` and `en` through `LocaleRuntime`. On stock DSH, selecting `ja` or `ko` fails with `locale "<id>" is not registered`. These languages will work after official DSH adds the locale IDs. Advanced users can use a DSH fork that updates `LOCALE_IDS` (locale-settings.ts) and `LOCALES` labels (client/index.ts), then rebuild. Changing this plugin alone cannot extend DSH's global locale list.
|
|
37
45
|
|
|
38
46
|
> While the agent is busy, "interrupt" and "queue" are no longer mutually exclusive: red interrupts and sends now, yellow inserts at the next turn, green queues until the end — all three coexist. Near DeepSeek peak pricing hours, one click freezes the session; resume later during off-peak pricing.
|
package/README.md
CHANGED
|
@@ -27,17 +27,25 @@
|
|
|
27
27
|
|
|
28
28
|
> **▼ DSH 版本适配**
|
|
29
29
|
>
|
|
30
|
-
>
|
|
30
|
+
> 本插件(compat/0.1.5 线,0.2.12-beta.1 起)**仅支持 DSH v0.1.5+**。
|
|
31
31
|
>
|
|
32
32
|
> | DSH 版本 | 状态 | 说明 |
|
|
33
33
|
> | --- | --- | --- |
|
|
34
|
-
> | ≥ 0.1.
|
|
35
|
-
> | < 0.1.
|
|
34
|
+
> | ≥ 0.1.5-alpha.1 | ✅ 支持 | 面向 0.1.5-rc.1 / rc.2 验证(类型契约已对照 dsh-v0.1.5-rc.2) |
|
|
35
|
+
> | < 0.1.5-alpha.1 | ⚠️ 不支持 | 请留在 main 线(0.2.11-beta.1,支持 0.1.2+)或更早版本 |
|
|
36
36
|
>
|
|
37
|
-
> - **分界点在 0.1.
|
|
38
|
-
> - **旧版为什么不能配新版 DSH**:旧版产物中的 `.d.ts` 仍引用已删除的 `@deepseek-ai/dsh-client-runtime/client`,在 v0.1.2+ 上做类型检查会解析失败。运行时 bundle 虽自包含,仍请一律升级到本版本。
|
|
37
|
+
> - **分界点在 0.1.5**:Session V3(surface node)、dockkit Sidebar 重写、Lexical composer 是 0.1.5 的结构性变更。本插件的三个 slot 锚点(`conversation.input.dock` / `conversation.input.right` / `settings.general.item`)在 0.1.5 全部保留,服务面(`send` / `cancel` / `updateQueue` / `blocks.set`)无破坏记录,因此代码零结构改动,仅收窄支持分段。
|
|
39
38
|
> - **队列条位置**:注册 `order: 1000`,排在 `conversation.input.dock` 带内所有已知条目(todo 0 / goal 10 / 官方 queue 20 / dsh-perm-gate 提示 30)之后,紧贴输入卡片。DSH 没有 "last" 语义,这是约定而非结构性保证——第三方插件若注册更大的 `order` 仍可能插到它下面。
|
|
40
39
|
|
|
40
|
+
> **▼ DSH 0.1.5 已知回归(宿主侧,非本插件 bug)**
|
|
41
|
+
>
|
|
42
|
+
> | 问题 | 对本插件的影响 | 讨论 |
|
|
43
|
+
> | --- | --- | --- |
|
|
44
|
+
> | fork 会话继承父会话「已入队未执行」的 prompt 并自动重跑 | 正是本插件管理的等待队列:fork 出的子会话可能重放父会话排队中的消息 | [#6314](https://github.com/deepseek-ai/deepseek-harness/discussions/6314) / [#6197](https://github.com/deepseek-ai/deepseek-harness/discussions/6197) |
|
|
45
|
+
> | composer 迁移 Lexical 后 IME 组合期 Enter 被当换行、浏览器翻译插件打崩输入框 | 影响「拉回编辑器回填草稿」与发送路径 | [#6231](https://github.com/deepseek-ai/deepseek-harness/discussions/6231) / [#6052](https://github.com/deepseek-ai/deepseek-harness/discussions/6052) |
|
|
46
|
+
> | 阻塞式工具等待期间 steer 无法抢占(最长约 10 分钟) | 黄色「下一轮插入」档位在该窗口不生效,用户可能误以为是插件问题 | [#6030](https://github.com/deepseek-ai/deepseek-harness/discussions/6030) |
|
|
47
|
+
> | 升级旧 profile 后 client combo 缓存陈旧,插件树整体不激活 | 排障第一步:**强制刷新浏览器(清缓存)**再排查 | [#5999](https://github.com/deepseek-ai/deepseek-harness/discussions/5999) / [#6374](https://github.com/deepseek-ai/deepseek-harness/discussions/6374) |
|
|
48
|
+
|
|
41
49
|
> **兼容性说明:** v0.2.9 已包含日语(`ja`)和韩语(`ko`)字典,但当前官方 DSH 只通过 `LocaleRuntime` 提供 `zh` 和 `en`。在原版 DSH 中选择 `ja` 或 `ko` 会失败,并提示 `locale "<id>" is not registered`。需要等待官方 DSH 增加对应 locale ID 后才能正常使用。高级用户可以维护 DSH fork,在 `packages/client/locale/src/locale-settings.ts` 更新 `LOCALE_IDS`,在 `packages/client/locale/src/client/index.ts` 更新 `LOCALES` 标签,并补齐核心字典和测试,然后重新构建并运行 fork 版本。仅修改本插件无法扩展 DSH 的全局 locale 列表。
|
|
42
50
|
|
|
43
51
|
> 智能体忙碌时不再只有"打断"或"排队"二选一:红色打断立即输入、黄色下一轮插入、绿色排队到最后,三档并存;邻近 DeepSeek 高峰收费时段可一键冻结会话,错峰再恢复继续。
|
package/dsh.plugin.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "dsh-external/dsh-input-traffic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"main": "./lib/index.js",
|
|
5
5
|
"description": "Busy-time input queue: three-tier planning, drag-to-reorder, interject/interrupt, batch clear, session freeze.",
|
|
6
6
|
"engines": {
|
|
7
|
-
"dsh": ">=0.1.
|
|
7
|
+
"dsh": ">=0.1.5-alpha.1 <0.2.0-0"
|
|
8
8
|
},
|
|
9
9
|
"contributes": {
|
|
10
10
|
"tools": [],
|
package/lib/client.js
CHANGED
|
@@ -215,42 +215,42 @@ window.__ModuleLoader__.load({
|
|
|
215
215
|
document.head.appendChild(tag);
|
|
216
216
|
}
|
|
217
217
|
var steer_queue_dock_module_css_default = {
|
|
218
|
-
"
|
|
219
|
-
"
|
|
220
|
-
"badgeNext": "FNESVa_badgeNext",
|
|
221
|
-
"plan": "FNESVa_plan",
|
|
222
|
-
"clear": "FNESVa_clear",
|
|
223
|
-
"badgeLater": "FNESVa_badgeLater",
|
|
224
|
-
"preview": "FNESVa_preview",
|
|
218
|
+
"lead": "FNESVa_lead",
|
|
219
|
+
"frozenRow": "FNESVa_frozenRow",
|
|
225
220
|
"actions": "FNESVa_actions",
|
|
221
|
+
"action": "FNESVa_action",
|
|
222
|
+
"panel": "FNESVa_panel",
|
|
223
|
+
"tierNow": "FNESVa_tierNow",
|
|
226
224
|
"tierLater": "FNESVa_tierLater",
|
|
227
|
-
"
|
|
228
|
-
"
|
|
229
|
-
"badge": "FNESVa_badge",
|
|
225
|
+
"tier": "FNESVa_tier",
|
|
226
|
+
"tierNext": "FNESVa_tierNext",
|
|
230
227
|
"steeringList": "FNESVa_steeringList",
|
|
231
|
-
"tierNow": "FNESVa_tierNow",
|
|
232
|
-
"frozenMark": "FNESVa_frozenMark",
|
|
233
|
-
"list": "FNESVa_list",
|
|
234
|
-
"count": "FNESVa_count",
|
|
235
|
-
"frozenRow": "FNESVa_frozenRow",
|
|
236
|
-
"badgeLabel": "FNESVa_badgeLabel",
|
|
237
228
|
"clearConfirm": "FNESVa_clearConfirm",
|
|
238
|
-
"editor": "FNESVa_editor",
|
|
239
229
|
"badgeNow": "FNESVa_badgeNow",
|
|
240
|
-
"
|
|
230
|
+
"clearLabel": "FNESVa_clearLabel",
|
|
231
|
+
"editor": "FNESVa_editor",
|
|
241
232
|
"chevron": "FNESVa_chevron",
|
|
242
|
-
"
|
|
233
|
+
"rowDragOver": "FNESVa_rowDragOver",
|
|
234
|
+
"clear": "FNESVa_clear",
|
|
235
|
+
"row": "FNESVa_row",
|
|
236
|
+
"badgeLater": "FNESVa_badgeLater",
|
|
237
|
+
"list": "FNESVa_list",
|
|
243
238
|
"frozenBanner": "FNESVa_frozenBanner",
|
|
244
|
-
"
|
|
245
|
-
"panel": "FNESVa_panel",
|
|
246
|
-
"lead": "FNESVa_lead",
|
|
239
|
+
"toolbar": "FNESVa_toolbar",
|
|
247
240
|
"toolbarActions": "FNESVa_toolbarActions",
|
|
248
|
-
"
|
|
249
|
-
"
|
|
241
|
+
"badgeNext": "FNESVa_badgeNext",
|
|
242
|
+
"count": "FNESVa_count",
|
|
243
|
+
"dock": "FNESVa_dock",
|
|
244
|
+
"freeze": "FNESVa_freeze",
|
|
245
|
+
"dot": "FNESVa_dot",
|
|
246
|
+
"preview": "FNESVa_preview",
|
|
247
|
+
"badgeLabel": "FNESVa_badgeLabel",
|
|
248
|
+
"badge": "FNESVa_badge",
|
|
249
|
+
"plan": "FNESVa_plan",
|
|
250
250
|
"clearCancel": "FNESVa_clearCancel",
|
|
251
|
-
"rowDragOver": "FNESVa_rowDragOver",
|
|
252
251
|
"frozenList": "FNESVa_frozenList",
|
|
253
|
-
"
|
|
252
|
+
"header": "FNESVa_header",
|
|
253
|
+
"frozenMark": "FNESVa_frozenMark"
|
|
254
254
|
};
|
|
255
255
|
//#endregion
|
|
256
256
|
//#region src/client/steer-queue-dock.tsx
|
|
@@ -1324,9 +1324,9 @@ window.__ModuleLoader__.load({
|
|
|
1324
1324
|
*
|
|
1325
1325
|
* List rows render sorted by `order` ascending, so a value above every other
|
|
1326
1326
|
* contributor keeps the strip as the bottom-most entry of the band — directly
|
|
1327
|
-
* on top of the composer card. Known contributors
|
|
1328
|
-
*
|
|
1329
|
-
*
|
|
1327
|
+
* on top of the composer card. Known contributors on 0.1.5-rc.2: `todo` 0,
|
|
1328
|
+
* `goal` 10, official `queue` 20, `dsh-perm-gate.notice` 30. DSH has no "last"
|
|
1329
|
+
* slot semantics, so this is a convention, not a
|
|
1330
1330
|
* structural guarantee: a third party registering a larger value could still
|
|
1331
1331
|
* land below us.
|
|
1332
1332
|
*/
|
package/lib/client.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","names":["useMemo","useState","useRef","useSyncExternalStore","useId","css","IconQueueOutline14","IconChevronDownOutline14","IconChevronUpOutline14","Tooltip","IconTrashOutline16","IconCheckOutline16","IconCloseOutline16","IconEditOutline16","IconRightUpOutline16","useSyncExternalStore","css"],"sources":["src/client/locales.ts","src/client/freeze-store.ts","src/client/steer-queue-dock.tsx","src/client/session-guard-bridge.ts","src/client/freeze-button.tsx","src/client/hide-enter-row.tsx","src/client/index.ts"],"sourcesContent":["/** `steer` client dictionaries (zh / en / ja / ko). */\n\n/** Dictionary namespace owned by this plugin. */\nexport const NS = 'steer'\n\n/** Simplified Chinese dictionary (the key-set source of truth). */\nexport const zh = {\n 'queue.count': '{n} 条排队消息',\n 'queue.edit': '编辑排队消息',\n 'queue.edit.unsupported': '包含非文本内容,暂不支持编辑',\n 'queue.save': '保存排队消息',\n 'queue.cancelEdit': '取消编辑',\n 'queue.remove': '删除排队消息',\n 'queue.removeFailed': '删除失败:这条消息可能已经开始发送。',\n 'queue.editFailed': '编辑失败:这条消息可能已经开始发送。',\n 'queue.editFailed.pulledBack': '编辑失败,内容已退回主输入框,请确认后重新发送。',\n 'steer.inflight': '{n} 条正在插入',\n 'steer.now': '打断并输入',\n 'steer.now.aria': '红色:打断当前动作并立即输入',\n 'steer.now.unsupported': '包含非文本内容,暂不支持打断',\n 'steer.nowFailed': '打断失败,请重试。',\n 'steer.next': '插话发送',\n 'steer.next.aria': '黄色:当前动作结束后插入输入',\n 'steer.nextFailed': '插话发送失败,请重试。',\n 'steer.later': '排队到下一轮',\n 'steer.later.aria': '绿色:排队,上一轮输入的动作都结束后再处理',\n 'steer.revoke': '收回排队',\n 'steer.revoke.aria': '绿色:撤销插入,收回排队(下一轮处理)',\n 'steer.revoke.unsupported': '包含非文本内容,暂不支持收回',\n 'steer.revokeFailed': '收回排队失败,请重试。',\n 'steer.moveUp': '上移',\n 'steer.moveDown': '下移',\n 'steer.reorder.unsupported': '包含非文本内容,暂不支持排序',\n 'steer.reorderFailed': '调整顺序失败,请重试。',\n 'steer.reorderStale': '队列已变化,本次排序已取消,请重试。',\n 'steer.dragReorder': '拖动调整顺序',\n 'steer.pullBack': '打回输入框编辑',\n 'steer.pullBack.unsupported': '包含非文本内容,暂不支持打回编辑',\n 'steer.pullBack.composerBusy': '主输入框已有内容,请先发送或清空后再打回',\n 'steer.pullBackFailed': '打回输入框失败,请重试。',\n 'steer.badge.now': '打断中',\n 'steer.badge.next': '插话中',\n 'steer.badge.later': '排队',\n 'steer.unavailable.running': '仅运行中可规划',\n 'steer.clear': '取消并清空',\n 'steer.clear.confirm': '确认清空?',\n 'steer.clear.cancel': '取消清空',\n 'steer.clear.aria': '取消当前执行并清空全部排队消息',\n 'steer.clearFailed': '取消并清空失败,请重试。',\n 'steer.freeze': '冻结追加',\n 'steer.resume': '恢复追加',\n 'steer.frozen': '已冻结:当前轮次完成后暂停,排队消息将在恢复后继续',\n 'steer.frozenInput': '已冻结:输入已暂停,恢复后继续',\n 'steer.frozenBadge': '已冻结',\n 'steer.freezeFailed': '冻结失败,请重试。',\n 'steer.resumeFailed': '恢复失败,请重试。',\n} satisfies Record<string, string>\n\n/** English dictionary (keys mirror zh). */\nexport const en: Record<keyof typeof zh, string> = {\n 'queue.count': '{n} queued messages',\n 'queue.edit': 'Edit queued message',\n 'queue.edit.unsupported': 'Contains non-text content; editing is unsupported',\n 'queue.save': 'Save queued message',\n 'queue.cancelEdit': 'Cancel edit',\n 'queue.remove': 'Remove queued message',\n 'queue.removeFailed': 'Remove failed: the message may have started sending.',\n 'queue.editFailed': 'Edit failed: the message may have started sending.',\n 'queue.editFailed.pulledBack': 'Edit failed; the content was moved back to the composer, please review and resend.',\n 'steer.inflight': '{n} inserting',\n 'steer.now': 'Interrupt and send',\n 'steer.now.aria': 'Red: interrupt the running action and send now',\n 'steer.now.unsupported': 'Contains non-text content; interrupting is unsupported',\n 'steer.nowFailed': 'Interrupt failed, please retry.',\n 'steer.next': 'Send after action',\n 'steer.next.aria': 'Yellow: insert after the current action finishes',\n 'steer.nextFailed': 'Steering failed, please retry.',\n 'steer.later': 'Queue for next turn',\n 'steer.later.aria': 'Green: queue; processed after all previously steered actions finish',\n 'steer.revoke': 'Pull back to queue',\n 'steer.revoke.aria': 'Green: revoke the insertion and queue for the next turn',\n 'steer.revoke.unsupported': 'Contains non-text content; revoking is unsupported',\n 'steer.revokeFailed': 'Revoke failed, please retry.',\n 'steer.moveUp': 'Move up',\n 'steer.moveDown': 'Move down',\n 'steer.reorder.unsupported': 'Contains non-text content; reordering is unsupported',\n 'steer.reorderFailed': 'Reorder failed, please retry.',\n 'steer.reorderStale': 'The queue changed; this reorder was cancelled, please retry.',\n 'steer.dragReorder': 'Drag to reorder',\n 'steer.pullBack': 'Edit in composer',\n 'steer.pullBack.unsupported': 'Contains non-text content; pulling back is unsupported',\n 'steer.pullBack.composerBusy': 'The composer already has content; send or clear it first',\n 'steer.pullBackFailed': 'Pull back failed, please retry.',\n 'steer.badge.now': 'interrupting',\n 'steer.badge.next': 'steering',\n 'steer.badge.later': 'queued',\n 'steer.unavailable.running': 'Planning requires a running session',\n 'steer.clear': 'Cancel and clear',\n 'steer.clear.confirm': 'Confirm clear?',\n 'steer.clear.cancel': 'Cancel clearing',\n 'steer.clear.aria': 'Cancel the current run and clear all queued messages',\n 'steer.clearFailed': 'Cancel and clear failed, please retry.',\n 'steer.freeze': 'Freeze & append',\n 'steer.resume': 'Resume & append',\n 'steer.frozen': 'Frozen: the current turn finishes, then the queue pauses until resumed',\n 'steer.frozenInput': 'Frozen: input paused, resume to continue',\n 'steer.frozenBadge': 'frozen',\n 'steer.freezeFailed': 'Freeze failed, please retry.',\n 'steer.resumeFailed': 'Resume failed, please retry.',\n}\n\n/** Japanese dictionary (keys mirror zh). */\nexport const ja: Record<keyof typeof zh, string> = {\n 'queue.count': '{n} 件のキューイング済みメッセージ',\n 'queue.edit': 'キューイング済みメッセージを編集',\n 'queue.edit.unsupported': '非テキストコンテンツが含まれており、編集はサポートされていません',\n 'queue.save': 'キューイング済みメッセージを保存',\n 'queue.cancelEdit': '編集をキャンセル',\n 'queue.remove': 'キューイング済みメッセージを削除',\n 'queue.removeFailed': '削除失敗:メッセージの送信が既に開始されている可能性があります。',\n 'queue.editFailed': '編集失敗:メッセージの送信が既に開始されている可能性があります。',\n 'queue.editFailed.pulledBack': '編集失敗。コンテンツはコンポーザに戻されました。確認後再送信してください。',\n 'steer.inflight': '{n} 件挿入中',\n 'steer.now': '中断して送信',\n 'steer.now.aria': '赤:実行中のアクションを中断して即座に送信',\n 'steer.now.unsupported': '非テキストコンテンツが含まれており、中断はサポートされていません',\n 'steer.nowFailed': '中断失敗。再試行してください。',\n 'steer.next': 'アクション後に送信',\n 'steer.next.aria': '黄:現在のアクション完了後に挿入',\n 'steer.nextFailed': 'ステア失敗。再試行してください。',\n 'steer.later': '次のターンまでキューイング',\n 'steer.later.aria': '緑:キューイング。以前のステア済みアクションがすべて完了してから処理',\n 'steer.revoke': 'キューに戻す',\n 'steer.revoke.aria': '緑:挿入を取り消し、次のターンまでキューイング',\n 'steer.revoke.unsupported': '非テキストコンテンツが含まれており、取り消しはサポートされていません',\n 'steer.revokeFailed': '取り消し失敗。再試行してください。',\n 'steer.moveUp': '上へ移動',\n 'steer.moveDown': '下へ移動',\n 'steer.reorder.unsupported': '非テキストコンテンツが含まれており、並べ替えはサポートされていません',\n 'steer.reorderFailed': '並べ替え失敗。再試行してください。',\n 'steer.reorderStale': 'キューが変更されました。本次の並べ替えはキャンセルされました。再試行してください。',\n 'steer.dragReorder': 'ドラッグして並べ替え',\n 'steer.pullBack': 'コンポーザに送り直して編集',\n 'steer.pullBack.unsupported': '非テキストコンテンツが含まれており、送り直しはサポートされていません',\n 'steer.pullBack.composerBusy': 'コンポーザに既にコンテンツがあります。送信またはクリアしてください',\n 'steer.pullBackFailed': '送り直し失敗。再試行してください。',\n 'steer.badge.now': '中断中',\n 'steer.badge.next': 'ステア中',\n 'steer.badge.later': 'キューイング済み',\n 'steer.unavailable.running': '実行中のみプランニング可能',\n 'steer.clear': '取り消して全消去',\n 'steer.clear.confirm': '消去を確認?',\n 'steer.clear.cancel': '消去をキャンセル',\n 'steer.clear.aria': '実行を停止し、すべてのキューイング済みメッセージを消去',\n 'steer.clearFailed': '取り消して全消去失敗。再試行してください。',\n 'steer.freeze': '凍結して追加',\n 'steer.resume': '再開して追加',\n 'steer.frozen': '凍結中:現在のターン完了後一時停止、再開後にキューが継続',\n 'steer.frozenInput': '凍結中:入力一時停止、再開後に継続',\n 'steer.frozenBadge': '凍結済み',\n 'steer.freezeFailed': '凍結失敗。再試行してください。',\n 'steer.resumeFailed': '再開失敗。再試行してください。',\n}\n\n/** Korean dictionary (keys mirror zh). */\nexport const ko: Record<keyof typeof zh, string> = {\n 'queue.count': '{n}개 대기열 메시지',\n 'queue.edit': '대기열 메시지 편집',\n 'queue.edit.unsupported': '비텍스트 콘텐츠가 포함되어 있어 편집이 지원되지 않습니다',\n 'queue.save': '대기열 메시지 저장',\n 'queue.cancelEdit': '편집 취소',\n 'queue.remove': '대기열 메시지 삭제',\n 'queue.removeFailed': '삭제 실패: 메시지 전송이 이미 시작되었을 수 있습니다.',\n 'queue.editFailed': '편집 실패: 메시지 전송이 이미 시작되었을 수 있습니다.',\n 'queue.editFailed.pulledBack': '편집 실패. 콘텐츠가 컴포저로 돌아갔습니다. 확인 후 다시 전송하세요.',\n 'steer.inflight': '{n}개 삽입 중',\n 'steer.now': '중단 후 전송',\n 'steer.now.aria': '빨간색: 실행 중인 액션을 중단하고 즉시 전송',\n 'steer.now.unsupported': '비텍스트 콘텐츠가 포함되어 있어 중단이 지원되지 않습니다',\n 'steer.nowFailed': '중단 실패. 다시 시도하세요.',\n 'steer.next': '액션 후 전송',\n 'steer.next.aria': '노란색: 현재 액션 완료 후 삽입',\n 'steer.nextFailed': '스티어 실패. 다시 시도하세요.',\n 'steer.later': '다음 턴까지 대기',\n 'steer.later.aria': '초록색: 대기. 이전 스티어된 액션이 모두 완료된 후 처리',\n 'steer.revoke': '대기열로 되돌리기',\n 'steer.revoke.aria': '초록색: 삽입 취소, 다음 턴까지 대기',\n 'steer.revoke.unsupported': '비텍스트 콘텐츠가 포함되어 있어 취소가 지원되지 않습니다',\n 'steer.revokeFailed': '취소 실패. 다시 시도하세요.',\n 'steer.moveUp': '위로 이동',\n 'steer.moveDown': '아래로 이동',\n 'steer.reorder.unsupported': '비텍스트 콘텐츠가 포함되어 있어 재정렬이 지원되지 않습니다',\n 'steer.reorderFailed': '재정렬 실패. 다시 시도하세요.',\n 'steer.reorderStale': '대기열이 변경되었습니다. 이번 재정렬이 취소되었습니다. 다시 시도하세요.',\n 'steer.dragReorder': '드래그로 재정렬',\n 'steer.pullBack': '컴포저로 되돌려 편집',\n 'steer.pullBack.unsupported': '비텍스트 콘텐츠가 포함되어 있어 되돌리기가 지원되지 않습니다',\n 'steer.pullBack.composerBusy': '컴포저에 이미 콘텐츠가 있습니다. 먼저 전송하거나 비우세요',\n 'steer.pullBackFailed': '되돌리기 실패. 다시 시도하세요.',\n 'steer.badge.now': '중단 중',\n 'steer.badge.next': '스티어 중',\n 'steer.badge.later': '대기열',\n 'steer.unavailable.running': '실행 중에만 계획 가능',\n 'steer.clear': '취소 후 전체 지우기',\n 'steer.clear.confirm': '지우기 확인?',\n 'steer.clear.cancel': '지우기 취소',\n 'steer.clear.aria': '현재 실행을 중지하고 모든 대기열 메시지를 지우기',\n 'steer.clearFailed': '취소 후 전체 지우기 실패. 다시 시도하세요.',\n 'steer.freeze': '동결 후 추가',\n 'steer.resume': '재개 후 추가',\n 'steer.frozen': '동결됨: 현재 턴 완료 후 일시정지, 재개 시 대기열 계속',\n 'steer.frozenInput': '동결됨: 입력 일시정지, 재개 시 계속',\n 'steer.frozenBadge': '동결됨',\n 'steer.freezeFailed': '동결 실패. 다시 시도하세요.',\n 'steer.resumeFailed': '재개 실패. 다시 시도하세요.',\n}\n\n/** Dictionary key union. */\nexport type SteerKey = keyof typeof zh\n","/**\n * Session-scoped freeze store shared by the composer freeze button (the\n * control) and the steering dock (the banner/disabled states).\n *\n * The queue is fully decoupled from freezing: freezing only stops the agent\n * from consuming the queue (the detached entries are preserved here so the\n * driver finds no pending work and stops). While frozen the entries stay\n * fully editable — text, order and the planned insertion tier (now/next/\n * later) can all change; resume re-submits the queue honoring those tiers.\n *\n * State is keyed by session id so freezing one session never leaks into\n * another: each session holds its own `frozen` flag and detached queue, and\n * mutating one session's queue only re-renders that session's consumers\n * (`useSyncExternalStore` bails on unchanged references for the others).\n */\n\n/** Insertion tier planned for one detached queued message. */\nexport type FrozenTier = 'queue' | 'safe_point' | 'force'\n\n/** One detached queued message with its planned insertion tier. */\nexport interface FrozenEntry {\n text: string\n tier: FrozenTier\n}\n\nexport interface FreezeState {\n frozen: boolean\n /** Detached queued messages in FIFO order, each with a planned tier. */\n pending: readonly FrozenEntry[]\n}\n\n/** Session id → per-session freeze state. */\nconst states = new Map<string, FreezeState>()\nconst listeners = new Set<() => void>()\n\n/** Stable empty snapshot: `useSyncExternalStore` needs a reference-stable\n * value for unset sessions so unchanged consumers never re-render. */\nconst EMPTY: FreezeState = { frozen: false, pending: [] }\n\n/** Minimal snapshot store (no runtime dependency, stable identity per mount). */\nexport const freezeStore = {\n /** Snapshot for one session; reference-stable until that session changes. */\n getSnapshot(sessionId: string): FreezeState {\n return states.get(sessionId) ?? EMPTY\n },\n subscribe(listener: () => void): () => void {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n },\n /** Replace one session's state; unset sessions fall back to EMPTY. */\n set(sessionId: string, next: FreezeState): void {\n if (next.frozen === false && next.pending.length === 0) {\n states.delete(sessionId)\n } else {\n states.set(sessionId, next)\n }\n emit()\n },\n}\n\n/** Reset all sessions (for tests). */\nexport function resetFreezeStore(): void {\n states.clear()\n emit()\n}\n\n/** Append one queued message while frozen (new input lands in the detached queue). */\nexport function pushPending(sessionId: string, text: string, tier: FrozenTier = 'queue'): void {\n const cur = states.get(sessionId) ?? EMPTY\n freezeStore.set(sessionId, { ...cur, pending: [...cur.pending, { text, tier }] })\n}\n\n/** Edit one detached queued message's text in place. */\nexport function updatePendingAt(sessionId: string, index: number, text: string): void {\n const pending = states.get(sessionId)?.pending\n if (pending === undefined) return\n const entry = pending[index]\n if (entry === undefined) return\n const next = [...pending]\n next[index] = { ...entry, text }\n freezeStore.set(sessionId, { frozen: true, pending: next })\n}\n\n/** Change one detached queued message's planned insertion tier. */\nexport function setTierAt(sessionId: string, index: number, tier: FrozenTier): void {\n const pending = states.get(sessionId)?.pending\n if (pending === undefined) return\n const entry = pending[index]\n if (entry === undefined) return\n const next = [...pending]\n next[index] = { ...entry, tier }\n freezeStore.set(sessionId, { frozen: true, pending: next })\n}\n\n/** Remove one detached queued message. */\nexport function removePendingAt(sessionId: string, index: number): void {\n const pending = states.get(sessionId)?.pending\n if (pending === undefined) return\n freezeStore.set(sessionId, { frozen: true, pending: pending.filter((_, i) => i !== index) })\n}\n\n/** Move one detached queued message to a new position (reorder while frozen). */\nexport function movePending(sessionId: string, from: number, to: number): void {\n if (from === to) return\n const pending = states.get(sessionId)?.pending\n if (pending === undefined) return\n const next = [...pending]\n const [moved] = next.splice(from, 1)\n if (moved === undefined) return\n next.splice(to, 0, moved)\n freezeStore.set(sessionId, { frozen: true, pending: next })\n}\n\nfunction emit(): void {\n for (const listener of listeners) listener()\n}\n","/**\r\n * Three-tier steering queue dock: the shadowing replacement for the official\r\n * `conversation.input.dock` entry (same cell id `queue`, priority -1, so the\r\n * lower priority wins and the official QueueDock never renders while this\r\n * plugin is mounted).\r\n *\r\n * Every queued row carries three planning buttons:\r\n * - green (later, the default state): the row already queues for the next\r\n * turn —plain Enter keeps feeding rows here; pressing green on a row that\r\n * was already steered (yellow) revokes the insertion and pulls it back to\r\n * later (the yellow flow is reversible);\r\n * - yellow (next): strict-steer the row into the running turn, consumed at\r\n * the next step boundary (after the current action finishes);\r\n * - red (now): cancel the running turn, then remove the row and re-send its\r\n * text as a fresh message —the re-send arms the harness wake latch (the\r\n * converged driver restarts) and the interrupted input is processed as the\r\n * next turn's input. A plain steer after cancel would re-insert a message\r\n * that is already pending in next-turn and the inbox rejects it.\r\n *\r\n * The toolbar also exposes a queue-level \"cancel and clear\" that stops the\r\n * current run and removes every queued row, plus a session-level\r\n * freeze/resume toggle for the peak-hour scenario: freeze stops the current\r\n * run while preserving the queue (keepInbox), resume re-arms the driver by\r\n * re-sending the first queued row so the preserved work continues.\r\n */\r\nimport { useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from 'react'\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\n// Type-only: the conversation slot/contract declarations (module augmentation\r\n// for the SlotMap and the session standard kit). No value import crosses the\r\n// plugin boundary.\r\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\r\nimport {\r\n IconCheckOutline16, IconChevronDownOutline14, IconChevronUpOutline14, IconCloseOutline16,\r\n IconEditOutline16, IconQueueOutline14, IconRightUpOutline16, IconTrashOutline16, Tooltip,\r\n} from '@deepseek-ai/dsh-client-ui-primitives'\r\nimport { freezeStore, setTierAt, updatePendingAt, removePendingAt, movePending } from './freeze-store.ts'\r\nimport css from './steer-queue-dock.module.css'\r\n\r\n/** One mutation accepted by the conversation queue verb. */\r\nexport type SteerQueueAction =\r\n | { kind: 'edit'; content: readonly { type: 'text'; text: string }[] }\r\n | { kind: 'remove' }\r\n | { kind: 'steer' }\r\n\r\n/** Busy marker for a whole-queue rebuild (reorder); locks every row action. */\r\nconst REORDER_MARK = '__reorder__'\r\n\r\n/** localStorage key for the manual collapse state (dsh-queue-plus parity). */\r\nconst COLLAPSE_KEY = 'dsh-input-traffic:collapsed'\r\n\r\n/** Queue operations injected by the session-scoped registration. */\r\nexport interface SteerQueueDockInjected {\r\n updateQueue: (itemId: string, action: SteerQueueAction) => Promise<void>\r\n /** Cancel the current turn while preserving the pending queue. */\r\n cancel: () => Promise<void>\r\n /** Re-send one plain-text message as a queued follow-up (the revoke path). */\r\n send: (text: string) => Promise<void>\r\n /** Steer one plain-text message into the session's next step (resume's safe_point tier). */\r\n sendSteer?: (text: string) => Promise<void>\r\n /** Back-fill the composer draft (the pull-back-to-composer edit path). */\r\n setDraft: (text: string) => void\r\n notify: (level: 'info' | 'error', text: string) => void\r\n /** Owning session id (for the dsh-session-guard bridge RPC). */\r\n sessionId?: string\r\n /** Raise/clear the composer block for the owning session (freeze keeps the\r\n * composer inert so Enter cannot leak into the conversation; absent on the\r\n * dock entry, only the freeze button injects it). */\r\n setComposerBlock?: (reason: string | undefined) => void\r\n}\r\n\r\n/** Full props of a dock entry: InputZone owner share + session standard kit + global seat + the locale seat. */\r\nexport type SteerQueueDockProps = PropsRuntime<'conversation.input.dock'> & SteerQueueDockInjected & PropsLocale<'steer'>\r\n\r\n/** The planning tier of one queued row. */\r\nexport type SteerTier = 'now' | 'next' | 'later'\r\n\r\n/**\r\n * Resolve the action sequence for one planning button press. Pure so the\r\n * button wiring and its tests share one truth.\r\n * @param tier - the pressed planning tier.\r\n * @returns the queue mutation (red re-uses a steer-shaped action for the\r\n * yellow branch; the red branch performs cancel + remove + resend instead).\r\n */\r\nexport function planActionFor(tier: SteerTier): { action: SteerQueueAction; interruptFirst: boolean } {\r\n if (tier === 'later') return { action: { kind: 'steer' }, interruptFirst: false }\r\n // Yellow steers only; red cancels the running turn first, then steers.\r\n return { action: { kind: 'steer' }, interruptFirst: tier === 'now' }\r\n}\r\n\r\n/**\r\n * Project the tier badge of one inbox row from its placement. Pure so the\r\n * row rendering and its tests share one truth.\r\n * @param placement - the inbox projection placement.\r\n * @returns the tier badge, or null for non-visible context rows.\r\n */\r\nexport function badgeFor(placement: 'queued' | 'steering' | 'context'): SteerTier | null {\r\n if (placement === 'steering') return 'next'\r\n if (placement === 'queued') return 'later'\r\n return null\r\n}\r\n\r\n/**\r\n * Auto-grow one edit textarea to its content. The CSS max-height caps the\r\n * growth; beyond it the textarea scrolls internally. Height is reset first so\r\n * shrink (deleting lines) also tracks the content.\r\n * @param el - the textarea to resize in place.\r\n */\r\nexport function resizeEditor(el: HTMLTextAreaElement): void {\r\n el.style.height = 'auto'\r\n el.style.height = `${el.scrollHeight}px`\r\n}\r\n\r\n/**\r\n * Queue strip with three-tier planning: one item renders directly; multiple\r\n * items default to a collapsible count header; an empty queue renders nothing.\r\n */\r\nexport function SteerQueueDock({ sessionId, useSession, input, updateQueue, cancel, send, setDraft, notify, t }: SteerQueueDockProps) {\r\n const inbox = useSession(s => s.queue)\r\n const queue = useMemo(() => inbox.filter(row => row.placement === 'queued'), [inbox])\r\n const steering = useMemo(() => inbox.filter(row => row.placement === 'steering'), [inbox])\r\n const running = useSession(s => s.running)\r\n const queueMutable = useSession(s => s.subagent === null)\r\n const [editing, setEditing] = useState<{ id: string; text: string } | null>(null)\r\n const [busy, setBusy] = useState<string | null>(null)\r\n const [clearing, setClearing] = useState(false)\r\n // Two-step clear confirmation: the first click arms the prompt, the second\r\n // executes; arming auto-reverts after a few seconds (no native confirm).\r\n const [confirmClear, setConfirmClear] = useState(false)\r\n const confirmTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\r\n // Drag-and-drop reorder source index and the current drop-target row.\r\n const dragIndex = useRef<number | null>(null)\r\n const [dragOver, setDragOver] = useState<number | null>(null)\r\n // Collapse state persists across mounts (dsh-queue-plus parity).\r\n const [collapsed, setCollapsed] = useState(() => {\r\n try {\r\n const v = localStorage.getItem(COLLAPSE_KEY)\r\n return v === null ? true : v === '1'\r\n } catch {\r\n return true\r\n }\r\n })\r\n // Session-level freeze lives in the composer-right control; the dock reads\r\n // the shared store for the banner and inert states. While frozen the\r\n // detached queue is rendered here (read-only) so the waiting area stays\r\n // visible — freezing only pauses the running behavior, it must not hide\r\n // the queued messages.\r\n const { frozen, pending: frozenPending } = useSyncExternalStore(\r\n freezeStore.subscribe,\r\n () => freezeStore.getSnapshot(sessionId ?? ''),\r\n )\r\n const sid = sessionId ?? ''\r\n const listId = useId()\r\n // The edit textarea; grown to its content on entry and on every input.\r\n const editorRef = useRef<HTMLTextAreaElement>(null)\r\n\r\n useEffect(() => {\r\n if (queue.length === 0 && !collapsed) setCollapsed(true)\r\n // Frozen-row edits use a `frozen:` id that never exists in the dsh queue;\r\n // skip the stale-check for them so the detached queue stays editable.\r\n if (editing !== null && !editing.id.startsWith('frozen:') && (!queueMutable || !queue.some(row => row.id === editing.id))) setEditing(null)\r\n }, [collapsed, editing, queue, queueMutable])\r\n\r\n // Persist the manual collapse state; clear the confirm timer on unmount.\r\n useEffect(() => {\r\n try {\r\n localStorage.setItem(COLLAPSE_KEY, collapsed ? '1' : '0')\r\n } catch {\r\n /* storage unavailable: in-memory only */\r\n }\r\n }, [collapsed])\r\n useEffect(() => () => {\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n }, [])\r\n\r\n // Grow the editor to its full content when a row enters edit mode.\r\n const editingId = editing?.id\r\n useEffect(() => {\r\n if (editingId === undefined) return\r\n const el = editorRef.current\r\n if (el !== null) resizeEditor(el)\r\n }, [editingId])\r\n\r\n // The dock stays mounted while the agent runs (the freeze entry must be\r\n // reachable before any message queues), while any row is pending, and while\r\n // the session is frozen (the detached queue stays visible).\r\n if (queue.length === 0 && steering.length === 0 && !running && !frozen) return null\r\n\r\n const interactionActive = queueMutable && (editing !== null || busy !== null || clearing)\r\n const expanded = !collapsed || interactionActive\r\n const listVisible = queue.length === 1 || expanded\r\n const planDisabled = !queueMutable || !running || frozen\r\n const nothingPending = queue.length === 0 && steering.length === 0\r\n // Reordering rebuilds the queue by re-sending texts; non-text rows cannot\r\n // be re-sent, so sorting is disabled while any such row is queued.\r\n const reorderUnsupported = queue.some(row => row.text === null)\r\n // Pull-back-to-composer is only offered when the composer draft is empty:\r\n // the pulled message back-fills the draft, so an occupied composer would be\r\n // overwritten. Steered (yellow/red) rows never offer it — once inserted,\r\n // they are not deeply re-edited.\r\n const composerEmpty = input.draft.trim() === ''\r\n\r\n const applyAction = async (\r\n itemId: string,\r\n action: SteerQueueAction,\r\n failure: string,\r\n ): Promise<boolean> => {\r\n setBusy(itemId)\r\n try {\r\n await updateQueue(itemId, action)\r\n return true\r\n } catch {\r\n notify('error', failure)\r\n return false\r\n } finally {\r\n setBusy(current => current === itemId ? null : current)\r\n }\r\n }\r\n\r\n const saveEdit = async (): Promise<void> => {\r\n if (editing === null || editing.text.trim() === '') return\r\n const itemId = editing.id\r\n const text = editing.text\r\n setBusy(itemId)\r\n try {\r\n await updateQueue(itemId, { kind: 'edit', content: [{ type: 'text', text }] })\r\n setEditing(null)\r\n } catch {\r\n // The edit failed (the agent may have claimed the row mid-edit): fall\r\n // back to the composer so the edited content is never lost. Only when\r\n // the composer is free — an occupied draft must not be overwritten.\r\n if (input.draft.trim() === '') {\r\n setDraft(text)\r\n setEditing(null)\r\n notify('error', t('queue.editFailed.pulledBack'))\r\n } else {\r\n notify('error', t('queue.editFailed'))\r\n }\r\n } finally {\r\n setBusy(current => current === itemId ? null : current)\r\n }\r\n }\r\n\r\n const steerRow = async (row: { id: string; text: string | null }, tier: Exclude<SteerTier, 'later'>): Promise<void> => {\r\n setBusy(row.id)\r\n try {\r\n if (tier === 'now') {\r\n // Interrupt, then re-submit: cancel stops the current run (keepInbox),\r\n // the row is removed so its identity cannot collide, and re-sending\r\n // the text arms the harness wake latch (the converged driver restarts\r\n // and processes it as the next turn's input). A plain steer after\r\n // cancel would re-insert a message already pending in next-turn and\r\n // the inbox rejects the duplicate.\r\n await cancel()\r\n await updateQueue(row.id, { kind: 'remove' })\r\n if (row.text !== null) await send(row.text)\r\n } else {\r\n await updateQueue(row.id, { kind: 'steer' })\r\n }\r\n } catch {\r\n notify('error', tier === 'now' ? t('steer.nowFailed') : t('steer.nextFailed'))\r\n } finally {\r\n setBusy(current => current === row.id ? null : current)\r\n }\r\n }\r\n\r\n /**\r\n * Revoke a steered (yellow) or interrupting (red) row back to later: remove\r\n * the admitted row and re-send its text as a queued follow-up, so it lands\r\n * in next-turn again (the yellow flow is reversible).\r\n */\r\n const revokeToLater = async (row: { id: string; text: string | null }): Promise<void> => {\r\n if (row.text === null) return\r\n setBusy(row.id)\r\n try {\r\n await updateQueue(row.id, { kind: 'remove' })\r\n await send(row.text)\r\n } catch {\r\n notify('error', t('steer.revokeFailed'))\r\n } finally {\r\n setBusy(current => current === row.id ? null : current)\r\n }\r\n }\r\n\r\n /**\r\n * Rebuild the queue in a new order: remove every queued row, then re-send\r\n * the texts sequentially so the agent's next-turn list matches the new\r\n * order. Concurrency protection (dsh-queue-plus parity): if a remove fails\r\n * with queue-item-not-found, the agent already claimed that row — the\r\n * rebuild stops immediately and nothing is re-sent, so the changed queue\r\n * is never scrambled.\r\n */\r\n const rebuildQueue = async (rows: readonly { id: string; text: string | null }[], next: readonly { id: string; text: string | null }[]): Promise<void> => {\r\n setBusy(REORDER_MARK)\r\n try {\r\n for (const row of rows) {\r\n try {\r\n await updateQueue(row.id, { kind: 'remove' })\r\n } catch (error) {\r\n if (error instanceof Error && error.message.includes('queue-item-not-found')) {\r\n notify('error', t('steer.reorderStale'))\r\n return\r\n }\r\n throw error\r\n }\r\n }\r\n for (const row of next) {\r\n if (row.text !== null) await send(row.text)\r\n }\r\n } catch {\r\n notify('error', t('steer.reorderFailed'))\r\n } finally {\r\n setBusy(null)\r\n }\r\n }\r\n\r\n /**\r\n * Move one queued row up/down in the FIFO order (arrow buttons).\r\n */\r\n const reorder = async (rowId: string, delta: -1 | 1): Promise<void> => {\r\n const rows = queue\r\n const index = rows.findIndex(row => row.id === rowId)\r\n const target = index + delta\r\n if (index < 0 || target < 0 || target >= rows.length) return\r\n const next = [...rows]\r\n const swapped = next[index] as typeof next[number]\r\n next[index] = next[target] as typeof next[number]\r\n next[target] = swapped\r\n if (next.some(row => row.text === null)) {\r\n notify('error', t('steer.reorder.unsupported'))\r\n return\r\n }\r\n await rebuildQueue(rows, next)\r\n }\r\n\r\n /**\r\n * Move one row to an absolute position (drag-and-drop drop handler).\r\n */\r\n const reorderTo = async (fromIndex: number, toIndex: number): Promise<void> => {\r\n if (fromIndex === toIndex) return\r\n const rows = queue\r\n if (rows[fromIndex] === undefined || rows[toIndex] === undefined) return\r\n const next = [...rows]\r\n const [moved] = next.splice(fromIndex, 1)\r\n if (moved === undefined) return\r\n next.splice(toIndex, 0, moved)\r\n if (next.some(row => row.text === null)) {\r\n notify('error', t('steer.reorder.unsupported'))\r\n return\r\n }\r\n await rebuildQueue(rows, next)\r\n }\r\n\r\n /** Arm or execute the two-step clear confirmation. */\r\n const armClear = (): void => {\r\n if (confirmClear) {\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n setConfirmClear(false)\r\n void clearAll()\r\n return\r\n }\r\n setConfirmClear(true)\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n confirmTimer.current = setTimeout(() => setConfirmClear(false), 3000)\r\n }\r\n\r\n /** Abort the armed clear confirmation (the explicit cancel button). */\r\n const cancelClear = (): void => {\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n setConfirmClear(false)\r\n }\r\n\r\n /** Save an in-place edit of one detached (frozen) queued message. */\r\n const saveFrozenEdit = async (index: number): Promise<void> => {\r\n if (editing === null) return\r\n const text = editing.text.trim()\r\n if (text === '') {\r\n setEditing(null)\r\n return\r\n }\r\n updatePendingAt(sid, index, text)\r\n setEditing(null)\r\n }\r\n\r\n /**\r\n * Pull one queued row back into the composer draft for editing: the text\r\n * back-fills the input box and the row leaves the queue; the user edits and\r\n * resubmits it as a fresh message.\r\n */\r\n const pullBackToComposer = async (row: { id: string; text: string | null }): Promise<void> => {\r\n if (row.text === null) return\r\n setDraft(row.text)\r\n setBusy(row.id)\r\n try {\r\n await updateQueue(row.id, { kind: 'remove' })\r\n } catch {\r\n notify('error', t('steer.pullBackFailed'))\r\n } finally {\r\n setBusy(current => current === row.id ? null : current)\r\n }\r\n }\r\n\r\n const clearAll = async (): Promise<void> => {\r\n setClearing(true)\r\n // Cancel the current run and clear every pending row (queued and\r\n // steering alike). Removal races the agent claiming rows;\r\n // item-not-found is a normal convergence and must not surface.\r\n const pending = [...queue, ...steering]\r\n try {\r\n await cancel()\r\n await Promise.all(pending.map(row =>\r\n updateQueue(row.id, { kind: 'remove' }).catch(() => undefined),\r\n ))\r\n } catch {\r\n notify('error', t('steer.clearFailed'))\r\n } finally {\r\n setClearing(false)\r\n }\r\n }\r\n\r\n return (\r\n <div className={css.dock} data-steer-dock=\"\">\r\n <div className={css.panel}>\r\n <div className={css.toolbar}>\r\n <button\r\n type=\"button\"\r\n className={css.header}\r\n aria-controls={listId}\r\n aria-expanded={expanded}\r\n disabled={queue.length <= 1 || interactionActive}\r\n onClick={() => { setCollapsed(value => !value) }}\r\n >\r\n <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>\r\n {queue.length > 0 && (\r\n <span className={css.count}>{t('queue.count', { n: queue.length })}</span>\r\n )}\r\n {queue.length > 1 && (\r\n <span className={css.chevron} aria-hidden>\r\n {expanded ? <IconChevronDownOutline14 /> : <IconChevronUpOutline14 />}\r\n </span>\r\n )}\r\n </button>\r\n <div className={css.toolbarActions}>\r\n {confirmClear && (\r\n <button\r\n type=\"button\"\r\n className={css.clearCancel}\r\n aria-label={t('steer.clear.cancel')}\r\n disabled={clearing || busy !== null || nothingPending}\r\n onClick={cancelClear}\r\n >\r\n <span className={css.clearLabel}>{t('steer.clear.cancel')}</span>\r\n </button>\r\n )}\r\n <Tooltip label={confirmClear ? t('steer.clear.confirm') : t('steer.clear')} side=\"top\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.clear} ${confirmClear ? css.clearConfirm : ''}`}\r\n aria-label={confirmClear ? t('steer.clear.confirm') : t('steer.clear')}\r\n disabled={clearing || busy !== null || nothingPending}\r\n onClick={armClear}\r\n >\r\n <IconTrashOutline16 size={14} />\r\n <span className={css.clearLabel}>{confirmClear ? t('steer.clear.confirm') : t('steer.clear')}</span>\r\n </button>\r\n </Tooltip>\r\n </div>\r\n </div>\r\n {frozen && (\r\n <div className={css.frozenBanner} role=\"status\">\r\n {t('steer.frozen')}\r\n </div>\r\n )}\r\n {/* While frozen the queue is detached into the shared store: render it\r\n here so the waiting area never disappears. The detached rows stay\r\n fully editable (edit / remove / reorder) — freezing only pauses\r\n the running behavior, it must not lock the queue. */}\r\n {frozen && frozenPending.length > 0 && (\r\n <ul className={css.frozenList} data-testid=\"frozen-list\">\r\n {frozenPending.map((entry, i) => {\r\n const editingFrozen = editing?.id === `frozen:${i}`\r\n const text = entry.text\r\n return (\r\n <li\r\n key={i}\r\n className={`${css.frozenRow} ${dragOver === i && frozen ? css.rowDragOver : ''}`}\r\n data-tier={entry.tier === 'force' ? 'now' : entry.tier === 'safe_point' ? 'next' : 'later'}\r\n data-editing={editingFrozen ? '' : undefined}\r\n draggable={!editingFrozen}\r\n title={!editingFrozen ? t('steer.dragReorder') : undefined}\r\n onDragStart={(event) => {\r\n if (editingFrozen) return\r\n dragIndex.current = i\r\n event.dataTransfer.effectAllowed = 'move'\r\n // Some engines only start HTML5 drag once data is set.\r\n event.dataTransfer.setData('text/plain', String(i))\r\n }}\r\n onDragOver={(event) => {\r\n if (dragIndex.current === null) return\r\n event.preventDefault()\r\n setDragOver(i)\r\n }}\r\n onDrop={(event) => {\r\n event.preventDefault()\r\n const from = dragIndex.current\r\n dragIndex.current = null\r\n setDragOver(null)\r\n if (from !== null) movePending(sid, from, i)\r\n }}\r\n onDragEnd={() => {\r\n dragIndex.current = null\r\n setDragOver(null)\r\n }}\r\n >\r\n <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>\r\n <SteerBadge tier={entry.tier === 'force' ? 'now' : entry.tier === 'safe_point' ? 'next' : 'later'} t={t} />\r\n {editingFrozen\r\n ? (\r\n <textarea\r\n ref={editorRef}\r\n autoFocus\r\n className={css.editor}\r\n aria-label={t('queue.edit')}\r\n rows={1}\r\n value={editing?.text ?? text}\r\n onChange={(event) => { setEditing({ id: `frozen:${i}`, text: event.currentTarget.value }) }}\r\n onInput={(event) => { resizeEditor(event.currentTarget) }}\r\n onKeyDown={(event) => {\r\n if (event.key === 'Escape') {\r\n setEditing(null)\r\n return\r\n }\r\n if (event.key === 'Enter' && !event.shiftKey && !event.nativeEvent.isComposing) {\r\n event.preventDefault()\r\n void saveFrozenEdit(i)\r\n }\r\n }}\r\n />\r\n )\r\n : <span className={css.preview}>{text}</span>}\r\n <div className={css.actions}>\r\n {editingFrozen ? (\r\n <>\r\n <Tooltip label={t('queue.save')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.save')}\r\n disabled={editing === null || editing.text.trim() === ''}\r\n onClick={() => { void saveFrozenEdit(i) }}\r\n >\r\n <IconCheckOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.cancelEdit')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.cancelEdit')}\r\n onClick={() => { setEditing(null) }}\r\n >\r\n <IconCloseOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n </>\r\n ) : (\r\n <>\r\n <Tooltip label={t('steer.moveUp')} side=\"bottom\" delayMs={500} disabled={i === 0}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveUp')}\r\n disabled={i === 0}\r\n onClick={() => movePending(sid, i, i - 1)}\r\n >\r\n <IconChevronUpOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.moveDown')} side=\"bottom\" delayMs={500} disabled={i === frozenPending.length - 1}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveDown')}\r\n disabled={i === frozenPending.length - 1}\r\n onClick={() => movePending(sid, i, i + 1)}\r\n >\r\n <IconChevronDownOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.edit')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.edit')}\r\n onClick={() => { setEditing({ id: `frozen:${i}`, text }) }}\r\n >\r\n <IconEditOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.remove')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.remove')}\r\n onClick={() => removePendingAt(sid, i)}\r\n >\r\n <IconTrashOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n {/* Planned insertion tier: freezing pauses consumption,\r\n it must not lock the tier planning of each row. */}\r\n <span className={css.plan} role=\"group\" aria-label={t('steer.later.aria')}>\r\n <Tooltip label={t('steer.now')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNow}`}\r\n aria-label={t('steer.now')}\r\n aria-pressed={entry.tier === 'force' || undefined}\r\n onClick={() => setTierAt(sid, i, 'force')}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.next')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNext}`}\r\n aria-label={t('steer.next')}\r\n aria-pressed={entry.tier === 'safe_point' || undefined}\r\n onClick={() => setTierAt(sid, i, 'safe_point')}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.later')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierLater}`}\r\n aria-label={t('steer.later')}\r\n aria-pressed={entry.tier === 'queue' || undefined}\r\n onClick={() => setTierAt(sid, i, 'queue')}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n </span>\r\n </>\r\n )}\r\n </div>\r\n <span className={css.frozenMark}>{t('steer.frozenBadge')}</span>\r\n </li>\r\n )\r\n })}\r\n </ul>\r\n )}\r\n <ul id={listId} className={css.list} hidden={!listVisible}>\r\n {listVisible && queue.map((row, index) => (\r\n <li\r\n key={row.id}\r\n className={`${css.row} ${dragOver === index ? css.rowDragOver : ''}`}\r\n data-tier={badgeFor('queued') ?? undefined}\r\n data-editing={editing?.id === row.id ? '' : undefined}\r\n draggable={queueMutable && !reorderUnsupported && busy === null && !frozen}\r\n title={queueMutable && !reorderUnsupported && busy === null && !frozen ? t('steer.dragReorder') : undefined}\r\n onDragStart={(event) => {\r\n dragIndex.current = index\r\n event.dataTransfer.effectAllowed = 'move'\r\n // Some engines only start HTML5 drag once data is set.\r\n event.dataTransfer.setData('text/plain', String(index))\r\n }}\r\n onDragOver={(event) => {\r\n if (dragIndex.current === null) return\r\n event.preventDefault()\r\n setDragOver(index)\r\n }}\r\n onDrop={(event) => {\r\n event.preventDefault()\r\n const from = dragIndex.current\r\n dragIndex.current = null\r\n setDragOver(null)\r\n if (from !== null) void reorderTo(from, index)\r\n }}\r\n onDragEnd={() => {\r\n dragIndex.current = null\r\n setDragOver(null)\r\n }}\r\n >\r\n {queue.length === 1 && <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>}\r\n <SteerBadge tier={badgeFor('queued')} t={t} />\r\n {editing?.id === row.id\r\n ? (\r\n <textarea\r\n ref={editorRef}\r\n autoFocus\r\n className={css.editor}\r\n aria-label={t('queue.edit')}\r\n rows={1}\r\n value={editing.text}\r\n onChange={(event) => { setEditing({ id: row.id, text: event.currentTarget.value }) }}\r\n onInput={(event) => { resizeEditor(event.currentTarget) }}\r\n onKeyDown={(event) => {\r\n if (event.key === 'Escape') {\r\n setEditing(null)\r\n return\r\n }\r\n // Plain Enter saves; Shift+Enter keeps editing (newline).\r\n if (event.key === 'Enter' && !event.shiftKey && !event.nativeEvent.isComposing) {\r\n event.preventDefault()\r\n void saveEdit()\r\n }\r\n }}\r\n />\r\n )\r\n : <span className={css.preview}>{row.preview}</span>}\r\n {queueMutable && <div className={css.actions}>\r\n {editing?.id === row.id\r\n ? (\r\n <>\r\n <Tooltip label={t('queue.save')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.save')}\r\n disabled={busy !== null || editing.text.trim() === ''}\r\n onClick={() => { void saveEdit() }}\r\n >\r\n <IconCheckOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.cancelEdit')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.cancelEdit')}\r\n disabled={busy !== null}\r\n onClick={() => { setEditing(null) }}\r\n >\r\n <IconCloseOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n </>\r\n )\r\n : (\r\n <>\r\n <Tooltip label={t('steer.moveUp')} side=\"bottom\" delayMs={500} disabled={frozen || reorderUnsupported}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveUp')}\r\n title={reorderUnsupported ? t('steer.reorder.unsupported') : undefined}\r\n disabled={busy !== null || frozen || reorderUnsupported}\r\n onClick={() => { void reorder(row.id, -1) }}\r\n >\r\n <IconChevronUpOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.moveDown')} side=\"bottom\" delayMs={500} disabled={frozen || reorderUnsupported}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveDown')}\r\n title={reorderUnsupported ? t('steer.reorder.unsupported') : undefined}\r\n disabled={busy !== null || frozen || reorderUnsupported}\r\n onClick={() => { void reorder(row.id, 1) }}\r\n >\r\n <IconChevronDownOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.pullBack')} side=\"bottom\" delayMs={500} disabled={row.text === null || !composerEmpty}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.pullBack')}\r\n title={row.text === null ? t('steer.pullBack.unsupported') : !composerEmpty ? t('steer.pullBack.composerBusy') : undefined}\r\n disabled={busy !== null || frozen || row.text === null || !composerEmpty}\r\n onClick={() => { void pullBackToComposer(row) }}\r\n >\r\n <IconRightUpOutline16 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.edit')} side=\"bottom\" delayMs={500} disabled={row.text === null}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.edit')}\r\n title={row.text === null ? t('queue.edit.unsupported') : undefined}\r\n disabled={busy !== null || row.text === null}\r\n onClick={() => {\r\n if (row.text !== null) setEditing({ id: row.id, text: row.text })\r\n }}\r\n >\r\n <IconEditOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.remove')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.remove')}\r\n disabled={busy !== null}\r\n onClick={() => {\r\n void applyAction(row.id, { kind: 'remove' }, t('queue.removeFailed'))\r\n }}\r\n >\r\n <IconTrashOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <span className={css.plan} role=\"group\" aria-label={t('steer.later.aria')}>\r\n <Tooltip label={t('steer.now')} side=\"bottom\" delayMs={500} disabled={planDisabled || row.text === null}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNow}`}\r\n aria-label={t('steer.now')}\r\n title={planDisabled ? t('steer.unavailable.running') : row.text === null ? t('steer.now.unsupported') : undefined}\r\n disabled={busy !== null || planDisabled || row.text === null}\r\n onClick={() => { void steerRow(row, 'now') }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.next')} side=\"bottom\" delayMs={500} disabled={planDisabled}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNext}`}\r\n aria-label={t('steer.next')}\r\n title={planDisabled ? t('steer.unavailable.running') : undefined}\r\n disabled={busy !== null || planDisabled}\r\n onClick={() => { void steerRow(row, 'next') }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.later')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierLater}`}\r\n aria-label={t('steer.later')}\r\n aria-pressed\r\n disabled={busy !== null || clearing}\r\n onClick={() => {\r\n // Later is the default queue state; pressing it\r\n // keeps the row queued (no-op by design).\r\n }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n </span>\r\n </>\r\n )}\r\n </div>}\r\n </li>\r\n ))}\r\n </ul>\r\n {steering.length > 0 && (\r\n <ul className={css.steeringList} data-steering-list=\"\">\r\n {steering.map(row => (\r\n <li key={row.id} className={css.row} data-tier={badgeFor('steering') ?? undefined}>\r\n <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>\r\n <SteerBadge tier={badgeFor('steering')} t={t} />\r\n <span className={css.preview}>{row.preview}</span>\r\n <div className={css.actions}>\r\n <Tooltip label={t('steer.revoke')} side=\"bottom\" delayMs={500} disabled={row.text === null}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierLater}`}\r\n aria-label={t('steer.revoke')}\r\n title={row.text === null ? t('steer.revoke.unsupported') : undefined}\r\n disabled={busy !== null || row.text === null || frozen}\r\n onClick={() => { void revokeToLater(row) }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n </div>\r\n </li>\r\n ))}\r\n </ul>\r\n )}\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\n/** Badge label keys per tier. */\r\nconst BADGE_KEYS: Record<SteerTier, string> = {\r\n now: 'steer.badge.now',\r\n next: 'steer.badge.next',\r\n later: 'steer.badge.later',\r\n}\r\n\r\n/** Badge tint classes per tier (present at bundle time; typed through the css-modules declaration). */\r\nconst BADGE_CLASSES: Record<SteerTier, string> = {\r\n now: css.badgeNow as string,\r\n next: css.badgeNext as string,\r\n later: css.badgeLater as string,\r\n}\r\n\r\n/** One row's tier badge: colored dot + label; context rows render nothing. */\r\nfunction SteerBadge({ tier, t }: { tier: SteerTier | null; t: SteerQueueDockProps['t'] }) {\r\n if (tier === null) return null\r\n return (\r\n <span className={`${css.badge} ${BADGE_CLASSES[tier]}`} data-badge={tier}>\r\n <span className={css.dot} aria-hidden />\r\n <span className={css.badgeLabel}>{t(BADGE_KEYS[tier])}</span>\r\n </span>\r\n )\r\n}\r\n","/**\r\n * input-traffic ↔ dsh-session-guard 透传桥(D8 fail-open)。\r\n *\r\n * input-traffic **只做冻结增强**(队列冻结/解冻),服务端会话门(暂停/恢复会话)\r\n * 归 dsh-session-guard 插件。冻结/解冻按钮触发时,尽力调用\r\n * `sessionGuard.stopNextTurn` / `resume`;**插件未装**(路由 404 / 网络失败 /\r\n * 返回错误)→ 静默跳过,**绝不报错**,前端冻结仍正常生效。\r\n *\r\n * 不吸收任何 auto-continue / 重试逻辑(重试归后端 dsh-session-guard,D9)。\r\n */\r\n\r\n/** 尽力调用 sessionGuard.stopNextTurn(停掉 session 下一回合)。失败静默。 */\r\nexport async function sessionGuardStopNextTurn(sessionId: string): Promise<boolean> {\r\n return callGuard(sessionId, 'stopNextTurn')\r\n}\r\n\r\n/** 尽力调用 sessionGuard.resume。失败静默。 */\r\nexport async function sessionGuardResume(sessionId: string): Promise<boolean> {\r\n return callGuard(sessionId, 'resume')\r\n}\r\n\r\nasync function callGuard(sessionId: string, action: string): Promise<boolean> {\r\n try {\r\n const res = await fetch('/session-guard/rpc', {\r\n method: 'POST',\r\n headers: { 'content-type': 'application/json' },\r\n body: JSON.stringify({ sessionId, action }),\r\n })\r\n if (!res.ok) return false\r\n const body = await res.json().catch(() => null)\r\n return body?.ok === true\r\n } catch {\r\n // 路由不存在(session-guard 未装)/ 网络失败 → fail-open。\r\n return false\r\n }\r\n}\r\n\r\n// 探测标记:session-guard 客户端据此跳过自带的回退冻结按钮(避免双按钮/占位)。\r\n// 在 bundle 顶层执行;input-traffic 桥存在即置位。\r\ndeclare global {\r\n // eslint-disable-next-line no-var\r\n var __DSH_SESSION_GUARD_BRIDGE__: boolean | undefined\r\n}\r\ntry {\r\n globalThis.__DSH_SESSION_GUARD_BRIDGE__ = true\r\n} catch {\r\n /* 浏览器环境无 window 时忽略 */\r\n}\r\n","/**\r\n * Session freeze/resume control, mounted in the composer's right tool row\r\n * (`conversation.input.right`) so it is reachable before anything queues.\r\n *\r\n * Peak-hour pause semantics: freeze does NOT interrupt the running turn —it\r\n * finishes naturally. The queued messages are detached (removed, preserved in\r\n * the shared store), so the driver finds no pending work and stops after the\r\n * current turn. Resume re-submits the preserved texts, waking the driver and\r\n * continuing the queue.\r\n *\r\n * dsh-session-guard 协作(D8 fail-open):\r\n * - 冻结 = 前端摘队列(本插件)+ composer block(阻止新输入漏进对话) + 尽力调服务端\r\n * sessionGuard.stopNextTurn(停掉 session 下一回合;session-guard 未装时静默跳过)。\r\n * - 解冻 = 清 composer block + **先** await sessionGuard.resume(让被打断回合的自然\r\n * 下一步先发生),**再**重投队列(later 级条目因此排在自然 next turn 之后,不再插队)。\r\n * - 本插件只做冻结增强,不承担重试/暂停决策(归后端,D9)。\r\n */\r\nimport { useSyncExternalStore } from 'react'\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\r\nimport { freezeStore } from './freeze-store.ts'\r\nimport type { FrozenTier } from './freeze-store.ts'\r\nimport type { SteerQueueDockInjected } from './steer-queue-dock.tsx'\r\nimport { sessionGuardResume, sessionGuardStopNextTurn } from './session-guard-bridge.ts'\r\nimport css from './freeze-button.module.css'\r\n\r\n/**\r\n * Full props of the composer-right entry.\r\n *\r\n * DUAL-VERSION: 0.1.1 delivers the `InputZone` owner share here, 0.1.2 renders\r\n * the slot with `{}` (`InputBar.tsx:466`). Only the session standard kit is\r\n * shared, so the type declares exactly that — reading `session`/`input` off\r\n * this slot is a compile error, not a 0.1.2 crash.\r\n */\r\nexport type FreezeButtonProps =\r\n Pick<PropsRuntime<'conversation.input.right'>, 'useSession' | 'sessionId'>\r\n & SteerQueueDockInjected\r\n & PropsLocale<'steer'>\r\n\r\n/**\r\n * Freeze/resume toggle for the peak-hour scenario.\r\n * @param props - slot props; the session snapshot drives the detach list.\r\n */\r\nexport function FreezeButton({ useSession, updateQueue, cancel, send, sendSteer, sessionId, setComposerBlock, notify, t }: FreezeButtonProps) {\r\n // The freeze store is keyed by session: read the owning session's snapshot.\r\n const sid = sessionId ?? ''\r\n const { frozen } = useSyncExternalStore(freezeStore.subscribe, () => freezeStore.getSnapshot(sid))\r\n const queue = useSession(s => s.queue)\r\n\r\n const freeze = async (): Promise<void> => {\r\n // Detach every pending input row — queued (next-turn) and already-steered\r\n // (next-step) alike — so nothing stays in the live queue while frozen.\r\n // Steered rows keep their next intent as a safe_point plan for resume.\r\n const rows = queue.filter(row => row.placement === 'queued' || row.placement === 'steering')\r\n // Preserve plain-text copies; non-text rows cannot be re-sent and are\r\n // released by the freeze (documented limitation).\r\n const pending: { text: string; tier: FrozenTier }[] = rows.flatMap(row =>\r\n row.text === null ? [] : [{ text: row.text, tier: row.placement === 'steering' ? 'safe_point' : 'queue' }],\r\n )\r\n // Detach every pending row: the running turn finishes naturally, then the\r\n // driver finds no pending work and stops.\r\n await Promise.all(rows.map(row =>\r\n updateQueue(row.id, { kind: 'remove' }).catch(() => undefined),\r\n ))\r\n freezeStore.set(sid, { frozen: true, pending })\r\n // Raise the composer block: while frozen the composer is inert, so plain\r\n // Enter can never leak a new message into the conversation (busyEnter\r\n // only gates busy sessions; an idle/paused session would send directly).\r\n setComposerBlock?.(t('steer.frozenInput'))\r\n // 服务端:停掉 session 下一回合(fail-open,session-guard 未装则静默)。\r\n if (sessionId !== undefined) void sessionGuardStopNextTurn(sessionId)\r\n }\r\n\r\n const resume = async (): Promise<void> => {\r\n const pending = freezeStore.getSnapshot(sid).pending\r\n freezeStore.set(sid, { frozen: false, pending: [] })\r\n setComposerBlock?.(undefined)\r\n try {\r\n // 先恢复服务端会话:被打断回合的自然下一步(deferredTools 续跑)先发生。\r\n // 之后再重投队列 —— later 级条目经 send 进入 next-turn,排在自然 next turn\r\n // 之后;safe_point/force 仍按各自语义插队。顺序倒置会让 later 抢在自然\r\n // next turn 前被消费(idle 态 send 立即唤醒新回合)。\r\n if (sessionId !== undefined) await sessionGuardResume(sessionId)\r\n // Re-submit the preserved queue in FIFO order honoring each entry's\r\n // planned insertion tier: force (red) interrupts the current run first,\r\n // safe_point (yellow) steers into the next step, queue (green) flows\r\n // through the wake-and-continue chain.\r\n for (const entry of pending) {\r\n if (entry.tier === 'force') await cancel()\r\n if (entry.tier === 'safe_point' && sendSteer !== undefined) await sendSteer(entry.text)\r\n else await send(entry.text)\r\n }\r\n } catch {\r\n notify('error', t('steer.resumeFailed'))\r\n }\r\n }\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n className={css.freeze}\r\n aria-label={frozen ? t('steer.resume') : t('steer.freeze')}\r\n aria-pressed={frozen || undefined}\r\n title={frozen ? t('steer.frozen') : undefined}\r\n onClick={() => {\r\n if (frozen) void resume()\r\n else void freeze()\r\n }}\r\n >\r\n <span className={css.label}>{frozen ? t('steer.resume') : t('steer.freeze')}</span>\r\n </button>\r\n )\r\n}\r\n","/**\r\n * Busy-Enter row hiding: shadows the official `settings.general.item` entry\r\n * `composer-enter` (same cell id, priority -1) so the lower priority wins and\r\n * the official \"繁忙时 Enter 键行为\" row never renders while this plugin is\r\n * mounted.\r\n *\r\n * The behavior itself is taken over by the plugin: plain Enter stays\r\n * queue-later (green), the planning dock owns yellow/red, and the plugin apply\r\n * pins `ui-conversation.busyEnter` to `queue` so no stale preference can\r\n * leak through the hidden row.\r\n */\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\r\n\r\n/** Full props of a settings-row entry (unused: the row renders nothing). */\r\nexport type HideEnterRowProps = PropsRuntime<'settings.general.item'> & PropsLocale<'steer'>\r\n\r\n/** Render nothing: the official busy-Enter row is hidden while mounted. */\r\nexport function HideEnterRow(_props: HideEnterRowProps): null {\r\n return null\r\n}\r\n","/**\r\n * dsh-input-traffic —browser half.\r\n *\r\n * The whole takeover lives here:\r\n * 1. registers the `steer` dictionaries;\r\n * 2. pins `ui-conversation.busyEnter` to `queue` (plain Enter = green later)\r\n * so the hidden official row cannot leak a stale queue/steer preference;\r\n * 3. shadows the official queue dock (`conversation.input.dock` cell id\r\n * `queue`, priority -1) with the three-tier planning strip;\r\n * 4. shadows the official busy-Enter settings row (`settings.general.item`\r\n * cell id `composer-enter`, priority -1) with a null render.\r\n *\r\n * ORDERING (why the dock registers at QUEUE_DOCK_ORDER instead of the\r\n * official dock's 20): a list slot's DISPLAY position is decided by `order`\r\n * alone — `ui-renderer/src/client/scoped-slots.tsx` maps the shadowing\r\n * winners to rows and then sorts them by `order` (both 0.1.1 and 0.1.2) —\r\n * while `priority` only decides which entry wins a shared cell id. Keeping\r\n * the official 20 therefore left the strip above any later contributor\r\n * (dsh-perm-gate's notice registers order 30), which pushed that notice\r\n * between the queue strip and the composer card. A deliberately high order\r\n * keeps the strip adjacent to the card; priority stays -1 so the cell\r\n * takeover still holds.\r\n *\r\n * All @deepseek-ai/* imports are type-only: collaboration happens through\r\n * cordis services and slot registration only (client bundle purity).\r\n */\r\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\r\nimport type { SessionId } from '@deepseek-ai/dsh-session/types'\r\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\r\nimport { NS, en, zh } from './locales.ts'\r\nimport { SteerQueueDock } from './steer-queue-dock.tsx'\r\nimport type { SteerQueueDockInjected } from './steer-queue-dock.tsx'\r\nimport { FreezeButton } from './freeze-button.tsx'\r\nimport { HideEnterRow } from './hide-enter-row.tsx'\r\n\r\n/** Durable conversation settings namespace owned by ui-conversation. */\r\nconst CONVERSATION_SETTINGS_NAMESPACE = 'ui-conversation'\r\n\r\n/** Busy-Enter field inside that namespace; the plugin pins it to queue. */\r\nconst BUSY_ENTER_FIELD = 'busyEnter'\r\n\r\n/**\r\n * Display order of the queue strip inside `conversation.input.dock`.\r\n *\r\n * List rows render sorted by `order` ascending, so a value above every other\r\n * contributor keeps the strip as the bottom-most entry of the band — directly\r\n * on top of the composer card. Known contributors in both 0.1.1-rc.2 and\r\n * 0.1.2-rc.1: `todo` 0, `goal` 10, official `queue` 20, `dsh-perm-gate.notice`\r\n * 30. DSH has no \"last\" slot semantics, so this is a convention, not a\r\n * structural guarantee: a third party registering a larger value could still\r\n * land below us.\r\n */\r\nexport const QUEUE_DOCK_ORDER = 1000\r\n\r\n/**\r\n * Deliver one plain-text message into the session's next step. The exposed\r\n * conversation `send` verb only queues into the next turn, so resume steers\r\n * through the session face's steer-mode prompt instead (no harness change).\r\n * @param ctx - root context (resolves the session face behind the scope).\r\n * @param actx - agent-scoped context of the owning session.\r\n * @param text - message text to deliver.\r\n */\r\nfunction steerPrompt(actx: ClientContext, text: string): Promise<void> {\r\n // steer-mode prompt 面在本版(main@0.2.8)契约中未声明;resume 落到 conversation.send\r\n // (排队到下一轮)交付 safe_point 文本,与 feature 分支语义对齐但取当前可用 API。\r\n const conversation = actx.get('conversation')\r\n if (conversation === undefined) return Promise.reject(new Error('steer resume: conversation service unavailable'))\r\n return conversation.send(text)\r\n}\r\n\r\n/** Services required by the browser half. */\r\nexport const inject = ['slots', 'locale', 'sessions', 'conversation', 'settingsScope']\r\n\r\n/**\r\n * Client plugin body: dictionaries, busy-Enter pinning, and the two slot\r\n * shadowings.\r\n * @param ctx - client root context.\r\n */\r\nexport function apply(ctx: ClientContext): void {\r\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-input-traffic: dictionaries')\r\n\r\n // Take over the busy-Enter behavior: plain Enter stays queue-later while\r\n // the official row is hidden. Pinning here also repairs a persisted `steer`\r\n // preference that would otherwise keep working invisibly behind the hidden\r\n // row. Best-effort: a memory-mode host simply accepts it locally.\r\n const conversationSettings = ctx.settingsScope.bind<{ busyEnter: 'queue' | 'steer' }>({\r\n namespace: CONVERSATION_SETTINGS_NAMESPACE,\r\n })\r\n void conversationSettings.set(BUSY_ENTER_FIELD, 'queue')\r\n\r\n // Shadow the official queue dock with the three-tier planning strip. The\r\n // high `order` keeps it the bottom-most entry of the band (see the file\r\n // header); `priority: -1` is what wins the official `queue` cell.\r\n ctx.slots.inject('conversation.input.dock', () => ctx.slots.register({\r\n name: 'conversation.input.dock',\r\n id: 'queue',\r\n order: QUEUE_DOCK_ORDER,\r\n priority: -1,\r\n locale: NS,\r\n inject: (sessionId: SessionId): SteerQueueDockInjected => {\r\n const actx = ctx.sessions.scope(sessionId)\r\n if (actx === undefined) throw new Error(`steer dock: session \"${sessionId}\" resolved no scope`)\r\n const conversation = actx.get('conversation')\r\n if (conversation === undefined) throw new Error('steer dock: conversation service unavailable')\r\n return {\r\n updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),\r\n cancel: () => conversation.cancel(),\r\n send: (text) => conversation.send(text),\r\n setDraft: (text) => { conversation.input.for(actx).actions.setDraft(text) },\r\n notify: (level, text) => { conversation.input.for(actx).notify(level, text) },\r\n }\r\n },\r\n }, SteerQueueDock))\r\n\r\n // Composer-right freeze/resume control (reachable before anything queues).\r\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\r\n name: 'conversation.input.right',\r\n id: 'steer-freeze',\r\n order: 30,\r\n locale: NS,\r\n inject: (sessionId: SessionId): SteerQueueDockInjected => {\r\n const actx = ctx.sessions.scope(sessionId)\r\n if (actx === undefined) throw new Error(`steer freeze: session \"${sessionId}\" resolved no scope`)\r\n const conversation = actx.get('conversation')\r\n if (conversation === undefined) throw new Error('steer freeze: conversation service unavailable')\r\n return {\r\n updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),\r\n cancel: () => conversation.cancel(),\r\n send: (text) => conversation.send(text),\r\n // safe_point 恢复经 conversation.send 排队到下一轮(本版契约无 steer prompt 面)。\r\n sendSteer: (text) => steerPrompt(actx, text),\r\n sessionId: String(sessionId),\r\n setDraft: (text) => { conversation.input.for(actx).actions.setDraft(text) },\r\n notify: (level, text) => { conversation.input.for(actx).notify(level, text) },\r\n // 冻结期间 raise composer block:composer 变 inert(回车/发送按钮全部失效),\r\n // 输入不会漏进对话;恢复时清除。block 不锁 input.right(恢复按钮仍可点)。\r\n setComposerBlock: (reason) => {\r\n conversation.blocks.set(sessionId, reason === undefined ? undefined : { reason })\r\n },\r\n }\r\n },\r\n }, FreezeButton))\r\n\r\n // Hide the official busy-Enter settings row (null render wins the cell).\r\n ctx.slots.inject('settings.general.item', () => ctx.slots.register({\r\n name: 'settings.general.item',\r\n id: 'composer-enter',\r\n order: 20,\r\n priority: -1,\r\n locale: NS,\r\n }, HideEnterRow))\r\n}\r\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"client.js","names":["useMemo","useState","useRef","useSyncExternalStore","useId","css","IconQueueOutline14","IconChevronDownOutline14","IconChevronUpOutline14","Tooltip","IconTrashOutline16","IconCheckOutline16","IconCloseOutline16","IconEditOutline16","IconRightUpOutline16","useSyncExternalStore","css"],"sources":["src/client/locales.ts","src/client/freeze-store.ts","src/client/steer-queue-dock.tsx","src/client/session-guard-bridge.ts","src/client/freeze-button.tsx","src/client/hide-enter-row.tsx","src/client/index.ts"],"sourcesContent":["/** `steer` client dictionaries (zh / en / ja / ko). */\n\n/** Dictionary namespace owned by this plugin. */\nexport const NS = 'steer'\n\n/** Simplified Chinese dictionary (the key-set source of truth). */\nexport const zh = {\n 'queue.count': '{n} 条排队消息',\n 'queue.edit': '编辑排队消息',\n 'queue.edit.unsupported': '包含非文本内容,暂不支持编辑',\n 'queue.save': '保存排队消息',\n 'queue.cancelEdit': '取消编辑',\n 'queue.remove': '删除排队消息',\n 'queue.removeFailed': '删除失败:这条消息可能已经开始发送。',\n 'queue.editFailed': '编辑失败:这条消息可能已经开始发送。',\n 'queue.editFailed.pulledBack': '编辑失败,内容已退回主输入框,请确认后重新发送。',\n 'steer.inflight': '{n} 条正在插入',\n 'steer.now': '打断并输入',\n 'steer.now.aria': '红色:打断当前动作并立即输入',\n 'steer.now.unsupported': '包含非文本内容,暂不支持打断',\n 'steer.nowFailed': '打断失败,请重试。',\n 'steer.next': '插话发送',\n 'steer.next.aria': '黄色:当前动作结束后插入输入',\n 'steer.nextFailed': '插话发送失败,请重试。',\n 'steer.later': '排队到下一轮',\n 'steer.later.aria': '绿色:排队,上一轮输入的动作都结束后再处理',\n 'steer.revoke': '收回排队',\n 'steer.revoke.aria': '绿色:撤销插入,收回排队(下一轮处理)',\n 'steer.revoke.unsupported': '包含非文本内容,暂不支持收回',\n 'steer.revokeFailed': '收回排队失败,请重试。',\n 'steer.moveUp': '上移',\n 'steer.moveDown': '下移',\n 'steer.reorder.unsupported': '包含非文本内容,暂不支持排序',\n 'steer.reorderFailed': '调整顺序失败,请重试。',\n 'steer.reorderStale': '队列已变化,本次排序已取消,请重试。',\n 'steer.dragReorder': '拖动调整顺序',\n 'steer.pullBack': '打回输入框编辑',\n 'steer.pullBack.unsupported': '包含非文本内容,暂不支持打回编辑',\n 'steer.pullBack.composerBusy': '主输入框已有内容,请先发送或清空后再打回',\n 'steer.pullBackFailed': '打回输入框失败,请重试。',\n 'steer.badge.now': '打断中',\n 'steer.badge.next': '插话中',\n 'steer.badge.later': '排队',\n 'steer.unavailable.running': '仅运行中可规划',\n 'steer.clear': '取消并清空',\n 'steer.clear.confirm': '确认清空?',\n 'steer.clear.cancel': '取消清空',\n 'steer.clear.aria': '取消当前执行并清空全部排队消息',\n 'steer.clearFailed': '取消并清空失败,请重试。',\n 'steer.freeze': '冻结追加',\n 'steer.resume': '恢复追加',\n 'steer.frozen': '已冻结:当前轮次完成后暂停,排队消息将在恢复后继续',\n 'steer.frozenInput': '已冻结:输入已暂停,恢复后继续',\n 'steer.frozenBadge': '已冻结',\n 'steer.freezeFailed': '冻结失败,请重试。',\n 'steer.resumeFailed': '恢复失败,请重试。',\n} satisfies Record<string, string>\n\n/** English dictionary (keys mirror zh). */\nexport const en: Record<keyof typeof zh, string> = {\n 'queue.count': '{n} queued messages',\n 'queue.edit': 'Edit queued message',\n 'queue.edit.unsupported': 'Contains non-text content; editing is unsupported',\n 'queue.save': 'Save queued message',\n 'queue.cancelEdit': 'Cancel edit',\n 'queue.remove': 'Remove queued message',\n 'queue.removeFailed': 'Remove failed: the message may have started sending.',\n 'queue.editFailed': 'Edit failed: the message may have started sending.',\n 'queue.editFailed.pulledBack': 'Edit failed; the content was moved back to the composer, please review and resend.',\n 'steer.inflight': '{n} inserting',\n 'steer.now': 'Interrupt and send',\n 'steer.now.aria': 'Red: interrupt the running action and send now',\n 'steer.now.unsupported': 'Contains non-text content; interrupting is unsupported',\n 'steer.nowFailed': 'Interrupt failed, please retry.',\n 'steer.next': 'Send after action',\n 'steer.next.aria': 'Yellow: insert after the current action finishes',\n 'steer.nextFailed': 'Steering failed, please retry.',\n 'steer.later': 'Queue for next turn',\n 'steer.later.aria': 'Green: queue; processed after all previously steered actions finish',\n 'steer.revoke': 'Pull back to queue',\n 'steer.revoke.aria': 'Green: revoke the insertion and queue for the next turn',\n 'steer.revoke.unsupported': 'Contains non-text content; revoking is unsupported',\n 'steer.revokeFailed': 'Revoke failed, please retry.',\n 'steer.moveUp': 'Move up',\n 'steer.moveDown': 'Move down',\n 'steer.reorder.unsupported': 'Contains non-text content; reordering is unsupported',\n 'steer.reorderFailed': 'Reorder failed, please retry.',\n 'steer.reorderStale': 'The queue changed; this reorder was cancelled, please retry.',\n 'steer.dragReorder': 'Drag to reorder',\n 'steer.pullBack': 'Edit in composer',\n 'steer.pullBack.unsupported': 'Contains non-text content; pulling back is unsupported',\n 'steer.pullBack.composerBusy': 'The composer already has content; send or clear it first',\n 'steer.pullBackFailed': 'Pull back failed, please retry.',\n 'steer.badge.now': 'interrupting',\n 'steer.badge.next': 'steering',\n 'steer.badge.later': 'queued',\n 'steer.unavailable.running': 'Planning requires a running session',\n 'steer.clear': 'Cancel and clear',\n 'steer.clear.confirm': 'Confirm clear?',\n 'steer.clear.cancel': 'Cancel clearing',\n 'steer.clear.aria': 'Cancel the current run and clear all queued messages',\n 'steer.clearFailed': 'Cancel and clear failed, please retry.',\n 'steer.freeze': 'Freeze & append',\n 'steer.resume': 'Resume & append',\n 'steer.frozen': 'Frozen: the current turn finishes, then the queue pauses until resumed',\n 'steer.frozenInput': 'Frozen: input paused, resume to continue',\n 'steer.frozenBadge': 'frozen',\n 'steer.freezeFailed': 'Freeze failed, please retry.',\n 'steer.resumeFailed': 'Resume failed, please retry.',\n}\n\n/** Japanese dictionary (keys mirror zh). */\nexport const ja: Record<keyof typeof zh, string> = {\n 'queue.count': '{n} 件のキューイング済みメッセージ',\n 'queue.edit': 'キューイング済みメッセージを編集',\n 'queue.edit.unsupported': '非テキストコンテンツが含まれており、編集はサポートされていません',\n 'queue.save': 'キューイング済みメッセージを保存',\n 'queue.cancelEdit': '編集をキャンセル',\n 'queue.remove': 'キューイング済みメッセージを削除',\n 'queue.removeFailed': '削除失敗:メッセージの送信が既に開始されている可能性があります。',\n 'queue.editFailed': '編集失敗:メッセージの送信が既に開始されている可能性があります。',\n 'queue.editFailed.pulledBack': '編集失敗。コンテンツはコンポーザに戻されました。確認後再送信してください。',\n 'steer.inflight': '{n} 件挿入中',\n 'steer.now': '中断して送信',\n 'steer.now.aria': '赤:実行中のアクションを中断して即座に送信',\n 'steer.now.unsupported': '非テキストコンテンツが含まれており、中断はサポートされていません',\n 'steer.nowFailed': '中断失敗。再試行してください。',\n 'steer.next': 'アクション後に送信',\n 'steer.next.aria': '黄:現在のアクション完了後に挿入',\n 'steer.nextFailed': 'ステア失敗。再試行してください。',\n 'steer.later': '次のターンまでキューイング',\n 'steer.later.aria': '緑:キューイング。以前のステア済みアクションがすべて完了してから処理',\n 'steer.revoke': 'キューに戻す',\n 'steer.revoke.aria': '緑:挿入を取り消し、次のターンまでキューイング',\n 'steer.revoke.unsupported': '非テキストコンテンツが含まれており、取り消しはサポートされていません',\n 'steer.revokeFailed': '取り消し失敗。再試行してください。',\n 'steer.moveUp': '上へ移動',\n 'steer.moveDown': '下へ移動',\n 'steer.reorder.unsupported': '非テキストコンテンツが含まれており、並べ替えはサポートされていません',\n 'steer.reorderFailed': '並べ替え失敗。再試行してください。',\n 'steer.reorderStale': 'キューが変更されました。本次の並べ替えはキャンセルされました。再試行してください。',\n 'steer.dragReorder': 'ドラッグして並べ替え',\n 'steer.pullBack': 'コンポーザに送り直して編集',\n 'steer.pullBack.unsupported': '非テキストコンテンツが含まれており、送り直しはサポートされていません',\n 'steer.pullBack.composerBusy': 'コンポーザに既にコンテンツがあります。送信またはクリアしてください',\n 'steer.pullBackFailed': '送り直し失敗。再試行してください。',\n 'steer.badge.now': '中断中',\n 'steer.badge.next': 'ステア中',\n 'steer.badge.later': 'キューイング済み',\n 'steer.unavailable.running': '実行中のみプランニング可能',\n 'steer.clear': '取り消して全消去',\n 'steer.clear.confirm': '消去を確認?',\n 'steer.clear.cancel': '消去をキャンセル',\n 'steer.clear.aria': '実行を停止し、すべてのキューイング済みメッセージを消去',\n 'steer.clearFailed': '取り消して全消去失敗。再試行してください。',\n 'steer.freeze': '凍結して追加',\n 'steer.resume': '再開して追加',\n 'steer.frozen': '凍結中:現在のターン完了後一時停止、再開後にキューが継続',\n 'steer.frozenInput': '凍結中:入力一時停止、再開後に継続',\n 'steer.frozenBadge': '凍結済み',\n 'steer.freezeFailed': '凍結失敗。再試行してください。',\n 'steer.resumeFailed': '再開失敗。再試行してください。',\n}\n\n/** Korean dictionary (keys mirror zh). */\nexport const ko: Record<keyof typeof zh, string> = {\n 'queue.count': '{n}개 대기열 메시지',\n 'queue.edit': '대기열 메시지 편집',\n 'queue.edit.unsupported': '비텍스트 콘텐츠가 포함되어 있어 편집이 지원되지 않습니다',\n 'queue.save': '대기열 메시지 저장',\n 'queue.cancelEdit': '편집 취소',\n 'queue.remove': '대기열 메시지 삭제',\n 'queue.removeFailed': '삭제 실패: 메시지 전송이 이미 시작되었을 수 있습니다.',\n 'queue.editFailed': '편집 실패: 메시지 전송이 이미 시작되었을 수 있습니다.',\n 'queue.editFailed.pulledBack': '편집 실패. 콘텐츠가 컴포저로 돌아갔습니다. 확인 후 다시 전송하세요.',\n 'steer.inflight': '{n}개 삽입 중',\n 'steer.now': '중단 후 전송',\n 'steer.now.aria': '빨간색: 실행 중인 액션을 중단하고 즉시 전송',\n 'steer.now.unsupported': '비텍스트 콘텐츠가 포함되어 있어 중단이 지원되지 않습니다',\n 'steer.nowFailed': '중단 실패. 다시 시도하세요.',\n 'steer.next': '액션 후 전송',\n 'steer.next.aria': '노란색: 현재 액션 완료 후 삽입',\n 'steer.nextFailed': '스티어 실패. 다시 시도하세요.',\n 'steer.later': '다음 턴까지 대기',\n 'steer.later.aria': '초록색: 대기. 이전 스티어된 액션이 모두 완료된 후 처리',\n 'steer.revoke': '대기열로 되돌리기',\n 'steer.revoke.aria': '초록색: 삽입 취소, 다음 턴까지 대기',\n 'steer.revoke.unsupported': '비텍스트 콘텐츠가 포함되어 있어 취소가 지원되지 않습니다',\n 'steer.revokeFailed': '취소 실패. 다시 시도하세요.',\n 'steer.moveUp': '위로 이동',\n 'steer.moveDown': '아래로 이동',\n 'steer.reorder.unsupported': '비텍스트 콘텐츠가 포함되어 있어 재정렬이 지원되지 않습니다',\n 'steer.reorderFailed': '재정렬 실패. 다시 시도하세요.',\n 'steer.reorderStale': '대기열이 변경되었습니다. 이번 재정렬이 취소되었습니다. 다시 시도하세요.',\n 'steer.dragReorder': '드래그로 재정렬',\n 'steer.pullBack': '컴포저로 되돌려 편집',\n 'steer.pullBack.unsupported': '비텍스트 콘텐츠가 포함되어 있어 되돌리기가 지원되지 않습니다',\n 'steer.pullBack.composerBusy': '컴포저에 이미 콘텐츠가 있습니다. 먼저 전송하거나 비우세요',\n 'steer.pullBackFailed': '되돌리기 실패. 다시 시도하세요.',\n 'steer.badge.now': '중단 중',\n 'steer.badge.next': '스티어 중',\n 'steer.badge.later': '대기열',\n 'steer.unavailable.running': '실행 중에만 계획 가능',\n 'steer.clear': '취소 후 전체 지우기',\n 'steer.clear.confirm': '지우기 확인?',\n 'steer.clear.cancel': '지우기 취소',\n 'steer.clear.aria': '현재 실행을 중지하고 모든 대기열 메시지를 지우기',\n 'steer.clearFailed': '취소 후 전체 지우기 실패. 다시 시도하세요.',\n 'steer.freeze': '동결 후 추가',\n 'steer.resume': '재개 후 추가',\n 'steer.frozen': '동결됨: 현재 턴 완료 후 일시정지, 재개 시 대기열 계속',\n 'steer.frozenInput': '동결됨: 입력 일시정지, 재개 시 계속',\n 'steer.frozenBadge': '동결됨',\n 'steer.freezeFailed': '동결 실패. 다시 시도하세요.',\n 'steer.resumeFailed': '재개 실패. 다시 시도하세요.',\n}\n\n/** Dictionary key union. */\nexport type SteerKey = keyof typeof zh\n","/**\n * Session-scoped freeze store shared by the composer freeze button (the\n * control) and the steering dock (the banner/disabled states).\n *\n * The queue is fully decoupled from freezing: freezing only stops the agent\n * from consuming the queue (the detached entries are preserved here so the\n * driver finds no pending work and stops). While frozen the entries stay\n * fully editable — text, order and the planned insertion tier (now/next/\n * later) can all change; resume re-submits the queue honoring those tiers.\n *\n * State is keyed by session id so freezing one session never leaks into\n * another: each session holds its own `frozen` flag and detached queue, and\n * mutating one session's queue only re-renders that session's consumers\n * (`useSyncExternalStore` bails on unchanged references for the others).\n */\n\n/** Insertion tier planned for one detached queued message. */\nexport type FrozenTier = 'queue' | 'safe_point' | 'force'\n\n/** One detached queued message with its planned insertion tier. */\nexport interface FrozenEntry {\n text: string\n tier: FrozenTier\n}\n\nexport interface FreezeState {\n frozen: boolean\n /** Detached queued messages in FIFO order, each with a planned tier. */\n pending: readonly FrozenEntry[]\n}\n\n/** Session id → per-session freeze state. */\nconst states = new Map<string, FreezeState>()\nconst listeners = new Set<() => void>()\n\n/** Stable empty snapshot: `useSyncExternalStore` needs a reference-stable\n * value for unset sessions so unchanged consumers never re-render. */\nconst EMPTY: FreezeState = { frozen: false, pending: [] }\n\n/** Minimal snapshot store (no runtime dependency, stable identity per mount). */\nexport const freezeStore = {\n /** Snapshot for one session; reference-stable until that session changes. */\n getSnapshot(sessionId: string): FreezeState {\n return states.get(sessionId) ?? EMPTY\n },\n subscribe(listener: () => void): () => void {\n listeners.add(listener)\n return () => { listeners.delete(listener) }\n },\n /** Replace one session's state; unset sessions fall back to EMPTY. */\n set(sessionId: string, next: FreezeState): void {\n if (next.frozen === false && next.pending.length === 0) {\n states.delete(sessionId)\n } else {\n states.set(sessionId, next)\n }\n emit()\n },\n}\n\n/** Reset all sessions (for tests). */\nexport function resetFreezeStore(): void {\n states.clear()\n emit()\n}\n\n/** Append one queued message while frozen (new input lands in the detached queue). */\nexport function pushPending(sessionId: string, text: string, tier: FrozenTier = 'queue'): void {\n const cur = states.get(sessionId) ?? EMPTY\n freezeStore.set(sessionId, { ...cur, pending: [...cur.pending, { text, tier }] })\n}\n\n/** Edit one detached queued message's text in place. */\nexport function updatePendingAt(sessionId: string, index: number, text: string): void {\n const pending = states.get(sessionId)?.pending\n if (pending === undefined) return\n const entry = pending[index]\n if (entry === undefined) return\n const next = [...pending]\n next[index] = { ...entry, text }\n freezeStore.set(sessionId, { frozen: true, pending: next })\n}\n\n/** Change one detached queued message's planned insertion tier. */\nexport function setTierAt(sessionId: string, index: number, tier: FrozenTier): void {\n const pending = states.get(sessionId)?.pending\n if (pending === undefined) return\n const entry = pending[index]\n if (entry === undefined) return\n const next = [...pending]\n next[index] = { ...entry, tier }\n freezeStore.set(sessionId, { frozen: true, pending: next })\n}\n\n/** Remove one detached queued message. */\nexport function removePendingAt(sessionId: string, index: number): void {\n const pending = states.get(sessionId)?.pending\n if (pending === undefined) return\n freezeStore.set(sessionId, { frozen: true, pending: pending.filter((_, i) => i !== index) })\n}\n\n/** Move one detached queued message to a new position (reorder while frozen). */\nexport function movePending(sessionId: string, from: number, to: number): void {\n if (from === to) return\n const pending = states.get(sessionId)?.pending\n if (pending === undefined) return\n const next = [...pending]\n const [moved] = next.splice(from, 1)\n if (moved === undefined) return\n next.splice(to, 0, moved)\n freezeStore.set(sessionId, { frozen: true, pending: next })\n}\n\nfunction emit(): void {\n for (const listener of listeners) listener()\n}\n","/**\r\n * Three-tier steering queue dock: the shadowing replacement for the official\r\n * `conversation.input.dock` entry (same cell id `queue`, priority -1, so the\r\n * lower priority wins and the official QueueDock never renders while this\r\n * plugin is mounted).\r\n *\r\n * Every queued row carries three planning buttons:\r\n * - green (later, the default state): the row already queues for the next\r\n * turn —plain Enter keeps feeding rows here; pressing green on a row that\r\n * was already steered (yellow) revokes the insertion and pulls it back to\r\n * later (the yellow flow is reversible);\r\n * - yellow (next): strict-steer the row into the running turn, consumed at\r\n * the next step boundary (after the current action finishes);\r\n * - red (now): cancel the running turn, then remove the row and re-send its\r\n * text as a fresh message —the re-send arms the harness wake latch (the\r\n * converged driver restarts) and the interrupted input is processed as the\r\n * next turn's input. A plain steer after cancel would re-insert a message\r\n * that is already pending in next-turn and the inbox rejects it.\r\n *\r\n * The toolbar also exposes a queue-level \"cancel and clear\" that stops the\r\n * current run and removes every queued row, plus a session-level\r\n * freeze/resume toggle for the peak-hour scenario: freeze stops the current\r\n * run while preserving the queue (keepInbox), resume re-arms the driver by\r\n * re-sending the first queued row so the preserved work continues.\r\n */\r\nimport { useEffect, useId, useMemo, useRef, useState, useSyncExternalStore } from 'react'\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\n// Type-only: the conversation slot/contract declarations (module augmentation\r\n// for the SlotMap and the session standard kit). No value import crosses the\r\n// plugin boundary.\r\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\r\nimport {\r\n IconCheckOutline16, IconChevronDownOutline14, IconChevronUpOutline14, IconCloseOutline16,\r\n IconEditOutline16, IconQueueOutline14, IconRightUpOutline16, IconTrashOutline16, Tooltip,\r\n} from '@deepseek-ai/dsh-client-ui-primitives'\r\nimport { freezeStore, setTierAt, updatePendingAt, removePendingAt, movePending } from './freeze-store.ts'\r\nimport css from './steer-queue-dock.module.css'\r\n\r\n/** One mutation accepted by the conversation queue verb. */\r\nexport type SteerQueueAction =\r\n | { kind: 'edit'; content: readonly { type: 'text'; text: string }[] }\r\n | { kind: 'remove' }\r\n | { kind: 'steer' }\r\n\r\n/** Busy marker for a whole-queue rebuild (reorder); locks every row action. */\r\nconst REORDER_MARK = '__reorder__'\r\n\r\n/** localStorage key for the manual collapse state (dsh-queue-plus parity). */\r\nconst COLLAPSE_KEY = 'dsh-input-traffic:collapsed'\r\n\r\n/** Queue operations injected by the session-scoped registration. */\r\nexport interface SteerQueueDockInjected {\r\n updateQueue: (itemId: string, action: SteerQueueAction) => Promise<void>\r\n /** Cancel the current turn while preserving the pending queue. */\r\n cancel: () => Promise<void>\r\n /** Re-send one plain-text message as a queued follow-up (the revoke path). */\r\n send: (text: string) => Promise<void>\r\n /** Steer one plain-text message into the session's next step (resume's safe_point tier). */\r\n sendSteer?: (text: string) => Promise<void>\r\n /** Back-fill the composer draft (the pull-back-to-composer edit path). */\r\n setDraft: (text: string) => void\r\n notify: (level: 'info' | 'error', text: string) => void\r\n /** Owning session id (for the dsh-session-guard bridge RPC). */\r\n sessionId?: string\r\n /** Raise/clear the composer block for the owning session (freeze keeps the\r\n * composer inert so Enter cannot leak into the conversation; absent on the\r\n * dock entry, only the freeze button injects it). */\r\n setComposerBlock?: (reason: string | undefined) => void\r\n}\r\n\r\n/** Full props of a dock entry: InputZone owner share + session standard kit + global seat + the locale seat. */\r\nexport type SteerQueueDockProps = PropsRuntime<'conversation.input.dock'> & SteerQueueDockInjected & PropsLocale<'steer'>\r\n\r\n/** The planning tier of one queued row. */\r\nexport type SteerTier = 'now' | 'next' | 'later'\r\n\r\n/**\r\n * Resolve the action sequence for one planning button press. Pure so the\r\n * button wiring and its tests share one truth.\r\n * @param tier - the pressed planning tier.\r\n * @returns the queue mutation (red re-uses a steer-shaped action for the\r\n * yellow branch; the red branch performs cancel + remove + resend instead).\r\n */\r\nexport function planActionFor(tier: SteerTier): { action: SteerQueueAction; interruptFirst: boolean } {\r\n if (tier === 'later') return { action: { kind: 'steer' }, interruptFirst: false }\r\n // Yellow steers only; red cancels the running turn first, then steers.\r\n return { action: { kind: 'steer' }, interruptFirst: tier === 'now' }\r\n}\r\n\r\n/**\r\n * Project the tier badge of one inbox row from its placement. Pure so the\r\n * row rendering and its tests share one truth.\r\n * @param placement - the inbox projection placement.\r\n * @returns the tier badge, or null for non-visible context rows.\r\n */\r\nexport function badgeFor(placement: 'queued' | 'steering' | 'context'): SteerTier | null {\r\n if (placement === 'steering') return 'next'\r\n if (placement === 'queued') return 'later'\r\n return null\r\n}\r\n\r\n/**\r\n * Auto-grow one edit textarea to its content. The CSS max-height caps the\r\n * growth; beyond it the textarea scrolls internally. Height is reset first so\r\n * shrink (deleting lines) also tracks the content.\r\n * @param el - the textarea to resize in place.\r\n */\r\nexport function resizeEditor(el: HTMLTextAreaElement): void {\r\n el.style.height = 'auto'\r\n el.style.height = `${el.scrollHeight}px`\r\n}\r\n\r\n/**\r\n * Queue strip with three-tier planning: one item renders directly; multiple\r\n * items default to a collapsible count header; an empty queue renders nothing.\r\n */\r\nexport function SteerQueueDock({ sessionId, useSession, input, updateQueue, cancel, send, setDraft, notify, t }: SteerQueueDockProps) {\r\n const inbox = useSession(s => s.queue)\r\n const queue = useMemo(() => inbox.filter(row => row.placement === 'queued'), [inbox])\r\n const steering = useMemo(() => inbox.filter(row => row.placement === 'steering'), [inbox])\r\n const running = useSession(s => s.running)\r\n const queueMutable = useSession(s => s.subagent === null)\r\n const [editing, setEditing] = useState<{ id: string; text: string } | null>(null)\r\n const [busy, setBusy] = useState<string | null>(null)\r\n const [clearing, setClearing] = useState(false)\r\n // Two-step clear confirmation: the first click arms the prompt, the second\r\n // executes; arming auto-reverts after a few seconds (no native confirm).\r\n const [confirmClear, setConfirmClear] = useState(false)\r\n const confirmTimer = useRef<ReturnType<typeof setTimeout> | null>(null)\r\n // Drag-and-drop reorder source index and the current drop-target row.\r\n const dragIndex = useRef<number | null>(null)\r\n const [dragOver, setDragOver] = useState<number | null>(null)\r\n // Collapse state persists across mounts (dsh-queue-plus parity).\r\n const [collapsed, setCollapsed] = useState(() => {\r\n try {\r\n const v = localStorage.getItem(COLLAPSE_KEY)\r\n return v === null ? true : v === '1'\r\n } catch {\r\n return true\r\n }\r\n })\r\n // Session-level freeze lives in the composer-right control; the dock reads\r\n // the shared store for the banner and inert states. While frozen the\r\n // detached queue is rendered here (read-only) so the waiting area stays\r\n // visible — freezing only pauses the running behavior, it must not hide\r\n // the queued messages.\r\n const { frozen, pending: frozenPending } = useSyncExternalStore(\r\n freezeStore.subscribe,\r\n () => freezeStore.getSnapshot(sessionId ?? ''),\r\n )\r\n const sid = sessionId ?? ''\r\n const listId = useId()\r\n // The edit textarea; grown to its content on entry and on every input.\r\n const editorRef = useRef<HTMLTextAreaElement>(null)\r\n\r\n useEffect(() => {\r\n if (queue.length === 0 && !collapsed) setCollapsed(true)\r\n // Frozen-row edits use a `frozen:` id that never exists in the dsh queue;\r\n // skip the stale-check for them so the detached queue stays editable.\r\n if (editing !== null && !editing.id.startsWith('frozen:') && (!queueMutable || !queue.some(row => row.id === editing.id))) setEditing(null)\r\n }, [collapsed, editing, queue, queueMutable])\r\n\r\n // Persist the manual collapse state; clear the confirm timer on unmount.\r\n useEffect(() => {\r\n try {\r\n localStorage.setItem(COLLAPSE_KEY, collapsed ? '1' : '0')\r\n } catch {\r\n /* storage unavailable: in-memory only */\r\n }\r\n }, [collapsed])\r\n useEffect(() => () => {\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n }, [])\r\n\r\n // Grow the editor to its full content when a row enters edit mode.\r\n const editingId = editing?.id\r\n useEffect(() => {\r\n if (editingId === undefined) return\r\n const el = editorRef.current\r\n if (el !== null) resizeEditor(el)\r\n }, [editingId])\r\n\r\n // The dock stays mounted while the agent runs (the freeze entry must be\r\n // reachable before any message queues), while any row is pending, and while\r\n // the session is frozen (the detached queue stays visible).\r\n if (queue.length === 0 && steering.length === 0 && !running && !frozen) return null\r\n\r\n const interactionActive = queueMutable && (editing !== null || busy !== null || clearing)\r\n const expanded = !collapsed || interactionActive\r\n const listVisible = queue.length === 1 || expanded\r\n const planDisabled = !queueMutable || !running || frozen\r\n const nothingPending = queue.length === 0 && steering.length === 0\r\n // Reordering rebuilds the queue by re-sending texts; non-text rows cannot\r\n // be re-sent, so sorting is disabled while any such row is queued.\r\n const reorderUnsupported = queue.some(row => row.text === null)\r\n // Pull-back-to-composer is only offered when the composer draft is empty:\r\n // the pulled message back-fills the draft, so an occupied composer would be\r\n // overwritten. Steered (yellow/red) rows never offer it — once inserted,\r\n // they are not deeply re-edited.\r\n const composerEmpty = input.draft.trim() === ''\r\n\r\n const applyAction = async (\r\n itemId: string,\r\n action: SteerQueueAction,\r\n failure: string,\r\n ): Promise<boolean> => {\r\n setBusy(itemId)\r\n try {\r\n await updateQueue(itemId, action)\r\n return true\r\n } catch {\r\n notify('error', failure)\r\n return false\r\n } finally {\r\n setBusy(current => current === itemId ? null : current)\r\n }\r\n }\r\n\r\n const saveEdit = async (): Promise<void> => {\r\n if (editing === null || editing.text.trim() === '') return\r\n const itemId = editing.id\r\n const text = editing.text\r\n setBusy(itemId)\r\n try {\r\n await updateQueue(itemId, { kind: 'edit', content: [{ type: 'text', text }] })\r\n setEditing(null)\r\n } catch {\r\n // The edit failed (the agent may have claimed the row mid-edit): fall\r\n // back to the composer so the edited content is never lost. Only when\r\n // the composer is free — an occupied draft must not be overwritten.\r\n if (input.draft.trim() === '') {\r\n setDraft(text)\r\n setEditing(null)\r\n notify('error', t('queue.editFailed.pulledBack'))\r\n } else {\r\n notify('error', t('queue.editFailed'))\r\n }\r\n } finally {\r\n setBusy(current => current === itemId ? null : current)\r\n }\r\n }\r\n\r\n const steerRow = async (row: { id: string; text: string | null }, tier: Exclude<SteerTier, 'later'>): Promise<void> => {\r\n setBusy(row.id)\r\n try {\r\n if (tier === 'now') {\r\n // Interrupt, then re-submit: cancel stops the current run (keepInbox),\r\n // the row is removed so its identity cannot collide, and re-sending\r\n // the text arms the harness wake latch (the converged driver restarts\r\n // and processes it as the next turn's input). A plain steer after\r\n // cancel would re-insert a message already pending in next-turn and\r\n // the inbox rejects the duplicate.\r\n await cancel()\r\n await updateQueue(row.id, { kind: 'remove' })\r\n if (row.text !== null) await send(row.text)\r\n } else {\r\n await updateQueue(row.id, { kind: 'steer' })\r\n }\r\n } catch {\r\n notify('error', tier === 'now' ? t('steer.nowFailed') : t('steer.nextFailed'))\r\n } finally {\r\n setBusy(current => current === row.id ? null : current)\r\n }\r\n }\r\n\r\n /**\r\n * Revoke a steered (yellow) or interrupting (red) row back to later: remove\r\n * the admitted row and re-send its text as a queued follow-up, so it lands\r\n * in next-turn again (the yellow flow is reversible).\r\n */\r\n const revokeToLater = async (row: { id: string; text: string | null }): Promise<void> => {\r\n if (row.text === null) return\r\n setBusy(row.id)\r\n try {\r\n await updateQueue(row.id, { kind: 'remove' })\r\n await send(row.text)\r\n } catch {\r\n notify('error', t('steer.revokeFailed'))\r\n } finally {\r\n setBusy(current => current === row.id ? null : current)\r\n }\r\n }\r\n\r\n /**\r\n * Rebuild the queue in a new order: remove every queued row, then re-send\r\n * the texts sequentially so the agent's next-turn list matches the new\r\n * order. Concurrency protection (dsh-queue-plus parity): if a remove fails\r\n * with queue-item-not-found, the agent already claimed that row — the\r\n * rebuild stops immediately and nothing is re-sent, so the changed queue\r\n * is never scrambled.\r\n */\r\n const rebuildQueue = async (rows: readonly { id: string; text: string | null }[], next: readonly { id: string; text: string | null }[]): Promise<void> => {\r\n setBusy(REORDER_MARK)\r\n try {\r\n for (const row of rows) {\r\n try {\r\n await updateQueue(row.id, { kind: 'remove' })\r\n } catch (error) {\r\n if (error instanceof Error && error.message.includes('queue-item-not-found')) {\r\n notify('error', t('steer.reorderStale'))\r\n return\r\n }\r\n throw error\r\n }\r\n }\r\n for (const row of next) {\r\n if (row.text !== null) await send(row.text)\r\n }\r\n } catch {\r\n notify('error', t('steer.reorderFailed'))\r\n } finally {\r\n setBusy(null)\r\n }\r\n }\r\n\r\n /**\r\n * Move one queued row up/down in the FIFO order (arrow buttons).\r\n */\r\n const reorder = async (rowId: string, delta: -1 | 1): Promise<void> => {\r\n const rows = queue\r\n const index = rows.findIndex(row => row.id === rowId)\r\n const target = index + delta\r\n if (index < 0 || target < 0 || target >= rows.length) return\r\n const next = [...rows]\r\n const swapped = next[index] as typeof next[number]\r\n next[index] = next[target] as typeof next[number]\r\n next[target] = swapped\r\n if (next.some(row => row.text === null)) {\r\n notify('error', t('steer.reorder.unsupported'))\r\n return\r\n }\r\n await rebuildQueue(rows, next)\r\n }\r\n\r\n /**\r\n * Move one row to an absolute position (drag-and-drop drop handler).\r\n */\r\n const reorderTo = async (fromIndex: number, toIndex: number): Promise<void> => {\r\n if (fromIndex === toIndex) return\r\n const rows = queue\r\n if (rows[fromIndex] === undefined || rows[toIndex] === undefined) return\r\n const next = [...rows]\r\n const [moved] = next.splice(fromIndex, 1)\r\n if (moved === undefined) return\r\n next.splice(toIndex, 0, moved)\r\n if (next.some(row => row.text === null)) {\r\n notify('error', t('steer.reorder.unsupported'))\r\n return\r\n }\r\n await rebuildQueue(rows, next)\r\n }\r\n\r\n /** Arm or execute the two-step clear confirmation. */\r\n const armClear = (): void => {\r\n if (confirmClear) {\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n setConfirmClear(false)\r\n void clearAll()\r\n return\r\n }\r\n setConfirmClear(true)\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n confirmTimer.current = setTimeout(() => setConfirmClear(false), 3000)\r\n }\r\n\r\n /** Abort the armed clear confirmation (the explicit cancel button). */\r\n const cancelClear = (): void => {\r\n if (confirmTimer.current !== null) clearTimeout(confirmTimer.current)\r\n setConfirmClear(false)\r\n }\r\n\r\n /** Save an in-place edit of one detached (frozen) queued message. */\r\n const saveFrozenEdit = async (index: number): Promise<void> => {\r\n if (editing === null) return\r\n const text = editing.text.trim()\r\n if (text === '') {\r\n setEditing(null)\r\n return\r\n }\r\n updatePendingAt(sid, index, text)\r\n setEditing(null)\r\n }\r\n\r\n /**\r\n * Pull one queued row back into the composer draft for editing: the text\r\n * back-fills the input box and the row leaves the queue; the user edits and\r\n * resubmits it as a fresh message.\r\n */\r\n const pullBackToComposer = async (row: { id: string; text: string | null }): Promise<void> => {\r\n if (row.text === null) return\r\n setDraft(row.text)\r\n setBusy(row.id)\r\n try {\r\n await updateQueue(row.id, { kind: 'remove' })\r\n } catch {\r\n notify('error', t('steer.pullBackFailed'))\r\n } finally {\r\n setBusy(current => current === row.id ? null : current)\r\n }\r\n }\r\n\r\n const clearAll = async (): Promise<void> => {\r\n setClearing(true)\r\n // Cancel the current run and clear every pending row (queued and\r\n // steering alike). Removal races the agent claiming rows;\r\n // item-not-found is a normal convergence and must not surface.\r\n const pending = [...queue, ...steering]\r\n try {\r\n await cancel()\r\n await Promise.all(pending.map(row =>\r\n updateQueue(row.id, { kind: 'remove' }).catch(() => undefined),\r\n ))\r\n } catch {\r\n notify('error', t('steer.clearFailed'))\r\n } finally {\r\n setClearing(false)\r\n }\r\n }\r\n\r\n return (\r\n <div className={css.dock} data-steer-dock=\"\">\r\n <div className={css.panel}>\r\n <div className={css.toolbar}>\r\n <button\r\n type=\"button\"\r\n className={css.header}\r\n aria-controls={listId}\r\n aria-expanded={expanded}\r\n disabled={queue.length <= 1 || interactionActive}\r\n onClick={() => { setCollapsed(value => !value) }}\r\n >\r\n <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>\r\n {queue.length > 0 && (\r\n <span className={css.count}>{t('queue.count', { n: queue.length })}</span>\r\n )}\r\n {queue.length > 1 && (\r\n <span className={css.chevron} aria-hidden>\r\n {expanded ? <IconChevronDownOutline14 /> : <IconChevronUpOutline14 />}\r\n </span>\r\n )}\r\n </button>\r\n <div className={css.toolbarActions}>\r\n {confirmClear && (\r\n <button\r\n type=\"button\"\r\n className={css.clearCancel}\r\n aria-label={t('steer.clear.cancel')}\r\n disabled={clearing || busy !== null || nothingPending}\r\n onClick={cancelClear}\r\n >\r\n <span className={css.clearLabel}>{t('steer.clear.cancel')}</span>\r\n </button>\r\n )}\r\n <Tooltip label={confirmClear ? t('steer.clear.confirm') : t('steer.clear')} side=\"top\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.clear} ${confirmClear ? css.clearConfirm : ''}`}\r\n aria-label={confirmClear ? t('steer.clear.confirm') : t('steer.clear')}\r\n disabled={clearing || busy !== null || nothingPending}\r\n onClick={armClear}\r\n >\r\n <IconTrashOutline16 size={14} />\r\n <span className={css.clearLabel}>{confirmClear ? t('steer.clear.confirm') : t('steer.clear')}</span>\r\n </button>\r\n </Tooltip>\r\n </div>\r\n </div>\r\n {frozen && (\r\n <div className={css.frozenBanner} role=\"status\">\r\n {t('steer.frozen')}\r\n </div>\r\n )}\r\n {/* While frozen the queue is detached into the shared store: render it\r\n here so the waiting area never disappears. The detached rows stay\r\n fully editable (edit / remove / reorder) — freezing only pauses\r\n the running behavior, it must not lock the queue. */}\r\n {frozen && frozenPending.length > 0 && (\r\n <ul className={css.frozenList} data-testid=\"frozen-list\">\r\n {frozenPending.map((entry, i) => {\r\n const editingFrozen = editing?.id === `frozen:${i}`\r\n const text = entry.text\r\n return (\r\n <li\r\n key={i}\r\n className={`${css.frozenRow} ${dragOver === i && frozen ? css.rowDragOver : ''}`}\r\n data-tier={entry.tier === 'force' ? 'now' : entry.tier === 'safe_point' ? 'next' : 'later'}\r\n data-editing={editingFrozen ? '' : undefined}\r\n draggable={!editingFrozen}\r\n title={!editingFrozen ? t('steer.dragReorder') : undefined}\r\n onDragStart={(event) => {\r\n if (editingFrozen) return\r\n dragIndex.current = i\r\n event.dataTransfer.effectAllowed = 'move'\r\n // Some engines only start HTML5 drag once data is set.\r\n event.dataTransfer.setData('text/plain', String(i))\r\n }}\r\n onDragOver={(event) => {\r\n if (dragIndex.current === null) return\r\n event.preventDefault()\r\n setDragOver(i)\r\n }}\r\n onDrop={(event) => {\r\n event.preventDefault()\r\n const from = dragIndex.current\r\n dragIndex.current = null\r\n setDragOver(null)\r\n if (from !== null) movePending(sid, from, i)\r\n }}\r\n onDragEnd={() => {\r\n dragIndex.current = null\r\n setDragOver(null)\r\n }}\r\n >\r\n <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>\r\n <SteerBadge tier={entry.tier === 'force' ? 'now' : entry.tier === 'safe_point' ? 'next' : 'later'} t={t} />\r\n {editingFrozen\r\n ? (\r\n <textarea\r\n ref={editorRef}\r\n autoFocus\r\n className={css.editor}\r\n aria-label={t('queue.edit')}\r\n rows={1}\r\n value={editing?.text ?? text}\r\n onChange={(event) => { setEditing({ id: `frozen:${i}`, text: event.currentTarget.value }) }}\r\n onInput={(event) => { resizeEditor(event.currentTarget) }}\r\n onKeyDown={(event) => {\r\n if (event.key === 'Escape') {\r\n setEditing(null)\r\n return\r\n }\r\n if (event.key === 'Enter' && !event.shiftKey && !event.nativeEvent.isComposing) {\r\n event.preventDefault()\r\n void saveFrozenEdit(i)\r\n }\r\n }}\r\n />\r\n )\r\n : <span className={css.preview}>{text}</span>}\r\n <div className={css.actions}>\r\n {editingFrozen ? (\r\n <>\r\n <Tooltip label={t('queue.save')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.save')}\r\n disabled={editing === null || editing.text.trim() === ''}\r\n onClick={() => { void saveFrozenEdit(i) }}\r\n >\r\n <IconCheckOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.cancelEdit')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.cancelEdit')}\r\n onClick={() => { setEditing(null) }}\r\n >\r\n <IconCloseOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n </>\r\n ) : (\r\n <>\r\n <Tooltip label={t('steer.moveUp')} side=\"bottom\" delayMs={500} disabled={i === 0}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveUp')}\r\n disabled={i === 0}\r\n onClick={() => movePending(sid, i, i - 1)}\r\n >\r\n <IconChevronUpOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.moveDown')} side=\"bottom\" delayMs={500} disabled={i === frozenPending.length - 1}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveDown')}\r\n disabled={i === frozenPending.length - 1}\r\n onClick={() => movePending(sid, i, i + 1)}\r\n >\r\n <IconChevronDownOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.edit')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.edit')}\r\n onClick={() => { setEditing({ id: `frozen:${i}`, text }) }}\r\n >\r\n <IconEditOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.remove')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.remove')}\r\n onClick={() => removePendingAt(sid, i)}\r\n >\r\n <IconTrashOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n {/* Planned insertion tier: freezing pauses consumption,\r\n it must not lock the tier planning of each row. */}\r\n <span className={css.plan} role=\"group\" aria-label={t('steer.later.aria')}>\r\n <Tooltip label={t('steer.now')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNow}`}\r\n aria-label={t('steer.now')}\r\n aria-pressed={entry.tier === 'force' || undefined}\r\n onClick={() => setTierAt(sid, i, 'force')}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.next')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNext}`}\r\n aria-label={t('steer.next')}\r\n aria-pressed={entry.tier === 'safe_point' || undefined}\r\n onClick={() => setTierAt(sid, i, 'safe_point')}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.later')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierLater}`}\r\n aria-label={t('steer.later')}\r\n aria-pressed={entry.tier === 'queue' || undefined}\r\n onClick={() => setTierAt(sid, i, 'queue')}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n </span>\r\n </>\r\n )}\r\n </div>\r\n <span className={css.frozenMark}>{t('steer.frozenBadge')}</span>\r\n </li>\r\n )\r\n })}\r\n </ul>\r\n )}\r\n <ul id={listId} className={css.list} hidden={!listVisible}>\r\n {listVisible && queue.map((row, index) => (\r\n <li\r\n key={row.id}\r\n className={`${css.row} ${dragOver === index ? css.rowDragOver : ''}`}\r\n data-tier={badgeFor('queued') ?? undefined}\r\n data-editing={editing?.id === row.id ? '' : undefined}\r\n draggable={queueMutable && !reorderUnsupported && busy === null && !frozen}\r\n title={queueMutable && !reorderUnsupported && busy === null && !frozen ? t('steer.dragReorder') : undefined}\r\n onDragStart={(event) => {\r\n dragIndex.current = index\r\n event.dataTransfer.effectAllowed = 'move'\r\n // Some engines only start HTML5 drag once data is set.\r\n event.dataTransfer.setData('text/plain', String(index))\r\n }}\r\n onDragOver={(event) => {\r\n if (dragIndex.current === null) return\r\n event.preventDefault()\r\n setDragOver(index)\r\n }}\r\n onDrop={(event) => {\r\n event.preventDefault()\r\n const from = dragIndex.current\r\n dragIndex.current = null\r\n setDragOver(null)\r\n if (from !== null) void reorderTo(from, index)\r\n }}\r\n onDragEnd={() => {\r\n dragIndex.current = null\r\n setDragOver(null)\r\n }}\r\n >\r\n {queue.length === 1 && <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>}\r\n <SteerBadge tier={badgeFor('queued')} t={t} />\r\n {editing?.id === row.id\r\n ? (\r\n <textarea\r\n ref={editorRef}\r\n autoFocus\r\n className={css.editor}\r\n aria-label={t('queue.edit')}\r\n rows={1}\r\n value={editing.text}\r\n onChange={(event) => { setEditing({ id: row.id, text: event.currentTarget.value }) }}\r\n onInput={(event) => { resizeEditor(event.currentTarget) }}\r\n onKeyDown={(event) => {\r\n if (event.key === 'Escape') {\r\n setEditing(null)\r\n return\r\n }\r\n // Plain Enter saves; Shift+Enter keeps editing (newline).\r\n if (event.key === 'Enter' && !event.shiftKey && !event.nativeEvent.isComposing) {\r\n event.preventDefault()\r\n void saveEdit()\r\n }\r\n }}\r\n />\r\n )\r\n : <span className={css.preview}>{row.preview}</span>}\r\n {queueMutable && <div className={css.actions}>\r\n {editing?.id === row.id\r\n ? (\r\n <>\r\n <Tooltip label={t('queue.save')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.save')}\r\n disabled={busy !== null || editing.text.trim() === ''}\r\n onClick={() => { void saveEdit() }}\r\n >\r\n <IconCheckOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.cancelEdit')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.cancelEdit')}\r\n disabled={busy !== null}\r\n onClick={() => { setEditing(null) }}\r\n >\r\n <IconCloseOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n </>\r\n )\r\n : (\r\n <>\r\n <Tooltip label={t('steer.moveUp')} side=\"bottom\" delayMs={500} disabled={frozen || reorderUnsupported}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveUp')}\r\n title={reorderUnsupported ? t('steer.reorder.unsupported') : undefined}\r\n disabled={busy !== null || frozen || reorderUnsupported}\r\n onClick={() => { void reorder(row.id, -1) }}\r\n >\r\n <IconChevronUpOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.moveDown')} side=\"bottom\" delayMs={500} disabled={frozen || reorderUnsupported}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.moveDown')}\r\n title={reorderUnsupported ? t('steer.reorder.unsupported') : undefined}\r\n disabled={busy !== null || frozen || reorderUnsupported}\r\n onClick={() => { void reorder(row.id, 1) }}\r\n >\r\n <IconChevronDownOutline14 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.pullBack')} side=\"bottom\" delayMs={500} disabled={row.text === null || !composerEmpty}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('steer.pullBack')}\r\n title={row.text === null ? t('steer.pullBack.unsupported') : !composerEmpty ? t('steer.pullBack.composerBusy') : undefined}\r\n disabled={busy !== null || frozen || row.text === null || !composerEmpty}\r\n onClick={() => { void pullBackToComposer(row) }}\r\n >\r\n <IconRightUpOutline16 />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.edit')} side=\"bottom\" delayMs={500} disabled={row.text === null}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.edit')}\r\n title={row.text === null ? t('queue.edit.unsupported') : undefined}\r\n disabled={busy !== null || row.text === null}\r\n onClick={() => {\r\n if (row.text !== null) setEditing({ id: row.id, text: row.text })\r\n }}\r\n >\r\n <IconEditOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('queue.remove')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={css.action}\r\n aria-label={t('queue.remove')}\r\n disabled={busy !== null}\r\n onClick={() => {\r\n void applyAction(row.id, { kind: 'remove' }, t('queue.removeFailed'))\r\n }}\r\n >\r\n <IconTrashOutline16 size={14} />\r\n </button>\r\n </Tooltip>\r\n <span className={css.plan} role=\"group\" aria-label={t('steer.later.aria')}>\r\n <Tooltip label={t('steer.now')} side=\"bottom\" delayMs={500} disabled={planDisabled || row.text === null}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNow}`}\r\n aria-label={t('steer.now')}\r\n title={planDisabled ? t('steer.unavailable.running') : row.text === null ? t('steer.now.unsupported') : undefined}\r\n disabled={busy !== null || planDisabled || row.text === null}\r\n onClick={() => { void steerRow(row, 'now') }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.next')} side=\"bottom\" delayMs={500} disabled={planDisabled}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierNext}`}\r\n aria-label={t('steer.next')}\r\n title={planDisabled ? t('steer.unavailable.running') : undefined}\r\n disabled={busy !== null || planDisabled}\r\n onClick={() => { void steerRow(row, 'next') }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n <Tooltip label={t('steer.later')} side=\"bottom\" delayMs={500}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierLater}`}\r\n aria-label={t('steer.later')}\r\n aria-pressed\r\n disabled={busy !== null || clearing}\r\n onClick={() => {\r\n // Later is the default queue state; pressing it\r\n // keeps the row queued (no-op by design).\r\n }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n </span>\r\n </>\r\n )}\r\n </div>}\r\n </li>\r\n ))}\r\n </ul>\r\n {steering.length > 0 && (\r\n <ul className={css.steeringList} data-steering-list=\"\">\r\n {steering.map(row => (\r\n <li key={row.id} className={css.row} data-tier={badgeFor('steering') ?? undefined}>\r\n <span className={css.lead} aria-hidden><IconQueueOutline14 /></span>\r\n <SteerBadge tier={badgeFor('steering')} t={t} />\r\n <span className={css.preview}>{row.preview}</span>\r\n <div className={css.actions}>\r\n <Tooltip label={t('steer.revoke')} side=\"bottom\" delayMs={500} disabled={row.text === null}>\r\n <button\r\n type=\"button\"\r\n className={`${css.tier} ${css.tierLater}`}\r\n aria-label={t('steer.revoke')}\r\n title={row.text === null ? t('steer.revoke.unsupported') : undefined}\r\n disabled={busy !== null || row.text === null || frozen}\r\n onClick={() => { void revokeToLater(row) }}\r\n >\r\n <span className={css.dot} aria-hidden />\r\n </button>\r\n </Tooltip>\r\n </div>\r\n </li>\r\n ))}\r\n </ul>\r\n )}\r\n </div>\r\n </div>\r\n )\r\n}\r\n\r\n/** Badge label keys per tier. */\r\nconst BADGE_KEYS: Record<SteerTier, string> = {\r\n now: 'steer.badge.now',\r\n next: 'steer.badge.next',\r\n later: 'steer.badge.later',\r\n}\r\n\r\n/** Badge tint classes per tier (present at bundle time; typed through the css-modules declaration). */\r\nconst BADGE_CLASSES: Record<SteerTier, string> = {\r\n now: css.badgeNow as string,\r\n next: css.badgeNext as string,\r\n later: css.badgeLater as string,\r\n}\r\n\r\n/** One row's tier badge: colored dot + label; context rows render nothing. */\r\nfunction SteerBadge({ tier, t }: { tier: SteerTier | null; t: SteerQueueDockProps['t'] }) {\r\n if (tier === null) return null\r\n return (\r\n <span className={`${css.badge} ${BADGE_CLASSES[tier]}`} data-badge={tier}>\r\n <span className={css.dot} aria-hidden />\r\n <span className={css.badgeLabel}>{t(BADGE_KEYS[tier])}</span>\r\n </span>\r\n )\r\n}\r\n","/**\r\n * input-traffic ↔ dsh-session-guard 透传桥(D8 fail-open)。\r\n *\r\n * input-traffic **只做冻结增强**(队列冻结/解冻),服务端会话门(暂停/恢复会话)\r\n * 归 dsh-session-guard 插件。冻结/解冻按钮触发时,尽力调用\r\n * `sessionGuard.stopNextTurn` / `resume`;**插件未装**(路由 404 / 网络失败 /\r\n * 返回错误)→ 静默跳过,**绝不报错**,前端冻结仍正常生效。\r\n *\r\n * 不吸收任何 auto-continue / 重试逻辑(重试归后端 dsh-session-guard,D9)。\r\n */\r\n\r\n/** 尽力调用 sessionGuard.stopNextTurn(停掉 session 下一回合)。失败静默。 */\r\nexport async function sessionGuardStopNextTurn(sessionId: string): Promise<boolean> {\r\n return callGuard(sessionId, 'stopNextTurn')\r\n}\r\n\r\n/** 尽力调用 sessionGuard.resume。失败静默。 */\r\nexport async function sessionGuardResume(sessionId: string): Promise<boolean> {\r\n return callGuard(sessionId, 'resume')\r\n}\r\n\r\nasync function callGuard(sessionId: string, action: string): Promise<boolean> {\r\n try {\r\n const res = await fetch('/session-guard/rpc', {\r\n method: 'POST',\r\n headers: { 'content-type': 'application/json' },\r\n body: JSON.stringify({ sessionId, action }),\r\n })\r\n if (!res.ok) return false\r\n const body = await res.json().catch(() => null)\r\n return body?.ok === true\r\n } catch {\r\n // 路由不存在(session-guard 未装)/ 网络失败 → fail-open。\r\n return false\r\n }\r\n}\r\n\r\n// 探测标记:session-guard 客户端据此跳过自带的回退冻结按钮(避免双按钮/占位)。\r\n// 在 bundle 顶层执行;input-traffic 桥存在即置位。\r\ndeclare global {\r\n var __DSH_SESSION_GUARD_BRIDGE__: boolean | undefined\r\n}\r\ntry {\r\n globalThis.__DSH_SESSION_GUARD_BRIDGE__ = true\r\n} catch {\r\n /* 浏览器环境无 window 时忽略 */\r\n}\r\n","/**\r\n * Session freeze/resume control, mounted in the composer's right tool row\r\n * (`conversation.input.right`) so it is reachable before anything queues.\r\n *\r\n * Peak-hour pause semantics: freeze does NOT interrupt the running turn —it\r\n * finishes naturally. The queued messages are detached (removed, preserved in\r\n * the shared store), so the driver finds no pending work and stops after the\r\n * current turn. Resume re-submits the preserved texts, waking the driver and\r\n * continuing the queue.\r\n *\r\n * dsh-session-guard 协作(D8 fail-open):\r\n * - 冻结 = 前端摘队列(本插件)+ composer block(阻止新输入漏进对话) + 尽力调服务端\r\n * sessionGuard.stopNextTurn(停掉 session 下一回合;session-guard 未装时静默跳过)。\r\n * - 解冻 = 清 composer block + **先** await sessionGuard.resume(让被打断回合的自然\r\n * 下一步先发生),**再**重投队列(later 级条目因此排在自然 next turn 之后,不再插队)。\r\n * - 本插件只做冻结增强,不承担重试/暂停决策(归后端,D9)。\r\n */\r\nimport { useSyncExternalStore } from 'react'\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\r\nimport { freezeStore } from './freeze-store.ts'\r\nimport type { FrozenTier } from './freeze-store.ts'\r\nimport type { SteerQueueDockInjected } from './steer-queue-dock.tsx'\r\nimport { sessionGuardResume, sessionGuardStopNextTurn } from './session-guard-bridge.ts'\r\nimport css from './freeze-button.module.css'\r\n\r\n/**\r\n * Full props of the composer-right entry.\r\n *\r\n * The slot carries no `InputZone` owner on this segment (0.1.5 keeps the\r\n * ownerless shape introduced in 0.1.2, `InputBar.tsx:466` renders `{}`); only\r\n * the session standard kit is shared, so the type declares exactly that —\r\n * reading `session`/`input` off this slot is a compile error, not a crash.\r\n */\r\nexport type FreezeButtonProps =\r\n Pick<PropsRuntime<'conversation.input.right'>, 'useSession' | 'sessionId'>\r\n & SteerQueueDockInjected\r\n & PropsLocale<'steer'>\r\n\r\n/**\r\n * Freeze/resume toggle for the peak-hour scenario.\r\n * @param props - slot props; the session snapshot drives the detach list.\r\n */\r\nexport function FreezeButton({ useSession, updateQueue, cancel, send, sendSteer, sessionId, setComposerBlock, notify, t }: FreezeButtonProps) {\r\n // The freeze store is keyed by session: read the owning session's snapshot.\r\n const sid = sessionId ?? ''\r\n const { frozen } = useSyncExternalStore(freezeStore.subscribe, () => freezeStore.getSnapshot(sid))\r\n const queue = useSession(s => s.queue)\r\n\r\n const freeze = async (): Promise<void> => {\r\n // Detach every pending input row — queued (next-turn) and already-steered\r\n // (next-step) alike — so nothing stays in the live queue while frozen.\r\n // Steered rows keep their next intent as a safe_point plan for resume.\r\n const rows = queue.filter(row => row.placement === 'queued' || row.placement === 'steering')\r\n // Preserve plain-text copies; non-text rows cannot be re-sent and are\r\n // released by the freeze (documented limitation).\r\n const pending: { text: string; tier: FrozenTier }[] = rows.flatMap(row =>\r\n row.text === null ? [] : [{ text: row.text, tier: row.placement === 'steering' ? 'safe_point' : 'queue' }],\r\n )\r\n // Detach every pending row: the running turn finishes naturally, then the\r\n // driver finds no pending work and stops.\r\n await Promise.all(rows.map(row =>\r\n updateQueue(row.id, { kind: 'remove' }).catch(() => undefined),\r\n ))\r\n freezeStore.set(sid, { frozen: true, pending })\r\n // Raise the composer block: while frozen the composer is inert, so plain\r\n // Enter can never leak a new message into the conversation (busyEnter\r\n // only gates busy sessions; an idle/paused session would send directly).\r\n setComposerBlock?.(t('steer.frozenInput'))\r\n // 服务端:停掉 session 下一回合(fail-open,session-guard 未装则静默)。\r\n if (sessionId !== undefined) void sessionGuardStopNextTurn(sessionId)\r\n }\r\n\r\n const resume = async (): Promise<void> => {\r\n const pending = freezeStore.getSnapshot(sid).pending\r\n freezeStore.set(sid, { frozen: false, pending: [] })\r\n setComposerBlock?.(undefined)\r\n try {\r\n // 先恢复服务端会话:被打断回合的自然下一步(deferredTools 续跑)先发生。\r\n // 之后再重投队列 —— later 级条目经 send 进入 next-turn,排在自然 next turn\r\n // 之后;safe_point/force 仍按各自语义插队。顺序倒置会让 later 抢在自然\r\n // next turn 前被消费(idle 态 send 立即唤醒新回合)。\r\n if (sessionId !== undefined) await sessionGuardResume(sessionId)\r\n // Re-submit the preserved queue in FIFO order honoring each entry's\r\n // planned insertion tier: force (red) interrupts the current run first,\r\n // safe_point (yellow) steers into the next step, queue (green) flows\r\n // through the wake-and-continue chain.\r\n for (const entry of pending) {\r\n if (entry.tier === 'force') await cancel()\r\n if (entry.tier === 'safe_point' && sendSteer !== undefined) await sendSteer(entry.text)\r\n else await send(entry.text)\r\n }\r\n } catch {\r\n notify('error', t('steer.resumeFailed'))\r\n }\r\n }\r\n\r\n return (\r\n <button\r\n type=\"button\"\r\n className={css.freeze}\r\n aria-label={frozen ? t('steer.resume') : t('steer.freeze')}\r\n aria-pressed={frozen || undefined}\r\n title={frozen ? t('steer.frozen') : undefined}\r\n onClick={() => {\r\n if (frozen) void resume()\r\n else void freeze()\r\n }}\r\n >\r\n <span className={css.label}>{frozen ? t('steer.resume') : t('steer.freeze')}</span>\r\n </button>\r\n )\r\n}\r\n","/**\r\n * Busy-Enter row hiding: shadows the official `settings.general.item` entry\r\n * `composer-enter` (same cell id, priority -1) so the lower priority wins and\r\n * the official \"繁忙时 Enter 键行为\" row never renders while this plugin is\r\n * mounted.\r\n *\r\n * The behavior itself is taken over by the plugin: plain Enter stays\r\n * queue-later (green), the planning dock owns yellow/red, and the plugin apply\r\n * pins `ui-conversation.busyEnter` to `queue` so no stale preference can\r\n * leak through the hidden row.\r\n */\r\nimport type { PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\r\n\r\n/** Full props of a settings-row entry (unused: the row renders nothing). */\r\nexport type HideEnterRowProps = PropsRuntime<'settings.general.item'> & PropsLocale<'steer'>\r\n\r\n/** Render nothing: the official busy-Enter row is hidden while mounted. */\r\nexport function HideEnterRow(_props: HideEnterRowProps): null {\r\n return null\r\n}\r\n","/**\r\n * dsh-input-traffic —browser half.\r\n *\r\n * The whole takeover lives here:\r\n * 1. registers the `steer` dictionaries;\r\n * 2. pins `ui-conversation.busyEnter` to `queue` (plain Enter = green later)\r\n * so the hidden official row cannot leak a stale queue/steer preference;\r\n * 3. shadows the official queue dock (`conversation.input.dock` cell id\r\n * `queue`, priority -1) with the three-tier planning strip;\r\n * 4. shadows the official busy-Enter settings row (`settings.general.item`\r\n * cell id `composer-enter`, priority -1) with a null render.\r\n *\r\n * ORDERING (why the dock registers at QUEUE_DOCK_ORDER instead of the\r\n * official dock's 20): a list slot's DISPLAY position is decided by `order`\r\n * alone — `ui-renderer/src/client/scoped-slots.tsx` maps the shadowing\r\n * winners to rows and then sorts them by `order` — while `priority` only\r\n * decides which entry wins a shared cell id. Keeping the official 20\r\n * therefore left the strip above any later contributor (dsh-perm-gate's\r\n * notice registers order 30), which pushed that notice between the queue\r\n * strip and the composer card. A deliberately high order keeps the strip\r\n * adjacent to the card; priority stays -1 so the cell takeover still holds.\r\n * Known `conversation.input.dock` contributors on 0.1.5-rc.2: `todo` 0,\r\n * `goal` 10, official `queue` 20, `dsh-perm-gate.notice` 30. Note 0.1.5 also\r\n * introduces adjacent slots (`conversation.composer.dock`,\r\n * `conversation.input.left`) — a third party registering a larger `order`\r\n * inside this slot could still land below us.\r\n *\r\n * All @deepseek-ai/* imports are type-only: collaboration happens through\r\n * cordis services and slot registration only (client bundle purity).\r\n */\r\nimport type { Context as ClientContext } from '@deepseek-ai/cordis'\r\nimport type { SessionId } from '@deepseek-ai/dsh-session/types'\r\nimport type {} from '@deepseek-ai/dsh-client-locale/client'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-settings/client'\r\nimport type {} from '@deepseek-ai/dsh-client-ui-conversation/client'\r\nimport { NS, en, zh } from './locales.ts'\r\nimport { SteerQueueDock } from './steer-queue-dock.tsx'\r\nimport type { SteerQueueDockInjected } from './steer-queue-dock.tsx'\r\nimport { FreezeButton } from './freeze-button.tsx'\r\nimport { HideEnterRow } from './hide-enter-row.tsx'\r\n\r\n/** Durable conversation settings namespace owned by ui-conversation. */\r\nconst CONVERSATION_SETTINGS_NAMESPACE = 'ui-conversation'\r\n\r\n/** Busy-Enter field inside that namespace; the plugin pins it to queue. */\r\nconst BUSY_ENTER_FIELD = 'busyEnter'\r\n\r\n/**\r\n * Display order of the queue strip inside `conversation.input.dock`.\r\n *\r\n * List rows render sorted by `order` ascending, so a value above every other\r\n * contributor keeps the strip as the bottom-most entry of the band — directly\r\n * on top of the composer card. Known contributors on 0.1.5-rc.2: `todo` 0,\r\n * `goal` 10, official `queue` 20, `dsh-perm-gate.notice` 30. DSH has no \"last\"\r\n * slot semantics, so this is a convention, not a\r\n * structural guarantee: a third party registering a larger value could still\r\n * land below us.\r\n */\r\nexport const QUEUE_DOCK_ORDER = 1000\r\n\r\n/**\r\n * Deliver one plain-text message into the session's next step. The exposed\r\n * conversation `send` verb only queues into the next turn, so resume steers\r\n * through the session face's steer-mode prompt instead (no harness change).\r\n * @param ctx - root context (resolves the session face behind the scope).\r\n * @param actx - agent-scoped context of the owning session.\r\n * @param text - message text to deliver.\r\n */\r\nfunction steerPrompt(actx: ClientContext, text: string): Promise<void> {\r\n // steer-mode prompt 面在本版(main@0.2.8)契约中未声明;resume 落到 conversation.send\r\n // (排队到下一轮)交付 safe_point 文本,与 feature 分支语义对齐但取当前可用 API。\r\n const conversation = actx.get('conversation')\r\n if (conversation === undefined) return Promise.reject(new Error('steer resume: conversation service unavailable'))\r\n return conversation.send(text)\r\n}\r\n\r\n/** Services required by the browser half. */\r\nexport const inject = ['slots', 'locale', 'sessions', 'conversation', 'settingsScope']\r\n\r\n/**\r\n * Client plugin body: dictionaries, busy-Enter pinning, and the two slot\r\n * shadowings.\r\n * @param ctx - client root context.\r\n */\r\nexport function apply(ctx: ClientContext): void {\r\n ctx.effect(() => ctx.locale.register(NS, { zh, en }), 'dsh-input-traffic: dictionaries')\r\n\r\n // Take over the busy-Enter behavior: plain Enter stays queue-later while\r\n // the official row is hidden. Pinning here also repairs a persisted `steer`\r\n // preference that would otherwise keep working invisibly behind the hidden\r\n // row. Best-effort: a memory-mode host simply accepts it locally.\r\n const conversationSettings = ctx.settingsScope.bind<{ busyEnter: 'queue' | 'steer' }>({\r\n namespace: CONVERSATION_SETTINGS_NAMESPACE,\r\n })\r\n void conversationSettings.set(BUSY_ENTER_FIELD, 'queue')\r\n\r\n // Shadow the official queue dock with the three-tier planning strip. The\r\n // high `order` keeps it the bottom-most entry of the band (see the file\r\n // header); `priority: -1` is what wins the official `queue` cell.\r\n ctx.slots.inject('conversation.input.dock', () => ctx.slots.register({\r\n name: 'conversation.input.dock',\r\n id: 'queue',\r\n order: QUEUE_DOCK_ORDER,\r\n priority: -1,\r\n locale: NS,\r\n inject: (sessionId: SessionId): SteerQueueDockInjected => {\r\n const actx = ctx.sessions.scope(sessionId)\r\n if (actx === undefined) throw new Error(`steer dock: session \"${sessionId}\" resolved no scope`)\r\n const conversation = actx.get('conversation')\r\n if (conversation === undefined) throw new Error('steer dock: conversation service unavailable')\r\n return {\r\n updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),\r\n cancel: () => conversation.cancel(),\r\n send: (text) => conversation.send(text),\r\n setDraft: (text) => { conversation.input.for(actx).actions.setDraft(text) },\r\n notify: (level, text) => { conversation.input.for(actx).notify(level, text) },\r\n }\r\n },\r\n }, SteerQueueDock))\r\n\r\n // Composer-right freeze/resume control (reachable before anything queues).\r\n ctx.slots.inject('conversation.input.right', () => ctx.slots.register({\r\n name: 'conversation.input.right',\r\n id: 'steer-freeze',\r\n order: 30,\r\n locale: NS,\r\n inject: (sessionId: SessionId): SteerQueueDockInjected => {\r\n const actx = ctx.sessions.scope(sessionId)\r\n if (actx === undefined) throw new Error(`steer freeze: session \"${sessionId}\" resolved no scope`)\r\n const conversation = actx.get('conversation')\r\n if (conversation === undefined) throw new Error('steer freeze: conversation service unavailable')\r\n return {\r\n updateQueue: (itemId, action) => conversation.updateQueue(itemId, action),\r\n cancel: () => conversation.cancel(),\r\n send: (text) => conversation.send(text),\r\n // safe_point 恢复经 conversation.send 排队到下一轮(本版契约无 steer prompt 面)。\r\n sendSteer: (text) => steerPrompt(actx, text),\r\n sessionId: String(sessionId),\r\n setDraft: (text) => { conversation.input.for(actx).actions.setDraft(text) },\r\n notify: (level, text) => { conversation.input.for(actx).notify(level, text) },\r\n // 冻结期间 raise composer block:composer 变 inert(回车/发送按钮全部失效),\r\n // 输入不会漏进对话;恢复时清除。block 不锁 input.right(恢复按钮仍可点)。\r\n setComposerBlock: (reason) => {\r\n conversation.blocks.set(sessionId, reason === undefined ? undefined : { reason })\r\n },\r\n }\r\n },\r\n }, FreezeButton))\r\n\r\n // Hide the official busy-Enter settings row (null render wins the cell).\r\n ctx.slots.inject('settings.general.item', () => ctx.slots.register({\r\n name: 'settings.general.item',\r\n id: 'composer-enter',\r\n order: 20,\r\n priority: -1,\r\n locale: NS,\r\n }, HideEnterRow))\r\n}\r\n"],"mappings":"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"}
|
|
@@ -3,10 +3,10 @@ import type { SteerQueueDockInjected } from './steer-queue-dock.tsx';
|
|
|
3
3
|
/**
|
|
4
4
|
* Full props of the composer-right entry.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* shared, so the type declares exactly that —
|
|
9
|
-
* this slot is a compile error, not a
|
|
6
|
+
* The slot carries no `InputZone` owner on this segment (0.1.5 keeps the
|
|
7
|
+
* ownerless shape introduced in 0.1.2, `InputBar.tsx:466` renders `{}`); only
|
|
8
|
+
* the session standard kit is shared, so the type declares exactly that —
|
|
9
|
+
* reading `session`/`input` off this slot is a compile error, not a crash.
|
|
10
10
|
*/
|
|
11
11
|
export type FreezeButtonProps = Pick<PropsRuntime<'conversation.input.right'>, 'useSession' | 'sessionId'> & SteerQueueDockInjected & PropsLocale<'steer'>;
|
|
12
12
|
/**
|
|
@@ -13,13 +13,17 @@
|
|
|
13
13
|
* ORDERING (why the dock registers at QUEUE_DOCK_ORDER instead of the
|
|
14
14
|
* official dock's 20): a list slot's DISPLAY position is decided by `order`
|
|
15
15
|
* alone — `ui-renderer/src/client/scoped-slots.tsx` maps the shadowing
|
|
16
|
-
* winners to rows and then sorts them by `order`
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
16
|
+
* winners to rows and then sorts them by `order` — while `priority` only
|
|
17
|
+
* decides which entry wins a shared cell id. Keeping the official 20
|
|
18
|
+
* therefore left the strip above any later contributor (dsh-perm-gate's
|
|
19
|
+
* notice registers order 30), which pushed that notice between the queue
|
|
20
|
+
* strip and the composer card. A deliberately high order keeps the strip
|
|
21
|
+
* adjacent to the card; priority stays -1 so the cell takeover still holds.
|
|
22
|
+
* Known `conversation.input.dock` contributors on 0.1.5-rc.2: `todo` 0,
|
|
23
|
+
* `goal` 10, official `queue` 20, `dsh-perm-gate.notice` 30. Note 0.1.5 also
|
|
24
|
+
* introduces adjacent slots (`conversation.composer.dock`,
|
|
25
|
+
* `conversation.input.left`) — a third party registering a larger `order`
|
|
26
|
+
* inside this slot could still land below us.
|
|
23
27
|
*
|
|
24
28
|
* All @deepseek-ai/* imports are type-only: collaboration happens through
|
|
25
29
|
* cordis services and slot registration only (client bundle purity).
|
|
@@ -30,9 +34,9 @@ import type { Context as ClientContext } from '@deepseek-ai/cordis';
|
|
|
30
34
|
*
|
|
31
35
|
* List rows render sorted by `order` ascending, so a value above every other
|
|
32
36
|
* contributor keeps the strip as the bottom-most entry of the band — directly
|
|
33
|
-
* on top of the composer card. Known contributors
|
|
34
|
-
*
|
|
35
|
-
*
|
|
37
|
+
* on top of the composer card. Known contributors on 0.1.5-rc.2: `todo` 0,
|
|
38
|
+
* `goal` 10, official `queue` 20, `dsh-perm-gate.notice` 30. DSH has no "last"
|
|
39
|
+
* slot semantics, so this is a convention, not a
|
|
36
40
|
* structural guarantee: a third party registering a larger value could still
|
|
37
41
|
* land below us.
|
|
38
42
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,KAAK,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAA;AAiBnE;;;;;;;;;;GAUG;AACH,eAAO,MAAM,gBAAgB,OAAO,CAAA;AAkBpC,6CAA6C;AAC7C,eAAO,MAAM,MAAM,UAAmE,CAAA;AAEtF;;;;GAIG;AACH,wBAAgB,KAAK,CAAC,GAAG,EAAE,aAAa,GAAG,IAAI,CAyE9C"}
|
|
@@ -11,9 +11,9 @@ const BUSY_ENTER_FIELD = 'busyEnter';
|
|
|
11
11
|
*
|
|
12
12
|
* List rows render sorted by `order` ascending, so a value above every other
|
|
13
13
|
* contributor keeps the strip as the bottom-most entry of the band — directly
|
|
14
|
-
* on top of the composer card. Known contributors
|
|
15
|
-
*
|
|
16
|
-
*
|
|
14
|
+
* on top of the composer card. Known contributors on 0.1.5-rc.2: `todo` 0,
|
|
15
|
+
* `goal` 10, official `queue` 20, `dsh-perm-gate.notice` 30. DSH has no "last"
|
|
16
|
+
* slot semantics, so this is a convention, not a
|
|
17
17
|
* structural guarantee: a third party registering a larger value could still
|
|
18
18
|
* land below us.
|
|
19
19
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/client/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-guard-bridge.d.ts","sourceRoot":"","sources":["../../../src/client/session-guard-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,4DAA4D;AAC5D,wBAAsB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAElF;AAED,qCAAqC;AACrC,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE5E;AAoBD,OAAO,CAAC,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"session-guard-bridge.d.ts","sourceRoot":"","sources":["../../../src/client/session-guard-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,4DAA4D;AAC5D,wBAAsB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAElF;AAED,qCAAqC;AACrC,wBAAsB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAE5E;AAoBD,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,4BAA4B,EAAE,OAAO,GAAG,SAAS,CAAA;CACtD"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session-guard-bridge.js","sourceRoot":"","sources":["../../../src/client/session-guard-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,4DAA4D;AAC5D,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,SAAiB;IAC9D,OAAO,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC,CAAA;AAC7C,CAAC;AAED,qCAAqC;AACrC,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,SAAiB;IACxD,OAAO,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;AACvC,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,SAAiB,EAAE,MAAc;IACxD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,EAAE;YAC5C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;SAC5C,CAAC,CAAA;QACF,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,KAAK,CAAA;QACzB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;QAC/C,OAAO,IAAI,EAAE,EAAE,KAAK,IAAI,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,6CAA6C;QAC7C,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;
|
|
1
|
+
{"version":3,"file":"session-guard-bridge.js","sourceRoot":"","sources":["../../../src/client/session-guard-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,4DAA4D;AAC5D,MAAM,CAAC,KAAK,UAAU,wBAAwB,CAAC,SAAiB;IAC9D,OAAO,SAAS,CAAC,SAAS,EAAE,cAAc,CAAC,CAAA;AAC7C,CAAC;AAED,qCAAqC;AACrC,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,SAAiB;IACxD,OAAO,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAA;AACvC,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,SAAiB,EAAE,MAAc;IACxD,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,oBAAoB,EAAE;YAC5C,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,SAAS,EAAE,MAAM,EAAE,CAAC;SAC5C,CAAC,CAAA;QACF,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,KAAK,CAAA;QACzB,MAAM,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAA;QAC/C,OAAO,IAAI,EAAE,EAAE,KAAK,IAAI,CAAA;IAC1B,CAAC;IAAC,MAAM,CAAC;QACP,6CAA6C;QAC7C,OAAO,KAAK,CAAA;IACd,CAAC;AACH,CAAC;AAOD,IAAI,CAAC;IACH,UAAU,CAAC,4BAA4B,GAAG,IAAI,CAAA;AAChD,CAAC;AAAC,MAAM,CAAC;IACP,uBAAuB;AACzB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-input-traffic",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"registry": "https://registry.npmjs.org",
|
|
6
6
|
"access": "public",
|
|
7
|
-
"tag": "dsh-0.1.
|
|
7
|
+
"tag": "dsh-0.1.5"
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
10
|
"description": "Busy-time input queue for the DeepSeek Harness web GUI: three-tier (now/next/later) planning, queue editing with drag-to-reorder and concurrency protection, interject (steer) and interrupt, batch clear with confirm, session freeze - a cordis client plugin, no dsh source changes, no PR required",
|
|
@@ -64,17 +64,17 @@
|
|
|
64
64
|
},
|
|
65
65
|
"engines": {
|
|
66
66
|
"node": ">=20",
|
|
67
|
-
"dsh": ">=0.1.
|
|
67
|
+
"dsh": ">=0.1.5-alpha.1 <0.2.0-0"
|
|
68
68
|
},
|
|
69
69
|
"license": "MIT",
|
|
70
70
|
"peerDependencies": {
|
|
71
71
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
72
|
-
"@deepseek-ai/dsh-client-locale": ">=0.1.
|
|
73
|
-
"@deepseek-ai/dsh-client-ui-conversation": ">=0.1.
|
|
74
|
-
"@deepseek-ai/dsh-client-ui-primitives": ">=0.1.
|
|
75
|
-
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.
|
|
76
|
-
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.
|
|
77
|
-
"@deepseek-ai/dsh-session": ">=0.1.
|
|
72
|
+
"@deepseek-ai/dsh-client-locale": ">=0.1.5-alpha.1 <0.2.0-0",
|
|
73
|
+
"@deepseek-ai/dsh-client-ui-conversation": ">=0.1.5-alpha.1 <0.2.0-0",
|
|
74
|
+
"@deepseek-ai/dsh-client-ui-primitives": ">=0.1.5-alpha.1 <0.2.0-0",
|
|
75
|
+
"@deepseek-ai/dsh-client-ui-settings": ">=0.1.5-alpha.1 <0.2.0-0",
|
|
76
|
+
"@deepseek-ai/dsh-client-ui-slots": ">=0.1.5-alpha.1 <0.2.0-0",
|
|
77
|
+
"@deepseek-ai/dsh-session": ">=0.1.5-alpha.1 <0.2.0-0"
|
|
78
78
|
},
|
|
79
79
|
"peerDependenciesMeta": {
|
|
80
80
|
"@deepseek-ai/cordis": {
|