dsh-input-traffic 0.6.0 → 0.6.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.ja.md CHANGED
@@ -6,6 +6,13 @@
6
6
  - [日本語 changelog](./CHANGELOG.ja.md)
7
7
  - [한국어 changelog](./CHANGELOG.ko.md)
8
8
 
9
+ ## 0.6.1 — 2026-09-30
10
+
11
+ ### 修正: キュー行を inbox プロジェクションから読むよう修正(実機検証済み)
12
+
13
+ - 実ホストではキュー行がセッションスナップショットに存在しないため、useProjection('inbox') から読むよう修正。従来の鏡像フィールド参照は実機で必ずクラッシュし、公式キューへフォールバックしていた。
14
+ - 損壊した「入力へ戻す」ボタンを削除(黄ティアが挿入の唯一の入口)。ティア色をリテラル値に固定。
15
+
9
16
  ## 0.6.0 — 2026-09-29
10
17
 
11
18
  ### DSH 0.2.0 対応(compat/0.2.0 ライン、dist-tag `dsh-0.2.0`)
package/CHANGELOG.ko.md CHANGED
@@ -6,6 +6,13 @@
6
6
  - [日本語 changelog](./CHANGELOG.ja.md)
7
7
  - [한국어 changelog](./CHANGELOG.ko.md)
8
8
 
9
+ ## 0.6.1 — 2026-09-30
10
+
11
+ ### 修正: キュー行を inbox プロジェクションから読むよう修正(実機検証済み)
12
+
13
+ - 実ホストではキュー行がセッションスナップショットに存在しないため、useProjection('inbox') から読むよう修正。従来の鏡像フィールド参照は実機で必ずクラッシュし、公式キューへフォールバックしていた。
14
+ - 損壊した「入力へ戻す」ボタンを削除(黄ティアが挿入の唯一の入口)。ティア色をリテラル値に固定。
15
+
9
16
  ## 0.6.0 — 2026-09-29
10
17
 
11
18
  ### DSH 0.2.0 대응(compat/0.2.0 라인, dist-tag `dsh-0.2.0`)
package/CHANGELOG.md CHANGED
@@ -2,6 +2,16 @@
2
2
 
3
3
  所有重要变更与 bug 修复记录于此。版本遵循语义化版本(`dsh plugin --profile web add dsh-input-traffic` 安装)。
4
4
 
5
+ ## 0.6.1 — 2026-09-30
6
+
7
+ ### 修复:队列行改读 inbox 投影(真实宿主渲染修复)
8
+
9
+ - 真实宿主的排队行不在会话快照上:组件改从 useProjection('inbox') 读取(next-turn=排队/绿档,next-step=插话/黄档),与官方 QueueDock 同源。此前读取的 s.queue 为镜像自造字段,行渲染必崩并回退官方队列。
10
+ - queueMutable 与官方判定对齐(continuable 子代理上下文亦可操作)。
11
+ - 移除真机上失效的「打回输入框」按钮;黄色档位是唯一插话入口。
12
+ - 行文本改由 content 块派生(textOf,对齐官方);三色圆点固定字面量配色(自定义皮肤重定义 warn 别名会洗掉黄色)。
13
+ - CSS 压制官方 QueueDock 容器;修复 verify-assembly 陈旧断言(settingsScope → configForms)。
14
+
5
15
  ## 0.6.0 — 2026-09-29
6
16
 
7
17
  ### DSH 0.2.0 适配(compat/0.2.0 线,dist-tag `dsh-0.2.0`)
