dsh-input-traffic 0.2.8 → 0.2.10-beta.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.
Files changed (39) hide show
  1. package/CHANGELOG.ja.md +78 -0
  2. package/CHANGELOG.ko.md +78 -0
  3. package/CHANGELOG.md +92 -0
  4. package/INSTALL.ja.md +151 -0
  5. package/INSTALL.ko.md +151 -0
  6. package/INSTALL.md +152 -0
  7. package/INSTALL.zh.md +151 -0
  8. package/README.en.md +63 -7
  9. package/README.ja.md +187 -0
  10. package/README.ko.md +181 -0
  11. package/README.md +86 -10
  12. package/dsh.plugin.json +13 -0
  13. package/lib/client.js +1433 -1338
  14. package/lib/client.js.map +1 -1
  15. package/lib/types/client/freeze-button.d.ts +16 -9
  16. package/lib/types/client/freeze-button.d.ts.map +1 -1
  17. package/lib/types/client/freeze-button.js +86 -55
  18. package/lib/types/client/freeze-button.js.map +1 -1
  19. package/lib/types/client/freeze-store.d.ts +17 -10
  20. package/lib/types/client/freeze-store.d.ts.map +1 -1
  21. package/lib/types/client/freeze-store.js +54 -38
  22. package/lib/types/client/freeze-store.js.map +1 -1
  23. package/lib/types/client/index.d.ts +47 -24
  24. package/lib/types/client/index.d.ts.map +1 -1
  25. package/lib/types/client/index.js +117 -79
  26. package/lib/types/client/index.js.map +1 -1
  27. package/lib/types/client/locales.d.ts +63 -58
  28. package/lib/types/client/locales.d.ts.map +1 -1
  29. package/lib/types/client/locales.js +211 -105
  30. package/lib/types/client/locales.js.map +1 -1
  31. package/lib/types/client/session-guard-bridge.d.ts +18 -0
  32. package/lib/types/client/session-guard-bridge.d.ts.map +1 -0
  33. package/lib/types/client/session-guard-bridge.js +42 -0
  34. package/lib/types/client/session-guard-bridge.js.map +1 -0
  35. package/lib/types/client/steer-queue-dock.d.ts +9 -1
  36. package/lib/types/client/steer-queue-dock.d.ts.map +1 -1
  37. package/lib/types/client/steer-queue-dock.js +6 -5
  38. package/lib/types/client/steer-queue-dock.js.map +1 -1
  39. package/package.json +15 -7
package/INSTALL.md ADDED
@@ -0,0 +1,152 @@
1
+ # Installation Guide (Official DSH CLI)
2
+
3
+ This guide uses only the official DSH `dsh plugin` command. The command installs the dependency into a profile and synchronizes `dsh.profile.bundles`. Do not replace it with plain `npm install`, direct `pnpm add` in the profile, or manual edits to the profile manifest.
4
+
5
+ - [English installation guide](./INSTALL.md)
6
+ - [中文安装指南](./INSTALL.zh.md)
7
+ - [日本語インストールガイド](./INSTALL.ja.md)
8
+ - [한국어 설치 안내](./INSTALL.ko.md)
9
+ - [English README](./README.en.md)
10
+ - [中文 README](./README.md)
11
+ - [日本語 README](./README.ja.md)
12
+ - [한국어 README](./README.ko.md)
13
+ - [Changelog](./CHANGELOG.md)
14
+ - [日本語 changelog](./CHANGELOG.ja.md)
15
+ - [한국어 changelog](./CHANGELOG.ko.md)
16
+
17
+ The placeholders in this guide are:
18
+
19
+ - `<profile>`: the DSH profile to modify, usually `web`;
20
+ - `dsh-input-traffic`: the npm package and runtime plugin ID.
21
+
22
+ ## 0. Prerequisites and profile discovery
23
+
24
+ ```bash
25
+ echo "DSH_HOME=${DSH_HOME:-$HOME/.dsh}"
26
+ dsh --version
27
+ ls "${DSH_HOME:-$HOME/.dsh}/profiles"
28
+ ```
29
+
30
+ Use the profile named by your running DSH process. `web` is common, but the active `--profile` argument is authoritative.
31
+
32
+ ## 1. Official installation
33
+
34
+ Install the latest version:
35
+
36
+ ```bash
37
+ dsh plugin --profile <profile> add dsh-input-traffic -w
38
+ ```
39
+
40
+ (The `-w` flag is required when the profile is a pnpm workspace root, as `web` is.)
41
+
42
+ Install the current release explicitly:
43
+
44
+ ```bash
45
+ dsh plugin --profile <profile> add dsh-input-traffic@0.2.9 -w
46
+ ```
47
+
48
+ The official CLI updates the profile dependency, lockfile, and `dsh.profile.bundles` automatically. Do not add a manual YAML row.
49
+
50
+ ### Supply-chain cooling period
51
+
52
+ The dsh runtime uses pnpm 11, whose `minimumReleaseAge` policy may block a freshly published version with `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION`. Add the version to `minimumReleaseAgeExclude` in `~/.dsh/profiles/web/pnpm-workspace.yaml`:
53
+
54
+ ```yaml
55
+ minimumReleaseAgeExclude:
56
+ - dsh-input-traffic@0.2.9
57
+ ```
58
+
59
+ ## 2. Upgrade
60
+
61
+ Upgrade to the latest registry version:
62
+
63
+ ```bash
64
+ dsh plugin --profile <profile> update dsh-input-traffic -w
65
+ ```
66
+
67
+ Restart DSH for host changes and refresh the Web page for client changes.
68
+
69
+ ## 3. Local-path / link: registration (alternative)
70
+
71
+ For development or offline installs, register the plugin from a local checkout:
72
+
73
+ ```bash
74
+ # ~/.dsh/profiles/web/package.json dependencies:
75
+ # "dsh-input-traffic": "link:<absolute path to dsh-input-traffic>"
76
+ # ~/.dsh/profiles/web/cordis.patch.yml:
77
+ # - insert:
78
+ # - id: input-traffic
79
+ # name: dsh-input-traffic
80
+ cd ~/.dsh/profiles/web && pnpm install && dsh web
81
+ ```
82
+
83
+ Or use the official CLI with a local path (no network needed):
84
+
85
+ ```bash
86
+ dsh plugin --profile <profile> add /absolute/path/to/dsh-input-traffic -w
87
+ ```
88
+
89
+ ## 4. Verify installation
90
+
91
+ Check the dependency and installed version:
92
+
93
+ ```bash
94
+ grep -n "dsh-input-traffic" \
95
+ "${DSH_HOME:-$HOME/.dsh}/profiles/<profile>/package.json"
96
+ node -p "require('${DSH_HOME:-$HOME/.dsh}/profiles/<profile>/node_modules/dsh-input-traffic/package.json').version"
97
+ ```
98
+
99
+ Check the official composition:
100
+
101
+ ```bash
102
+ dsh --profile <profile> --dump-default-config
103
+ ```
104
+
105
+ It must contain:
106
+
107
+ ```yaml
108
+ - id: input-traffic
109
+ name: dsh-input-traffic
110
+ ```
111
+
112
+ ## 5. Verify the plugin
113
+
114
+ Restart DSH, then refresh the Web page. In a session, verify:
115
+
116
+ 1. The three-tier planning dock appears in the waiting area;
117
+ 2. The "Freeze session" button is visible on the composer's right;
118
+ 3. The official "busy-Enter behavior" settings row is hidden;
119
+ 4. While the agent is busy, sending a message places it in the waiting area with red/yellow/green planning buttons.
120
+
121
+ ## Japanese and Korean support status
122
+
123
+ The plugin ships `ja` and `ko` dictionaries, but the current official DSH release exposes only `zh` and `en` through `LocaleRuntime`. On stock DSH, selecting Japanese or Korean fails with `locale "<id>" is not registered`.
124
+
125
+ To use them before official support lands, maintain a DSH fork and update:
126
+
127
+ - `packages/client/locale/src/locale-settings.ts`: add `ja` and `ko` to `LOCALE_IDS`.
128
+ - `packages/client/locale/src/client/index.ts`: add `{ id: 'ja', label: '日本語' }` and `{ id: 'ko', label: '한국어' }` to `LOCALES`.
129
+ - Add the corresponding core dictionaries and tests, then rebuild and run the forked DSH.
130
+
131
+ A plugin-only change cannot extend DSH's global locale list.
132
+
133
+ ## 6. Troubleshooting
134
+
135
+ | Symptom | Action |
136
+ | --- | --- |
137
+ | `dsh` is not found | Install or enable the official DSH CLI. |
138
+ | `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION` | Add the version to `minimumReleaseAgeExclude` in the profile's `pnpm-workspace.yaml`. |
139
+ | Plugin shows as "disabled/unmounted" with no error | Check the profile composition. |
140
+ | Client entry missing from `__DSH_BOOT__` | Confirm `exports["./client"]` exists and the host fiber was established. |
141
+ | Freeze/resume buttons not working | Ensure session-guard is installed if using session-level locking; the plugin operates fail-open when session-guard is absent. |
142
+ | Stale client bundle | Hard-refresh the browser (Ctrl+Shift+R) after an upgrade. |
143
+
144
+ ## 7. Remove
145
+
146
+ Use the official command:
147
+
148
+ ```bash
149
+ dsh plugin --profile <profile> remove dsh-input-traffic
150
+ ```
151
+
152
+ Restart DSH afterwards to restore the official queue dock and the "busy-Enter behavior" settings row.
package/INSTALL.zh.md ADDED
@@ -0,0 +1,151 @@
1
+ # 安装指南(官方 DSH CLI)
2
+
3
+ 本指南只使用官方 `dsh plugin` 命令。该命令会把依赖装进 profile 并同步 `dsh.profile.bundles`。不要用普通 `npm install`、在 profile 里直接 `pnpm add` 或手工编辑 profile 清单代替。
4
+
5
+ - [安装指南](./INSTALL.zh.md)
6
+ - [English installation guide](./INSTALL.md)
7
+ - [日本語インストールガイド](./INSTALL.ja.md)
8
+ - [한국어 설치 안내](./INSTALL.ko.md)
9
+ - [中文 README](./README.md)
10
+ - [English README](./README.en.md)
11
+ - [日本語 README](./README.ja.md)
12
+ - [한국어 README](./README.ko.md)
13
+ - [版本更新日志](./CHANGELOG.md)
14
+ - [日本語 changelog](./CHANGELOG.ja.md)
15
+ - [한국어 changelog](./CHANGELOG.ko.md)
16
+
17
+ 本指南中的占位符:
18
+
19
+ - `<profile>`:要修改的 DSH profile,通常是 `web`;
20
+ - `dsh-input-traffic`:npm 包名与运行时插件 ID。
21
+
22
+ ## 0. 前置检查与 profile 确认
23
+
24
+ ```bash
25
+ echo "DSH_HOME=${DSH_HOME:-$HOME/.dsh}"
26
+ dsh --version
27
+ ls "${DSH_HOME:-$HOME/.dsh}/profiles"
28
+ ```
29
+
30
+ 使用你正在运行的 DSH 进程对应的 profile。`web` 很常见,但以实际 `--profile` 参数为准。
31
+
32
+ ## 1. 官方安装
33
+
34
+ 安装最新版本:
35
+
36
+ ```bash
37
+ dsh plugin --profile <profile> add dsh-input-traffic -w
38
+ ```
39
+
40
+ (当 profile 是 pnpm workspace root 时必须带 `-w`,`web` 就是。)
41
+
42
+ 显式安装当前发布版:
43
+
44
+ ```bash
45
+ dsh plugin --profile <profile> add dsh-input-traffic@0.2.9 -w
46
+ ```
47
+
48
+ 官方 CLI 会自动更新 profile 依赖、锁文件与 `dsh.profile.bundles`。不要手工追加 YAML。
49
+
50
+ ### 供应链冷却期
51
+
52
+ dsh 运行环境使用 pnpm 11,其 `minimumReleaseAge` 策略可能拦截刚发布的版本,报 `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION`。把版本加入 `~/.dsh/profiles/web/pnpm-workspace.yaml` 的 `minimumReleaseAgeExclude`:
53
+
54
+ ```yaml
55
+ minimumReleaseAgeExclude:
56
+ - dsh-input-traffic@0.2.9
57
+ ```
58
+
59
+ ## 2. 升级
60
+
61
+ 升级到 registry 最新版本:
62
+
63
+ ```bash
64
+ dsh plugin --profile <profile> update dsh-input-traffic -w
65
+ ```
66
+
67
+ 宿主侧改动需重启 DSH;浏览器侧刷新 Web 页面。
68
+
69
+ ## 3. 本地路径 / link: 注册(备选)
70
+
71
+ 开发或离线安装时,可以从本地检出注册插件:
72
+
73
+ ```bash
74
+ # ~/.dsh/profiles/web/package.json dependencies 增加:
75
+ # "dsh-input-traffic": "link:<dsh-input-traffic 的绝对路径>"
76
+ # ~/.dsh/profiles/web/cordis.patch.yml:
77
+ # - insert:
78
+ # - id: input-traffic
79
+ # name: dsh-input-traffic
80
+ cd ~/.dsh/profiles/web && pnpm install && dsh web
81
+ ```
82
+
83
+ 或用官方 CLI 加本地路径(无需网络):
84
+
85
+ ```bash
86
+ dsh plugin --profile <profile> add /dsh-input-traffic 的绝对路径/ -w
87
+ ```
88
+
89
+ ## 4. 验证安装
90
+
91
+ 检查依赖与安装版本:
92
+
93
+ ```bash
94
+ grep -n "dsh-input-traffic" \
95
+ "${DSH_HOME:-$HOME/.dsh}/profiles/<profile>/package.json"
96
+ ```
97
+
98
+ 检查官方组合配置:
99
+
100
+ ```bash
101
+ dsh --profile <profile> --dump-default-config
102
+ ```
103
+
104
+ 应包含:
105
+
106
+ ```yaml
107
+ - id: input-traffic
108
+ name: dsh-input-traffic
109
+ ```
110
+
111
+ ## 5. 验证插件
112
+
113
+ 重启 DSH 后刷新 Web 页面。在会话中验证:
114
+
115
+ 1. 等待区出现三档规划 dock;
116
+ 2. 输入框右侧显示「冻结会话」按钮;
117
+ 3. 公式设置面板的「繁忙时 Enter 键行为」设置行已隐藏;
118
+ 4. 智能体忙碌时发送消息,消息进入等待区并显示红/黄/绿规划按钮。
119
+
120
+ ## 日语与韩语支持状态
121
+
122
+ 插件自带 `ja` 与 `ko` 字典,但当前官方 DSH 只通过 `LocaleRuntime` 暴露 `zh` 和 `en`。在原版 DSH 上选择日语或韩语会报 `locale "<id>" is not registered`。
123
+
124
+ 官方支持落地前要使用它们,请维护 DSH fork 并更新:
125
+
126
+ - `packages/client/locale/src/locale-settings.ts`:把 `ja` 与 `ko` 加入 `LOCALE_IDS`。
127
+ - `packages/client/locale/src/client/index.ts`:在 `LOCALES` 中加入 `{ id: 'ja', label: '日本語' }` 与 `{ id: 'ko', label: '한국어' }`。
128
+ - 补齐对应的核心字典与测试,然后重新构建并运行 fork 版本。
129
+
130
+ 仅修改插件无法扩展 DSH 的全局 locale 列表。
131
+
132
+ ## 6. 排查
133
+
134
+ | 症状 | 处理 |
135
+ | --- | --- |
136
+ | 找不到 `dsh` 命令 | 安装或启用官方 DSH CLI。 |
137
+ | `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION` | 把版本加入 profile 的 `pnpm-workspace.yaml` 的 `minimumReleaseAgeExclude`。 |
138
+ | 插件显示「已停用/未挂载」且无错误 | 检查 profile 组合。 |
139
+ | client 入口不在 `__DSH_BOOT__` | 确认 `exports["./client"]` 存在且 host fiber 已建立。 |
140
+ | 冻结/恢复按钮不工作 | 如使用会话级锁定,确保 session-guard 已安装;未安装时插件以 fail-open 方式运行。 |
141
+ | 浏览器显示旧 bundle | 升级后硬刷新(Ctrl+Shift+R)。 |
142
+
143
+ ## 7. 卸载
144
+
145
+ 使用官方命令:
146
+
147
+ ```bash
148
+ dsh plugin --profile <profile> remove dsh-input-traffic
149
+ ```
150
+
151
+ 重启后,公式队列 dock 与「繁忙时 Enter 键行为」设置行将恢复。
package/README.en.md CHANGED
@@ -2,7 +2,7 @@
2
2
  <strong>Three-tier input traffic control for the DeepSeek Harness Web GUI</strong>