package/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-external/dsh-input-traffic",
3
- "version": "0.6.0",
3
+ "version": "0.6.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": {
package/lib/client.js CHANGED
@@ -211,7 +211,7 @@ window.__ModuleLoader__.load({
211
211
  }
212
212
  //#endregion
213
213
  //#region \0dsh-css:E:\test\rewrite-agently\mine-dsh-plugins\_wt-020\dsh-input-traffic\src\client\steer-queue-dock.module.css.mjs
214
- const css$1 = ".jJPyLG_dock{box-sizing:border-box;width:min(calc(100% - var(--dsh-composer-side-clearance,16px) - var(--dsh-composer-side-clearance,16px) - var(--dsh-composer-dock-inset,8px) - var(--dsh-composer-dock-inset,8px)), calc(var(--dsh-chat-content-width,100%) - var(--dsh-composer-dock-inset,8px) - var(--dsh-composer-dock-inset,8px)));max-width:calc(var(--dsh-composer-card-max-width,var(--dsh-chat-content-width,100%)) - var(--dsh-composer-dock-inset,8px) - var(--dsh-composer-dock-inset,8px));padding:0 var(--dsh-composer-dock-inset,8px);flex:none;margin:0 auto}.jJPyLG_panel{background:var(--dsw-alias-bg-layer-1,#fffc);border:1px solid var(--dsw-alias-border-l2,#00000014);border-radius:10px;overflow:hidden}.jJPyLG_toolbar{border-bottom:1px solid var(--dsw-alias-border-l2,#0000000f);align-items:center;gap:8px;padding:4px 8px;display:flex}.jJPyLG_header{color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border:0;align-items:center;gap:6px;padding:2px 6px;font-size:12px;display:inline-flex}.jJPyLG_header:disabled{cursor:default}.jJPyLG_lead{color:var(--dsw-alias-label-tertiary,#9ca3af);display:inline-flex}.jJPyLG_count{font-weight:600}.jJPyLG_chevron{color:var(--dsw-alias-label-tertiary,#9ca3af);display:inline-flex}.jJPyLG_toolbarActions{margin-left:auto}.jJPyLG_clear{color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;align-items:center;gap:4px;padding:3px 8px;font-size:12px;display:inline-flex}.jJPyLG_freeze{border:1px solid var(--dsw-alias-border-l3,#0000001f);color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border-radius:6px;align-items:center;gap:4px;padding:3px 8px;font-size:12px;display:inline-flex}.jJPyLG_freeze[aria-pressed=true]{border-color:var(--dsw-alias-state-success-primary,#30a46c);color:var(--dsw-alias-state-success-primary,#30a46c)}.jJPyLG_freeze:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000a)}.jJPyLG_freeze:disabled{opacity:.5;cursor:default}.jJPyLG_frozenBanner{border-bottom:1px solid var(--dsw-alias-border-l2,#0000000f);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#30a46c) 8%, transparent);color:var(--dsw-alias-state-success-primary,#30a46c);padding:4px 10px;font-size:12px}.jJPyLG_frozenList{margin:0;padding:4px;list-style:none}.jJPyLG_frozenRow{border-radius:6px;align-items:center;gap:8px;padding:4px 6px;display:flex}.jJPyLG_frozenMark{color:var(--dsw-alias-label-tertiary,#9ca3af);flex:none;margin-left:auto;font-size:11px}.jJPyLG_clear:hover:not(:disabled){border-color:var(--dsw-alias-border-l3,#0000001f);background:var(--dsw-alias-interactive-bg-hover,#0000000a)}.jJPyLG_clear:disabled{opacity:.5;cursor:default}.jJPyLG_clearConfirm{border-color:var(--dsw-alias-state-error-primary,#e5484d);color:var(--dsw-alias-state-error-primary,#e5484d)}.jJPyLG_clearConfirm:hover:not(:disabled){border-color:var(--dsw-alias-state-error-primary,#e5484d);background:color-mix(in srgb, var(--dsw-alias-state-error-primary,#e5484d) 8%, transparent)}.jJPyLG_clearCancel{color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;align-items:center;gap:4px;padding:3px 8px;font-size:12px;display:inline-flex}.jJPyLG_clearCancel:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000a)}.jJPyLG_clearLabel{font-size:12px}.jJPyLG_list{margin:0;padding:4px;list-style:none}.jJPyLG_row{border-radius:6px;align-items:center;gap:8px;padding:4px 6px;display:flex}.jJPyLG_row[draggable=true]{cursor:grab}.jJPyLG_row[draggable=true]:active{cursor:grabbing}.jJPyLG_rowDragOver{outline:2px dashed var(--dsw-alias-border-l4,#00000040);outline-offset:-2px;background:var(--dsw-alias-interactive-bg-hover,#0000000d)}.jJPyLG_row:hover{background:var(--dsw-alias-interactive-bg-hover,#00000008)}.jJPyLG_row[data-editing]{align-items:flex-start}.jJPyLG_preview{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary,#1f2937);flex:1;font-size:13px;overflow:hidden}.jJPyLG_badge{white-space:nowrap;border-radius:999px;flex:none;align-items:center;gap:4px;padding:1px 6px;font-size:11px;line-height:16px;display:inline-flex}.jJPyLG_badgeLabel{color:inherit}.jJPyLG_badgeNow{color:var(--dsw-alias-state-error-primary,#e5484d);background:color-mix(in srgb, var(--dsw-alias-state-error-primary,#e5484d) 10%, transparent)}.jJPyLG_badgeNext{color:var(--dsw-alias-state-warn-primary,#e8a33d);background:color-mix(in srgb, var(--dsw-alias-state-warn-primary,#e8a33d) 12%, transparent)}.jJPyLG_badgeLater{color:var(--dsw-alias-state-success-primary,#30a46c);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#30a46c) 12%, transparent)}.jJPyLG_badgeNow .jJPyLG_dot{background:var(--dsw-alias-state-error-primary,#e5484d)}.jJPyLG_badgeNext .jJPyLG_dot{background:var(--dsw-alias-state-warn-primary,#e8a33d)}.jJPyLG_badgeLater .jJPyLG_dot{background:var(--dsw-alias-state-success-primary,#30a46c)}.jJPyLG_steeringList{margin:0;padding:0 4px 4px;list-style:none}.jJPyLG_steeringList .jJPyLG_row{opacity:.85}.jJPyLG_editor{border:1px solid var(--dsw-alias-border-l3,#00000026);background:var(--dsw-alias-bg-layer-2,#fff);resize:none;border-radius:6px;flex:1;min-width:0;max-height:160px;padding:4px 6px;font-size:13px;line-height:20px;overflow-y:auto}.jJPyLG_actions{align-items:center;gap:2px;display:inline-flex}.jJPyLG_action{width:24px;height:24px;color:var(--dsw-alias-label-tertiary,#9ca3af);cursor:pointer;background:0 0;border:0;border-radius:6px;justify-content:center;align-items:center;display:inline-flex}.jJPyLG_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000d);color:var(--dsw-alias-label-primary,#1f2937)}.jJPyLG_action:disabled{opacity:.4;cursor:default}.jJPyLG_plan{border-left:1px solid var(--dsw-alias-border-l2,#00000014);align-items:center;gap:2px;margin-left:4px;padding-left:6px;display:inline-flex}.jJPyLG_tier{cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;justify-content:center;align-items:center;width:20px;height:20px;padding:0;display:inline-flex}.jJPyLG_tier:hover:not(:disabled){border-color:var(--dsw-alias-border-l4,#0003)}.jJPyLG_tier:disabled{cursor:default}.jJPyLG_tierLater{border-color:var(--dsw-alias-state-success-primary,#30a46c);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#30a46c) 12%, transparent)}.jJPyLG_dot{border-radius:50%;width:10px;height:10px}.jJPyLG_tierNow .jJPyLG_dot{background:var(--dsw-alias-state-error-primary,#e5484d)}.jJPyLG_tierNext .jJPyLG_dot{background:var(--dsw-alias-state-warn-primary,#e8a33d)}.jJPyLG_tierLater .jJPyLG_dot{background:var(--dsw-alias-state-success-primary,#30a46c)}";
214
+ const css$1 = ".jJPyLG_dock{box-sizing:border-box;width:min(calc(100% - var(--dsh-composer-side-clearance,16px) - var(--dsh-composer-side-clearance,16px) - var(--dsh-composer-dock-inset,8px) - var(--dsh-composer-dock-inset,8px)), calc(var(--dsh-chat-content-width,100%) - var(--dsh-composer-dock-inset,8px) - var(--dsh-composer-dock-inset,8px)));max-width:calc(var(--dsh-composer-card-max-width,var(--dsh-chat-content-width,100%)) - var(--dsh-composer-dock-inset,8px) - var(--dsh-composer-dock-inset,8px));padding:0 var(--dsh-composer-dock-inset,8px);flex:none;margin:0 auto}.jJPyLG_panel{background:var(--dsw-alias-bg-layer-1,#fffc);border:1px solid var(--dsw-alias-border-l2,#00000014);border-radius:10px;overflow:hidden}.jJPyLG_toolbar{border-bottom:1px solid var(--dsw-alias-border-l2,#0000000f);align-items:center;gap:8px;padding:4px 8px;display:flex}.jJPyLG_header{color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border:0;align-items:center;gap:6px;padding:2px 6px;font-size:12px;display:inline-flex}.jJPyLG_header:disabled{cursor:default}.jJPyLG_lead{color:var(--dsw-alias-label-tertiary,#9ca3af);display:inline-flex}.jJPyLG_count{font-weight:600}.jJPyLG_chevron{color:var(--dsw-alias-label-tertiary,#9ca3af);display:inline-flex}.jJPyLG_toolbarActions{margin-left:auto}.jJPyLG_clear{color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;align-items:center;gap:4px;padding:3px 8px;font-size:12px;display:inline-flex}.jJPyLG_freeze{border:1px solid var(--dsw-alias-border-l3,#0000001f);color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border-radius:6px;align-items:center;gap:4px;padding:3px 8px;font-size:12px;display:inline-flex}.jJPyLG_freeze[aria-pressed=true]{border-color:var(--dsw-alias-state-success-primary,#30a46c);color:var(--dsw-alias-state-success-primary,#30a46c)}.jJPyLG_freeze:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000a)}.jJPyLG_freeze:disabled{opacity:.5;cursor:default}.jJPyLG_frozenBanner{border-bottom:1px solid var(--dsw-alias-border-l2,#0000000f);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#30a46c) 8%, transparent);color:var(--dsw-alias-state-success-primary,#30a46c);padding:4px 10px;font-size:12px}.jJPyLG_frozenList{margin:0;padding:4px;list-style:none}.jJPyLG_frozenRow{border-radius:6px;align-items:center;gap:8px;padding:4px 6px;display:flex}.jJPyLG_frozenMark{color:var(--dsw-alias-label-tertiary,#9ca3af);flex:none;margin-left:auto;font-size:11px}.jJPyLG_clear:hover:not(:disabled){border-color:var(--dsw-alias-border-l3,#0000001f);background:var(--dsw-alias-interactive-bg-hover,#0000000a)}.jJPyLG_clear:disabled{opacity:.5;cursor:default}.jJPyLG_clearConfirm{border-color:var(--dsw-alias-state-error-primary,#e5484d);color:var(--dsw-alias-state-error-primary,#e5484d)}.jJPyLG_clearConfirm:hover:not(:disabled){border-color:var(--dsw-alias-state-error-primary,#e5484d);background:color-mix(in srgb, var(--dsw-alias-state-error-primary,#e5484d) 8%, transparent)}.jJPyLG_clearCancel{color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;align-items:center;gap:4px;padding:3px 8px;font-size:12px;display:inline-flex}.jJPyLG_clearCancel:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000a)}.jJPyLG_clearLabel{font-size:12px}.jJPyLG_list{margin:0;padding:4px;list-style:none}.jJPyLG_row{border-radius:6px;align-items:center;gap:8px;padding:4px 6px;display:flex}.jJPyLG_row[draggable=true]{cursor:grab}.jJPyLG_row[draggable=true]:active{cursor:grabbing}.jJPyLG_rowDragOver{outline:2px dashed var(--dsw-alias-border-l4,#00000040);outline-offset:-2px;background:var(--dsw-alias-interactive-bg-hover,#0000000d)}.jJPyLG_row:hover{background:var(--dsw-alias-interactive-bg-hover,#00000008)}.jJPyLG_row[data-editing]{align-items:flex-start}.jJPyLG_preview{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary,#1f2937);flex:1;font-size:13px;overflow:hidden}.jJPyLG_badge{white-space:nowrap;border-radius:999px;flex:none;align-items:center;gap:4px;padding:1px 6px;font-size:11px;line-height:16px;display:inline-flex}.jJPyLG_badgeLabel{color:inherit}.jJPyLG_badgeNow{color:var(--dsw-alias-state-error-primary,#e5484d);background:color-mix(in srgb, var(--dsw-alias-state-error-primary,#e5484d) 10%, transparent)}.jJPyLG_badgeNext{color:var(--dsw-alias-state-warn-primary,#e8a33d);background:color-mix(in srgb, var(--dsw-alias-state-warn-primary,#e8a33d) 12%, transparent)}.jJPyLG_badgeLater{color:var(--dsw-alias-state-success-primary,#30a46c);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#30a46c) 12%, transparent)}.jJPyLG_badgeNow .jJPyLG_dot{background:var(--dsw-alias-state-error-primary,#e5484d)}.jJPyLG_badgeNext .jJPyLG_dot{background:var(--dsw-alias-state-warn-primary,#e8a33d)}.jJPyLG_badgeLater .jJPyLG_dot{background:var(--dsw-alias-state-success-primary,#30a46c)}.jJPyLG_steeringList{margin:0;padding:0 4px 4px;list-style:none}.jJPyLG_steeringList .jJPyLG_row{opacity:.85}.jJPyLG_editor{border:1px solid var(--dsw-alias-border-l3,#00000026);background:var(--dsw-alias-bg-layer-2,#fff);resize:none;border-radius:6px;flex:1;min-width:0;max-height:160px;padding:4px 6px;font-size:13px;line-height:20px;overflow-y:auto}.jJPyLG_actions{align-items:center;gap:2px;display:inline-flex}.jJPyLG_action{width:24px;height:24px;color:var(--dsw-alias-label-tertiary,#9ca3af);cursor:pointer;background:0 0;border:0;border-radius:6px;justify-content:center;align-items:center;display:inline-flex}.jJPyLG_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000d);color:var(--dsw-alias-label-primary,#1f2937)}.jJPyLG_action:disabled{opacity:.4;cursor:default}.jJPyLG_plan{border-left:1px solid var(--dsw-alias-border-l2,#00000014);align-items:center;gap:2px;margin-left:4px;padding-left:6px;display:inline-flex}.jJPyLG_tier{cursor:pointer;background:0 0;border:1px solid #0000;border-radius:6px;justify-content:center;align-items:center;width:20px;height:20px;padding:0;display:inline-flex}.jJPyLG_tier:hover:not(:disabled){border-color:var(--dsw-alias-border-l4,#0003)}.jJPyLG_tier:disabled{cursor:default}.jJPyLG_tierNow{background:#e5484d1f;border-color:#e5484d}.jJPyLG_tierNext{background:#e8a33d1f;border-color:#e8a33d}.jJPyLG_tierLater{border-color:var(--dsw-alias-state-success-primary,#30a46c);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#30a46c) 12%, transparent)}.jJPyLG_dot{border-radius:50%;width:10px;height:10px}.jJPyLG_tierNow .jJPyLG_dot{background:#e5484d}.jJPyLG_tierNext .jJPyLG_dot{background:#e8a33d}.jJPyLG_tierLater .jJPyLG_dot{background:#30a46c}";
215
215
  const tagId$1 = "dsh-input-traffic/steer-queue-dock.module.css";
216
216
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
217
217
  const tag = document.createElement("style");
@@ -221,42 +221,42 @@ window.__ModuleLoader__.load({
221
221
  document.head.appendChild(tag);
222
222
  }
223
223
  var steer_queue_dock_module_css_default = {
224
+ "freeze": "jJPyLG_freeze",
225
+ "clearLabel": "jJPyLG_clearLabel",
226
+ "dock": "jJPyLG_dock",
224
227
  "clearConfirm": "jJPyLG_clearConfirm",
225
- "dot": "jJPyLG_dot",
228
+ "editor": "jJPyLG_editor",
226
229
  "plan": "jJPyLG_plan",
227
- "frozenBanner": "jJPyLG_frozenBanner",
230
+ "badgeNext": "jJPyLG_badgeNext",
231
+ "frozenMark": "jJPyLG_frozenMark",
232
+ "badge": "jJPyLG_badge",
233
+ "list": "jJPyLG_list",
234
+ "badgeNow": "jJPyLG_badgeNow",
228
235
  "clearCancel": "jJPyLG_clearCancel",
229
236
  "preview": "jJPyLG_preview",
230
- "editor": "jJPyLG_editor",
231
- "actions": "jJPyLG_actions",
232
- "badgeLater": "jJPyLG_badgeLater",
233
- "badgeLabel": "jJPyLG_badgeLabel",
234
- "frozenMark": "jJPyLG_frozenMark",
235
237
  "steeringList": "jJPyLG_steeringList",
236
- "count": "jJPyLG_count",
237
- "list": "jJPyLG_list",
238
+ "lead": "jJPyLG_lead",
239
+ "tierNow": "jJPyLG_tierNow",
240
+ "tierNext": "jJPyLG_tierNext",
241
+ "action": "jJPyLG_action",
242
+ "row": "jJPyLG_row",
243
+ "badgeLater": "jJPyLG_badgeLater",
244
+ "tier": "jJPyLG_tier",
238
245
  "frozenList": "jJPyLG_frozenList",
239
- "toolbarActions": "jJPyLG_toolbarActions",
246
+ "actions": "jJPyLG_actions",
247
+ "tierLater": "jJPyLG_tierLater",
240
248
  "chevron": "jJPyLG_chevron",
241
- "freeze": "jJPyLG_freeze",
242
- "badgeNext": "jJPyLG_badgeNext",
243
- "panel": "jJPyLG_panel",
244
- "row": "jJPyLG_row",
245
- "badgeNow": "jJPyLG_badgeNow",
246
- "dock": "jJPyLG_dock",
247
249
  "rowDragOver": "jJPyLG_rowDragOver",
248
- "tier": "jJPyLG_tier",
249
- "frozenRow": "jJPyLG_frozenRow",
250
- "tierNow": "jJPyLG_tierNow",
251
- "clearLabel": "jJPyLG_clearLabel",
250
+ "dot": "jJPyLG_dot",
251
+ "panel": "jJPyLG_panel",
252
+ "count": "jJPyLG_count",
252
253
  "toolbar": "jJPyLG_toolbar",
253
- "lead": "jJPyLG_lead",
254
+ "frozenRow": "jJPyLG_frozenRow",
255
+ "header": "jJPyLG_header",
256
+ "frozenBanner": "jJPyLG_frozenBanner",
254
257
  "clear": "jJPyLG_clear",
255
- "badge": "jJPyLG_badge",
256
- "action": "jJPyLG_action",
257
- "tierLater": "jJPyLG_tierLater",
258
- "tierNext": "jJPyLG_tierNext",
259
- "header": "jJPyLG_header"
258
+ "toolbarActions": "jJPyLG_toolbarActions",
259
+ "badgeLabel": "jJPyLG_badgeLabel"
260
260
  };
261
261
  //#endregion
262
262
  //#region src/client/steer-queue-dock.tsx
@@ -285,6 +285,22 @@ window.__ModuleLoader__.load({
285
285
  * run while preserving the queue (keepInbox), resume re-arms the driver by
286
286
  * re-sending the first queued row so the preserved work continues.
287
287
  */
288
+ /**
289
+ * Suppress the OFFICIAL queue dock entirely: our shadowing entry owns the
290
+ * `queue` cell, so the official dock is only ever mounted as a crash fallback
291
+ * — and its per-row 插话发送 duplicates our yellow tier. Hide the whole
292
+ * container by its css-module class (the `_7yHdaG` hash is baked into the
293
+ * host build and stable across restarts), plus the aria-label match as a
294
+ * second net in case the host rehashes.
295
+ */
296
+ const HIDE_OFFICIAL_QUEUE_CSS = "[class*=\"_7yHdaG_dock\"]{display:none!important}";
297
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=\"dsh-input-traffic/hide-official-steer\"]") === null) {
298
+ const tag = document.createElement("style");
299
+ tag.dataset.plugin = "dsh-input-traffic";
300
+ tag.dataset.pluginCss = "dsh-input-traffic/hide-official-steer";
301
+ tag.textContent = HIDE_OFFICIAL_QUEUE_CSS;
302
+ document.head.appendChild(tag);
303
+ }
288
304
  /** Busy marker for a whole-queue rebuild (reorder); locks every row action. */
289
305
  const REORDER_MARK = "__reorder__";
290
306
  /** localStorage key for the manual collapse state (dsh-queue-plus parity). */
@@ -311,15 +327,33 @@ window.__ModuleLoader__.load({
311
327
  el.style.height = `${el.scrollHeight}px`;
312
328
  }
313
329
  /**
330
+ * Concatenate a queued row's text blocks; null when the row carries anything
331
+ * non-text (attachments) or no content — mirrors the host queue dock's own
332
+ * helper (ui-conversation client.js `textOf`). Wire rows do NOT carry a
333
+ * `.text` field; the text lives in `content` blocks.
334
+ */
335
+ function textOf(content) {
336
+ if (content === void 0 || content.length === 0) return null;
337
+ if (!content.every((block) => block.type === "text")) return null;
338
+ const joined = content.map((block) => block.text ?? "").join("");
339
+ return joined === "" ? null : joined;
340
+ }
341
+ /**
314
342
  * Queue strip with three-tier planning: one item renders directly; multiple
315
343
  * items default to a collapsible count header; an empty queue renders nothing.
316
344
  */
317
- function SteerQueueDock({ sessionId, useSession, input, updateQueue, cancel, send, setDraft, notify, t }) {
318
- const inbox = useSession((s) => s.queue);
319
- const queue = (0, react.useMemo)(() => inbox.filter((row) => row.placement === "queued"), [inbox]);
320
- const steering = (0, react.useMemo)(() => inbox.filter((row) => row.placement === "steering"), [inbox]);
345
+ function SteerQueueDock({ sessionId, useSession, useProjection, input, updateQueue, cancel, send, setDraft, notify, t }) {
346
+ const inbox = useProjection("inbox");
347
+ const queue = (0, react.useMemo)(() => (inbox?.["next-turn"] ?? []).map((row) => ({
348
+ ...row,
349
+ text: textOf(row.content) ?? row.text ?? null
350
+ })), [inbox]);
351
+ const steering = (0, react.useMemo)(() => (inbox?.["next-step"] ?? []).map((row) => ({
352
+ ...row,
353
+ text: textOf(row.content) ?? row.text ?? null
354
+ })), [inbox]);
321
355
  const running = useSession((s) => s.running);
322
- const queueMutable = useSession((s) => s.subagent === null);
356
+ const queueMutable = useSession((s) => s.subagent === null || s.subagent.address.mode === "continuable");
323
357
  const [editing, setEditing] = (0, react.useState)(null);
324
358
  const [busy, setBusy] = (0, react.useState)(null);
325
359
  const [clearing, setClearing] = (0, react.useState)(false);
@@ -369,7 +403,6 @@ window.__ModuleLoader__.load({
369
403
  const planDisabled = !queueMutable || !running || frozen;
370
404
  const nothingPending = queue.length === 0 && steering.length === 0;
371
405
  const reorderUnsupported = queue.some((row) => row.text === null);
372
- const composerEmpty = input.draft.trim() === "";
373
406
  const applyAction = async (itemId, action, failure) => {
374
407
  setBusy(itemId);
375
408
  try {
@@ -383,7 +416,7 @@ window.__ModuleLoader__.load({
383
416
  }
384
417
  };
385
418
  const saveEdit = async () => {
386
- if (editing === null || editing.text.trim() === "") return;
419
+ if (editing === null || typeof editing.text !== "string" || editing.text.trim() === "") return;
387
420
  const itemId = editing.id;
388
421
  const text = editing.text;
389
422
  setBusy(itemId);
@@ -527,23 +560,6 @@ window.__ModuleLoader__.load({
527
560
  updatePendingAt(sid, index, text);
528
561
  setEditing(null);
529
562
  };
530
- /**
531
- * Pull one queued row back into the composer draft for editing: the text
532
- * back-fills the input box and the row leaves the queue; the user edits and
533
- * resubmits it as a fresh message.
534
- */
535
- const pullBackToComposer = async (row) => {
536
- if (row.text === null) return;
537
- setDraft(row.text);
538
- setBusy(row.id);
539
- try {
540
- await updateQueue(row.id, { kind: "remove" });
541
- } catch {
542
- notify("error", t("steer.pullBackFailed"));
543
- } finally {
544
- setBusy((current) => current === row.id ? null : current);
545
- }
546
- };
547
563
  const clearAll = async () => {
548
564
  setClearing(true);
549
565
  const pending = [...queue, ...steering];
@@ -919,7 +935,7 @@ window.__ModuleLoader__.load({
919
935
  }
920
936
  }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
921
937
  className: steer_queue_dock_module_css_default.preview,
922
- children: row.preview
938
+ children: row.text
923
939
  }),
924
940
  queueMutable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
925
941
  className: steer_queue_dock_module_css_default.actions,
@@ -986,23 +1002,6 @@ window.__ModuleLoader__.load({
986
1002
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconChevronDownOutlineMedium, {})
987
1003
  })
988
1004
  }),
989
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
990
- label: t("steer.pullBack"),
991
- side: "bottom",
992
- delayMs: 500,
993
- disabled: row.text === null || !composerEmpty,
994
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
995
- type: "button",
996
- className: steer_queue_dock_module_css_default.action,
997
- "aria-label": t("steer.pullBack"),
998
- title: row.text === null ? t("steer.pullBack.unsupported") : !composerEmpty ? t("steer.pullBack.composerBusy") : void 0,
999
- disabled: busy !== null || frozen || row.text === null || !composerEmpty,
1000
- onClick: () => {
1001
- pullBackToComposer(row);
1002
- },
1003
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconRightUpOutlineMedium, {})
1004
- })
1005
- }),
1006
1005
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
1007
1006
  label: t("queue.edit"),
1008
1007
  side: "bottom",
@@ -1017,7 +1016,7 @@ window.__ModuleLoader__.load({
1017
1016
  onClick: () => {
1018
1017
  if (row.text !== null) setEditing({
1019
1018
  id: row.id,
1020
- text: row.text
1019
+ text: row.text ?? ""
1021
1020
  });
1022
1021
  },
1023
1022
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEditOutlineMedium, { size: 14 })
@@ -1125,7 +1124,7 @@ window.__ModuleLoader__.load({
1125
1124
  }),
1126
1125
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
1127
1126
  className: steer_queue_dock_module_css_default.preview,
1128
- children: row.preview
1127
+ children: row.text
1129
1128
  }),
1130
1129
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
1131
1130
  className: steer_queue_dock_module_css_default.actions,
@@ -1261,16 +1260,20 @@ window.__ModuleLoader__.load({
1261
1260
  * Freeze/resume toggle for the peak-hour scenario.
1262
1261
  * @param props - slot props; the session snapshot drives the detach list.
1263
1262
  */
1264
- function FreezeButton({ useSession, updateQueue, cancel, send, sendSteer, sessionId, setComposerBlock, notify, t }) {
1263
+ function FreezeButton({ useProjection, updateQueue, cancel, send, sendSteer, sessionId, setComposerBlock, notify, t }) {
1265
1264
  const sid = sessionId ?? "";
1266
1265
  const { frozen } = (0, react.useSyncExternalStore)(freezeStore.subscribe, () => freezeStore.getSnapshot(sid));
1267
- const queue = useSession((s) => s.queue);
1266
+ const inbox = useProjection("inbox");
1268
1267
  const freeze = async () => {
1269
- const rows = queue.filter((row) => row.placement === "queued" || row.placement === "steering");
1270
- const pending = rows.flatMap((row) => row.text === null ? [] : [{
1268
+ const steeredIds = new Set((inbox?.["next-step"] ?? []).map((row) => row.id));
1269
+ const rows = [...inbox?.["next-turn"] ?? [], ...inbox?.["next-step"] ?? []].map((row) => ({
1270
+ ...row,
1271
+ text: textOf(row.content) ?? row.text ?? null
1272
+ }));
1273
+ const pending = rows.flatMap((row) => typeof row.text === "string" && row.text !== "" ? [{
1271
1274
  text: row.text,
1272
- tier: row.placement === "steering" ? "safe_point" : "queue"
1273
- }]);
1275
+ tier: steeredIds.has(row.id) ? "safe_point" : "queue"
1276
+ }] : []);
1274
1277
  await Promise.all(rows.map((row) => updateQueue(row.id, { kind: "remove" }).catch(() => void 0)));
1275
1278
  freezeStore.set(sid, {
1276
1279
  frozen: true,
@@ -1373,8 +1376,9 @@ window.__ModuleLoader__.load({
1373
1376
  *
1374
1377
  * List rows render sorted by `order` ascending, so a value above every other
1375
1378
  * contributor keeps the strip as the bottom-most entry of the band — directly
1376
- * on top of the composer card. Known contributors on 0.1.5-rc.2: `todo` 0,
1377
- * `goal` 10, official `queue` 20, `dsh-perm-gate.notice` 30. DSH has no "last"
1379
+ * on top of the composer card. Known contributors (stable across hosts
1380
+ * 0.1.5-rc.1 → 0.2.0-rc.2): `todo` 0, official `queue` 20,
1381
+ * `dsh-perm-gate.notice` 30, `dsh-tidy-display-entry` 0. DSH has no "last"
1378
1382
  * slot semantics, so this is a convention, not a
1379
1383
  * structural guarantee: a third party registering a larger value could still
1380
1384
  * land below us.