3
3
  </p>
4
4
  <p align="center">
5
- <a href="README.md">中文</a> · <strong>English</strong>
5
+ <strong>English</strong> · <a href="README.md">中文</a> · <a href="README.ja.md">日本語</a> · <a href="README.ko.md">한국어</a>
6
6
  </p>
7
7
  <p align="center">
8
8
  <a href="LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-263146?style=flat-square"></a>
@@ -11,6 +11,30 @@
11
11
 
12
12
  # dsh-input-traffic
13
13
 
14
+ - [English README](./README.en.md)
15
+ - [中文 README](./README.md)
16
+ - [日本語 README](./README.ja.md)
17
+ - [한국어 README](./README.ko.md)
18
+ - [Installation guide](./INSTALL.md)
19
+ - [中文安装指南](./INSTALL.zh.md)
20
+ - [日本語インストールガイド](./INSTALL.ja.md)
21
+ - [한국어 설치 안내](./INSTALL.ko.md)
22
+ - [Changelog](./CHANGELOG.md)
23
+ - [日本語 changelog](./CHANGELOG.ja.md)
24
+ - [한국어 changelog](./CHANGELOG.ko.md)
25
+
26
+ > **▼ DSH version support**
27
+ > | DSH version | Queue strip / freeze button | Busy-Enter pin | Key difference |
28
+ > | --- | --- | --- | --- |
29
+ > | 0.1.1-rc.2 | ✅ | ✅ | `conversation.input.right` still carries the `InputZone` owner (the plugin no longer depends on it) |
30
+ > | 0.1.2-rc.1 | ✅ | ✅ | That slot lost its owner (`InputBar.tsx:466` passes `{}`); the freeze button now reads the session standard kit `useSession` |
31
+ >
32
+ > - **One artifact, runtime-adaptive**: the same `lib/client.js` works on both releases. The client bundle only `require`s `react` / `react/jsx-runtime` / `@deepseek-ai/dsh-client-ui-primitives` — all three are in the shared module table of both releases, so the `dsh-client-runtime` → `dsh-client-store` rename never reaches it.
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.
34
+ > - **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
+
36
+ > **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
+
14
38
  > 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.
15
39
 
16
40
  A cordis client plugin assembled via the `dsh plugin` command and a bundle patch — no dsh source changes, no PR required.
@@ -70,9 +94,22 @@ The "Freeze session / Resume session" button on the composer's right (beside the
70
94
 
71
95
  - **Freeze**: the current turn is **not interrupted** — it finishes naturally, then consumption pauses. The queue is fully **decoupled from freezing**: freezing only stops the agent from consuming (executing / inserting / appending), while the waiting area stays visible and **fully operable** — reorder, edit, remove and set the red/yellow/green insertion tier, just like when not frozen;
72
96
  - **Resume**: the (possibly edited) queue is re-submitted and **each entry executes with its planned tier** (red = interrupt and process immediately, yellow = interject, green = queue); the agent continues in FIFO order;
73
- - Engine: freeze = detach every queued row via `updateQueue(remove)` (copies with their tiers kept in the plugin store); the driver stops naturally once the current turn ends with no pending work; edits made while frozen (text / order / tier) write back to the store in real time; resume = re-submit via `send(text)`, waking the driver (red-tier entries are preceded by `cancel()`);
97
+ - **Session isolation**: freeze state and the detached queue are keyed **by sessionId** (`src/client/freeze-store.ts`'s `Map<string, FreezeState>`) — freezing session A never affects session B's banner/button/queue; editing only re-renders the owning session's consumers;
98
+ - **Engine**: freeze = detach every queued row via `updateQueue(remove)` (copies with their tiers kept in the plugin store, keyed by session); the driver stops naturally once the current turn ends with no pending work; edits made while frozen (text / order / tier) write back to the store in real time; resume = first `await sessionGuard.resume(sessionId)` (so the interrupted turn's natural next step happens first), then re-submit via `send(text)`, waking the driver (red-tier entries are preceded by `cancel()`);
74
99
  - Note: queued messages containing non-text content (images) cannot be re-sent and are released by the freeze (they do not come back).
75
100
 
101
+ ### Session-level locking via dsh-session-guard
102
+
103
+ The freeze button hands off to a **sessionGuard bridge** (`src/client/session-guard-bridge.ts` → `POST /session-guard/rpc { action: stopNextTurn|resume, sessionId }`) for **per-session locking** on the server side, while raising a composer block (`conversation.blocks.set`) so the input box turns inert and Enter can no longer leak into the conversation:
104
+
105
+ - **Component references**:
106
+ - `src/client/freeze-button.tsx` — freeze/resume control (slot `conversation.input.right`);
107
+ - `src/client/steer-queue-dock.tsx` — three-tier planning dock + frozen banner/list (slot `conversation.input.dock` id `queue`);
108
+ - `src/client/freeze-store.ts` — session-scoped freeze state (`Map<sessionId, {frozen, pending}>`, shared by button ↔ dock);
109
+ - `src/client/session-guard-bridge.ts` — session-guard RPC bridge (fail-open, silently skipped when session-guard is absent);
110
+ - `src/client/index.ts` — slot registration + composer-block injection (`conversation.blocks.set`).
111
+ - **Scope comparison**: this plugin's freeze button = **per-session** (locks that one session by id); session-guard's **auto peak gate = global** (pauses all running sessions on peak entry, resumes all on exit). They complement each other — the gate handles the global case, the button the single-session case.
112
+
76
113
  ## Queue management
77
114
 
78
115
  Each waiting-area message (while not frozen) offers:
@@ -107,13 +144,17 @@ The dock and the freeze button **no longer use hand-drawn colors** — they refe
107
144
  ## Installation
108
145
 
109
146
  ```sh
110
- # Option 1: install from npm (recommended)
147
+ # Option 1: install from npm (recommended, stable release)
111
148
  # (the profile is a pnpm workspace root, so -w is required)
112
149
  dsh plugin --profile web add dsh-input-traffic -w
113
150
 
114
- # Option 2: assemble from git or a local path
151
+ # Option 2: install directly from GitHub (drscrewdriver fork — trial new features first)
152
+ # (lib/ is not committed; after install build in the profile:
153
+ # cd ~/.dsh/profiles/web/node_modules/dsh-input-traffic && npm install --legacy-peer-deps && npm run build)
154
+ dsh plugin --profile web add github:drscrewdriver/dsh-input-traffic#main
155
+
156
+ # Option 3: assemble from a local path
115
157
  # dsh plugin --profile web add /absolute/path/to/dsh-input-traffic -w
116
- # (after git install, build in the profile's node_modules: npm install --legacy-peer-deps && npm run build)
117
158
 
118
159
  # Confirm the composed tree contains the new row
119
160
  dsh web --dump-config | grep -B1 -A2 'input-traffic'
@@ -122,6 +163,8 @@ dsh web --dump-config | grep -B1 -A2 'input-traffic'
122
163
  dsh web
123
164
  ```
124
165
 
166
+ > ⚠️ **GitHub reachability**: installing via github: requires access to github.com; if your network is restricted, set up a working proxy or mirror first, otherwise add may stall while fetching.
167
+
125
168
  Local build and tests:
126
169
 
127
170
  ```sh
@@ -184,7 +227,7 @@ Expected — the plugin hides it and pins Enter to green queue; a stale preferen
184
227
 
185
228
  ### Queued messages disappeared after freezing
186
229
 
187
- Expected — the freeze detaches the queue into the plugin store (removed from the waiting area); they return on resume. Refreshing the page loses the frozen queue; avoid refreshing while frozen.
230
+ Expected — the freeze detaches the queue into the plugin store (keyed by session, removed from the waiting area); they return on resume. Refreshing the page loses the frozen queue; avoid refreshing while frozen.
188
231
 
189
232
  ### Move up/down is disabled
190
233
 
@@ -220,7 +263,7 @@ src/
220
263
  ├── index.ts # browser half apply: busyEnter pinned to queue + three slot registrations
221
264
  ├── steer-queue-dock.tsx # three-tier planning dock (shadows conversation.input.dock id queue)
222
265
  ├── freeze-button.tsx # freeze/resume button (conversation.input.right)
223
- ├── freeze-store.ts # shared freeze state (composer button ↔ dock banner)
266
+ ├── freeze-store.ts # session-scoped freeze state (Map<sessionId, {frozen, pending}>)
224
267
  ├── hide-enter-row.tsx # settings-row hiding (shadows settings.general.item id composer-enter)
225
268
  ├── locales.ts # steer dictionaries (zh/en)
226
269
  └── *.module.css
@@ -250,6 +293,19 @@ End-to-end browser verification on a live `dsh web`, zero application console er
250
293
  - Semantics reference: [dsh-traffic-light](https://github.com/yimeng-dev/dsh-traffic-light) (desktop session-status traffic light)
251
294
  - Harness anchors: `packages/client/AGENTS.md`, `packages/client/tsdown.client.ts`, `packages/client/web/src/platform.ts`, `packages/bundle/web-app/cordis.patch.yml`, `packages/client/ui-conversation/src/client/queue/QueueDock.tsx`, `packages/host/apiproxy/src/api-proxy.ts`
252
295
 
296
+ ## drscrewdriver DSH Plugin Family
297
+
298
+ This project is one of the DSH plugins maintained by [drscrewdriver](https://github.com/drscrewdriver). If this one helps you, the others likely will too:
299
+
300
+ | Plugin | One-liner |
301
+ |---|---|
302
+ | **[dsh-input-traffic](https://github.com/drscrewdriver/dsh-input-traffic)** | Busy-time input queue: three-tier traffic control, drag-to-reorder, session freeze |
303
+ | **[dsh-session-guard](https://github.com/drscrewdriver/dsh-session-guard)** | Peak auto session gate: weekend mode + peak auto-pause + session-level lock + backend auto-retry (pairs with this plugin's button) |
304
+ | [dsh-thinking-levels](https://github.com/drscrewdriver/dsh-thinking-levels) | Per-round reasoning_effort control: Auto scheduling or manual wire level |
305
+ | [dsh-seatbelt-sandbox](https://github.com/drscrewdriver/dsh-seatbelt-sandbox) | macOS Seatbelt sandbox adapter: native libsandbox loader replacing deprecated sandbox-exec |
306
+ | [dsh-switch-search](https://github.com/drscrewdriver/dsh-switch-search) | Session content search sidebar: title/content toggle, type-filter by user/reply/tool |
307
+
253
308
  ## License
254
309
 
255
310
  MIT
311
+
package/README.ja.md ADDED
@@ -0,0 +1,187 @@
1
+ <p align="center">
2
+ <strong>DeepSeek Harness Web GUI 向け三段階入力交通管制</strong>
3
+ </p>
4
+ <p align="center">
5
+ <a href="README.en.md">English</a> · <a href="README.md">中文</a> · <strong>日本語</strong> · <a href="README.ko.md">한국어</a>
6
+ </p>
7
+ <p align="center">
8
+ <a href="LICENSE"><img alt="MIT License" src="https://img.shields.io/badge/license-MIT-263146?style=flat-square"></a>
9
+ <img src="https://camo.githubusercontent.com/2c11fb2e0e14bb9985c5acbe61123a7441c5ee63aa27fa6e04e2a707ebfd6022/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6473682d2d706c7567696e2d72656164792d3437384342463f6c6f676f3d646565707365656b266c6f676f436f6c6f723d7768697465" alt="dsh-plugin" style="max-width: 100%;">
10
+ <img alt="Public beta" src="https://img.shields.io/badge/status-public%20beta-7da1de?style=flat-square">
11
+ </p>
12
+
13
+ # dsh-input-traffic
14
+
15
+ - [English README](./README.en.md)
16
+ - [中文 README](./README.md)
17
+ - [日本語 README](./README.ja.md)
18
+ - [한국어 README](./README.ko.md)
19
+ - [Installation guide](./INSTALL.md)
20
+ - [中文安装指南](./INSTALL.zh.md)
21
+ - [日本語インストールガイド](./INSTALL.ja.md)
22
+ - [한국어 설치 안내](./INSTALL.ko.md)
23
+ - [Changelog](./CHANGELOG.md)
24
+ - [日本語 changelog](./CHANGELOG.ja.md)
25
+ - [한국어 changelog](./CHANGELOG.ko.md)
26
+
27
+ > **互換性について:** `ja` と `ko` の辞書は同梱されていますが、現在の公式 DSH リリースは `LocaleRuntime` 経由で `zh` と `en` のみを提供しています。純正 DSH で `ja` または `ko` を選択すると `locale "<id>" is not registered` で失敗します。公式 DSH が locale ID を追加するまで利用できません。上級ユーザーは DSH フォークを保守し、`packages/client/locale/src/locale-settings.ts` の `LOCALE_IDS` と `packages/client/locale/src/client/index.ts` の `LOCALES` ラベルを更新し、コア辞書とテストを追加して再ビルド・実行してください。このプラグインだけでは DSH のグローバル locale 一一覧を拡張できません。
28
+
29
+ > エージェントがビジーなとき、「中断」か「キュー」の二択ではありません:赤は即座に中断して送信、黄は次のターンに挿入、green は最後までキューイング——3 段階が共存します。DeepSeek のピーク課金時間帯に近づいたら、ワンクリックでセッションを凍結し、オフピーク時に再開します。
30
+
31
+ `dsh plugin` コマンドで组装 + バンドルパッチで装配する cordis クライアントプラグイン。dsh のソース変更も PR も不要です。
32
+
33
+ > 💡 **「セッション凍結」が推奨される理由**:DeepSeek は 2026-08-17 から**峰谷課金**を開始しました——ピーク時間帯(北京時間 9:00-12:00、14:00-18:00)の単価はオフピーク(その他の時間帯、昼間・夜間・週末・祝日を含む)の **2 倍**です。長時間実行されるセッションが高価な窗口を跨ぐ場合、手動で凍結して API 消費を一時停止し、オフピーク時に再開することで、費用を最大 **50%** 削減できます。
34
+ >
35
+ > **推奨セットアップ**:**リマインダー**プラグイン([dsh-notify](https://github.com/zhengjy01/dsh-notify) など、凍結/再開のタイミングをデスクトップ通知)と**課金統計**プラグイン([dsh-deepseek-usage](https://github.com/yyb16yyb-hub/dsh-deepseek-usage)、[dsh-cost-tracker](https://github.com/yflmq001/dsh-cost-tracker)、[dsh-billing-balance](https://github.com/YZz-S/dsh-billing-balance) など、凍結前後の実際の支出を確認)を組み合わせ、「リマインド → 凍結 → オフピーク再開 → 精算」の節約ループを実現します。
36
+
37
+ ## 機能一覧
38
+
39
+ - **3 段階の挿入が共存**:エージェントがビジーなとき、すべての入力はまず待機エリアに入り、会話に入るタイミングを選択できます——「中断」か「キュー」の単一選択ではありません:
40
+ - 🔴 **赤(now)**:現在のターンを中断して即座に送信——実行中の生成が停止し、メッセージがエージェントにより即座に処理されて応答されます;
41
+ - 🟡 **黄(next)**:次の自然なターンに挿入——現在のアクション(ツール呼び出し/実行中の生成)が完了してから挿入;
42
+ - 🟢 **緑(later)**:ロジック全体の実行完了後に入力——キューで待機し、前の入力のすべてのアクションが完了してから処理(デフォルト)。
43
+ - **黄色は取り消し可能**:挿入済み(黄色)のメッセージに緑ボタンを押すと、挿入を取り消してキューに戻せます。
44
+ - **キュー内容は編集可能**:キューに入っているメッセージは直接編集できます——マルチラインエディタはコンテンツに応じて自動拡張され、長いメッセージも完全に表示されます(Enter で保存 / Shift+Enter で改行 / Esc でキャンセル);**コンポーザに送り直して編集**も可能です。
45
+ - **キュー管理**:待機エリアのメッセージは**上へ/下へ移動**して順序を変更、削除、および「取り消して全消去」ができます。
46
+ - **編集でコンテンツを失わない**:保存に失敗した場合(エージェントが既にメッセージを取得済み)、編集内容は自動的にコンポーザに戻ります。
47
+ - **ピーク時間ク時間帯の凍結**:入力ボックス右側の「セッション凍結」ボタン——DeepSeek のピーク課金時間帯(9:00-12:00、14:00-18:00)に近づいたら、API 消費を一時停止:現在のターンが自然に完了してから暂停、未送信キューは凍結保存;「セッション再開」でオフピーク時に処理を継続。
48
+ - **セッション隔離凍結**:凍結キューは **sessionId で隔離**——あるセッションの凍結は他のセッションに影響しません(独立した frozen フラグと detached キュー)。
49
+ - **公式動作の上書き**:プラグイン有効時、公式設定パネルの「ビジー時の Enter キー動作」設定行は非表示になります(Enter 行為は緑キューに固定)。
50
+ - **日夜自動適応**:キュー枠と凍結ボタンはすべて dsh 公式セマンティックトークン(`--dsw-alias-*`)を使用し、システムダークモード / dsh ダークテーマに自動追従します。
51
+
52
+ ## 3 段階のセマンティクス
53
+
54
+ | 段階 | 色 | セマンティクス | 底層メカニズム(dsh 既存 RPC 組み合わせ) |
55
+ |---|---|---|---|
56
+ | **later**(デフォルト) | 緑 | キュー:前の入力のすべてのアクションが完了してから処理;挿入済み(黄色)メッセージに緑 = **挿入取り消し、キューに戻す** | Enter デフォルト queue → `agent.followup()`(next-turn);取り消し = `updateQueue(remove)` + `send(text)` |
57
+ | **next** | 黄 | 次の自然なターンに挿入:現在のアクションが完了してから | `updateQueue(id, { kind: 'steer' })` → `agent.steer()`(next-step バウンダリ) |
58
+ | **now** | 赤 | 中断して送信:現在のターンを停止し、メッセージは即座に処理 | `cancel()` → `updateQueue/remove`(inbox の重複挿入拒否を回避)→ `send(text)`(再送信、ドライバーを即座に起動) |
59
+
60
+ ## セッション凍結 / 再開(ピーク時間帯の一時停止)⭐ 推奨
61
+
62
+ > **節約の位置づけ**:これは本プラグインの DeepSeek 峰谷課金(2026-08-17 発効)に対する**コア推奨機能**です——ピーク時間帯の単価は倍増、オフピーク時は半額。手動凍結で緊急でない生成を「一時停止」し、オフピーク時に再開することで、高価な窗口を直接回避します。
63
+ >
64
+ > **推奨セットアップ**:**リマインダー**プラグイン([dsh-notify](https://github.com/zhengjy01/dsh-notify))ピーク出入り時に通知;**課金統計**プラグイン([dsh-deepseek-usage](https://github.com/yyb16yyb-hub/dsh-deepseek-usage)、[dsh-cost-tracker](https://github.com/yflmq001/dsh-cost-tracker)、[dsh-billing-balance](https://github.com/YZz-S/dsh-billing-balance))凍結前後の実際の支出を確認。
65
+
66
+ - **凍結**:現在のターンは**中断されず**、自然に完了してから一時停止;キューは凍結と**疎結合**——凍結はエージェントの消費(実行/挿入/追加)のみを停止し、待機エリアは表示されたまま**完全に操作可能**(順序変更、編集、削除、赤/黄/緑の挿入段階設定);
67
+ - **再開**:(修正済みの)キューが再送信され、**各エントリは予定された段階で実行**(赤=中断して即座に処理、黄=挿入、緑=キュー);エージェントは FIFO 継続;
68
+ - **セッション隔離**:凍結状態と detached キューは **sessionId で分離**(`Map<sessionId, …>`)——セッション A の凍結はセッション B のバナー/ボタン/キューに影響しません;
69
+ - **エンジン**:凍結 = `updateQueue(remove)` で各行を分離(段階のコピーはプラグイン store にセッションごと保存)、現在のターンが pending なしで自然に停止;再開 = まず `sessionGuard.resume(sessionId)`、その後 `send(text)` で再送信してドライバーを起動(赤段階は `cancel()` の後に送信);
70
+ - 注意:画像などの非テキスト内容を含むキューイング済みメッセージは再送信できず、凍結時にキューから解放されます(復元されません)。
71
+
72
+ ### dsh-session-guard によるセッション級ロック
73
+
74
+ 凍結ボタンは **sessionGuard ブリッジ**(`POST /session-guard/rpc { action: stopNextTurn|resume, sessionId }`)を介してサービス側の**セッション級ロック**にハンドオフします。同時にコンポーザブロック(`conversation.blocks.set`)を raise し、入力ボックスが inert になり、Enter が会話に漏れなくなります。
75
+
76
+ ## キュー管理
77
+
78
+ 待機エリアの各行(未凍結時)は以下の操作を提供:
79
+
80
+ | 操作 | 説明 |
81
+ |---|---|
82
+ | 上へ/下へ移動 | FIFO 順序を再構築(画像メッセージがキューにある場合は無効) |
83
+ | **ドラッグで並べ替え** | 行をドラッグしてターゲット位置に移動(ネイティブ HTML5 DnD) |
84
+ | コンポーザに送り直して編集 | メッセージ内容をコンポーザドラフトに戻し、キューから削除 |
85
+ | 編集/削除 | マルチラインエディタで直接編集/メッセージ取消 |
86
+ | 赤/黄/緑プランニング | 「3 段階のセマンティクス」参照 |
87
+ | 取り消して全消去 | 2 段階確認後、実行停止+全キュー削除 |
88
+
89
+ ## 日夜モード(ダーク自動適応)
90
+
91
+ キュー枠と凍結ボタンは dsh 公式セマンティックトークン(`--dsw-alias-*`)を引用し、ダークモードで**ダークグレー背景+白文字反転**に自動切替。設定不要。
92
+
93
+ ## インストール
94
+
95
+ ```sh
96
+ # 方式一:npm からインストール(推奨、安定版)
97
+ dsh plugin --profile web add dsh-input-traffic -w
98
+
99
+ # 方式二:GitHub から直接インストール(drscrewdriver フォーク専用)
100
+ dsh plugin --profile web add github:drscrewdriver/dsh-input-traffic#main
101
+
102
+ # 方式三:ローカルパスで装配
103
+ # dsh plugin --profile web add /absolute/path/to/dsh-input-traffic -w
104
+
105
+ # 確認
106
+ dsh web --dump-config | grep -B1 -A2 'input-traffic'
107
+
108
+ # dsh web 再起動(必須!)
109
+ dsh web
110
+ ```
111
+
112
+ > ⚠️ **GitHub ネットワーク到達性**:github: 直接インストールは github.com への接続が必要です。ネットワーク制限がある場合はプロキシまたはミラーアクセラレータを設定してください。
113
+
114
+ > **供应链冷却期**:pnpm 11 の `minimumReleaseAge` ポリシーにより、新規公開版が `ERR_PNPM_MINIMUM_RELEASE_AGE_VIOLATION` でブロックされることがあります。`~/.dsh/profiles/web/pnpm-workspace.yaml` の `minimumReleaseAgeExclude` にバージョンを追加してください。
115
+
116
+ 詳細は [INSTALL.ja.md](./INSTALL.ja.md) を参照。
117
+
118
+ ## 開発(TDD + Lint)
119
+
120
+ ```sh
121
+ npm run tdd # vitest watch:変更で再実行、赤→緑ループ
122
+ npm run lint # ESLint flat config
123
+ npm run lint:fix # 自動修正
124
+ npm run verify # 一体化ゲート:lint + test + build + verify-assembly
125
+ ```
126
+
127
+ ## 使い方
128
+
129
+ 1. エージェントがビジーなとき直接入力して送信——メッセージは**待機エリアに入ります**(デフォルト緑キュー);
130
+ 2. メッセージにプランニングボタンを押します:
131
+ - 🟡 黄 = 挿入——現在のアクション完了後に挿入;
132
+ - 🔴 赤 = 中断——現在のアクションを即座に停止、メッセージは即座に処理;
133
+ - 🟢 緑 = キューを維持(デフォルト);挿入済みメッセージに緑 = 取り消してキューに戻す;
134
+ 3. 順序変更/再編集:上へ下へ移動、コンポーザに送り直し、またはマルチラインインラインエディタ(Enter 保存、Shift+Enter 改行);
135
+ 4. **節約の鍵(推奨)**:ピーク時間帯(9:00-12:00、14:00-18:00)に近づいたら、「セッション凍結」を押して一時停止;オフピーク時に「セッション再開」で継続。
136
+
137
+ ## よくある質問
138
+
139
+ ### 中断後にメッセージに応答がない / 会話が停止する
140
+
141
+ 歴史的問題(修正済み)。原因:harness の inbox は同じメッセージの重複挿入を拒否します。中断後に元のメッセージを直接ステアすると `"message is already pending"` で拒否され、メッセージがキューに滞留してエージェントが停止します。現在の実装は `cancel → remove → resend`(新しいメッセージとして再送信)です。まだ発生する場合は、プラグインを最新にビルドして dsh web を再起動してください。
142
+
143
+ ### 編集保存に失敗した後、コンテンツはどこへ?
144
+
145
+ 失われません。保存に失敗した場合(エージェントが既にメッセージを取得済み)、編集内容は自動的にコンポーザに戻り「編集失敗、内容はコンポーザに戻されました」という通知が表示されます。コンポーザに既にドラフトがある場合は上書きされません。
146
+
147
+ ### 設定パネルに「ビジー時の Enter キー動作」がない
148
+
149
+ 正常です——プラグインが上書きした後、その設定行は非表示になり、Enter 行為は緑キューに固定されます。
150
+
151
+ ### 凍結後にキューイングされたメッセージが消えた
152
+
153
+ 正常です——凍結はキューをプラグイン store に保存します(セッションごと隔離、待機エリアから凍結リストに移動)。再開後に再表示されます。**ページを更新すると凍結キューは失われます**——凍結中に更新しないでください。
154
+
155
+ ### 上へ/下へボタンが使用不可
156
+
157
+ キューに画像などの非テキストメッセージが含まれている場合、並べ替えは無効になります(画像メッセージは再送信不可)。コンポーザに送り直して編集も同様です。
158
+
159
+ ## アンインストール
160
+
161
+ ```sh
162
+ dsh plugin --profile web remove dsh-input-traffic
163
+ ```
164
+
165
+ 再起動後、公式のキュー dock と「ビジー時の Enter キー動作」設定行が復元されます。
166
+
167
+ ## 互換性とプライバシー
168
+
169
+ - DeepSeek Harness と web プロフィールが必要です。Windows / macOS / Linux の dsh web で検証済み。
170
+ - プラグインは純ブラウザ側(クライアント)プラグインです。すべての操作は dsh 既存の RPC を介して行われ、**公式ソースは変更しません**。
171
+ - プラグインはセッション内容以外のデータを読み取ったりアップロードしません。凍結キューはブラウザメモリにのみ保存されます。
172
+
173
+ ## drscrewdriver DSH Plugin Family
174
+
175
+ 本プロジェクトは [drscrewdriver](https://github.com/drscrewdriver) がメンテナンスする DSH プラグインシリーズの一つです:
176
+
177
+ | プラグイン | 一言説明 |
178
+ |---|---|
179
+ | **[dsh-input-traffic](https://github.com/drscrewdriver/dsh-input-traffic)** | DSH Web GUI ビジー時入力キュー:3 段階交通管制、ドラッグ並べ替え、セッション凍結 |
180
+ | **[dsh-session-guard](https://github.com/drscrewdriver/dsh-session-guard)** | ピーク自動セッションゲート:週末モード + ピーク自動暂停 + セッション級ロック + バックエンド自動リトライ |
181
+ | [dsh-thinking-levels](https://github.com/drscrewdriver/dsh-thinking-levels) | ラウンド単位 reasoning_effort 制御:Auto スケジューリングまたは手動固定 |
182
+ | [dsh-seatbelt-sandbox](https://github.com/drscrewdriver/dsh-seatbelt-sandbox) | macOS Seatbelt サンドボックスアダプタ |
183
+ | [dsh-switch-search](https://github.com/drscrewdriver/dsh-switch-search) | サイドバー会話検索強化 |
184
+
185
+ ## ライセンス
186
+
187
+ MIT