dsh-input-traffic 0.5.5 → 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/README.ko.md CHANGED
@@ -1,181 +1,181 @@
1
- <p align="center">
2
- <strong>DeepSeek Harness Web GUI용 3단계 입력 트래픽 제어</strong>
3
- </p>
4
- <p align="center">
5
- <a href="README.en.md">English</a> · <a href="README.md">中文</a> · <a href="README.ja.md">日本語</a> · <strong>한국어</strong>
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
- > 에이전트가 바쁠 때 "중단" 또는 "대기" 둘 중 하나가 아닙니다: 빨간색은 즉시 중단 후 전송, 노란색은 다음 턴에 삽입, 초록색은 끝까지 대기 — 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로 격리** — 한 세션의 동결은 다른 세션에 영향을 주지 않습니다.
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 시행)에 대한 **핵심 권장 기능**입니다 — 피크 시간대 단가 2배, 오피크는 반값. 수동 동결로 긴급하지 않은 생성을 "일시정지"하고 오피크에 재개하면 비싼 시간대를 직접 회피합니다.
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
- - **세션 격리**: 동결 상태와 분리된 대기열은 **sessionId로 격리** — 세션 A의 동결은 세션 B의 배너/버튼/대기열에 영향 없음;
69
- - **엔진**: 동결 = `updateQueue/remove)`로 각 행 분리(단계별 복사본은 플러그인 store에 세션별 저장), 현재 턴이 pending 없이 자연 정지; 재개 = 먼저 `sessionGuard.resume(sessionId)`, 그 후 `send(text)`로 재전송하여 드라이버 깨우기(빨간 단계는 `cancel()` 후 전송);
70
- - 주의: 이미지 등 비텍스트 내용이 포함된 대기열 메시지는 재전송 불가하며, 동결 시 대기열에서 해제됩니다(복원되지 않음).
71
-
72
- ## 대기열 관리
73
-
74
- 대기영역 각 행(미동결 시)은 다음 작업을 제공:
75
-
76
- | 작업 | 설명 |
77
- |---|---|
78
- | 위로/아래로 이동 | FIFO 순서 재구성(이미지 메시지가 대기열에 있으면 비활성화) |
79
- | **드래그로 재정렬** | 행을 드래그하여 대상 위치로 이동(네이티브 HTML5 DnD) |
80
- | 컴포저로 되돌려 편집 | 메시지 내용을 컴포저 초안으로 복귀 |
81
- | 편집/삭제 | 멀티라인 에디터로 직접 편집/취소 |
82
- | 빨간/노란/초록 계획 | "3단계 의미론" 참조 |
83
- | 취소 후 전체 지우기 | 2단계 확인 후 실행 중지 + 전체 대기열 삭제 |
84
-
85
- ## 주야 모드(자동 다크 적응)
86
-
87
- 대기열 프레임과 동결 버튼은 모두 dsh 공식 시맨틱 토큰(`--dsw-alias-*`)을 사용하며, 다크모드에서 **다크그레이 배경 + 흰색 반전 텍스트**로 자동 전환. 설정 불필요.
88
-
89
- ## 설치
90
-
91
- ```sh
92
- # 방법 1: npm에서 설치(권장, 안정 버전)
93
- dsh plugin --profile web add dsh-input-traffic -w
94
-
95
- # 방법 2: GitHub에서 직접 설치(drscrewdriver 포크 전용)
96
- dsh plugin --profile web add github:drscrewdriver/dsh-input-traffic#main
97
-
98
- # 방법 3: 로컬 경로로 조립
99
- # dsh plugin --profile web add /absolute/path/to/dsh-input-traffic -w
100
-
101
- # 확인
102
- dsh web --dump-config | grep -B1 -A2 'input-traffic'
103
-
104
- # dsh web 재시작(필수!)
105
- dsh web
106
- ```
107
-
108
- > ⚠️ **GitHub 네트워크 도달성**: github: 직접 설치는 github.com 연결이 필요합니다. 네트워크 제한이 있는 경우 프록시 또는 미러 가속기를 설정하세요.
109
-
110
- 상세는 [INSTALL.ko.md](./INSTALL.ko.md)를 참조하세요.
111
-
112
- ## 개발(TDD + Lint)
113
-
114
- ```sh
115
- npm run tdd # vitest watch: 변경 시 재실행, 빨강→초록 루프
116
- npm run lint # ESLint flat config
117
- npm run lint:fix # 자동 수정
118
- npm run verify # 통합 게이트: lint + test + build + verify-assembly
119
- ```
120
-
121
- ## 사용법
122
-
123
- 1. 에이전트가 바쁠 때 직접 입력하여 전송 — 메시지는 **대기 영역에 진입**(기본 초록 대기열);
124
- 2. 메시지에 계획 버튼을 누릅니다:
125
- - 🟡 노랑 = 삽입 — 현재 액션 완료 후 삽입;
126
- - 🔴 빨강 = 중단 — 현재 액션을 즉시 중지, 메시지가 즉시 처리;
127
- - 🟢 초록 = 대기 유지(기본값); 삽입된 메시지에 초록 = 취소하여 대기열로 복귀;
128
- 3. 순서 변경/재편집: 위로/아래로 이동, 컴포저로 되돌리기, 또는 멀티라인 인라인 에디터(Enter 저장, Shift+Enter 줄바꿈);
129
- 4. **절약 핵심(권장)**: 피크 시간대(9:00-12:00, 14:00-18:00)에 가까워지면 "세션 동결"을 눌러 일시정지; 오피크에 "세션 재개"로 계속.
130
-
131
- ## 자주 묻는 질문
132
-
133
- ### 중단 후 메시지에 응답이 없음 / 대화 정지
134
-
135
- 과거 문제(수정 완료). 원인: harness inbox는 이미 대기 중인 메시지의 중복 삽입을 거부합니다. 중단 후 원본 메시지를 직접 steer하면 `"message is already pending"`으로 거부되어 메시지가 대기열에 고정되고 에이전트가 정지합니다. 현재 구현은 `cancel → remove → resend`(새 메시지로 재전송)입니다. 여전히 발생하면 플러그인을 최신 빌드하고 dsh web을 재시작하세요.
136
-
137
- ### 편집 저장 실패 후 내용은 어디로?
138
-
139
- 손실되지 않습니다. 저장 실패 시(에이전트가 이미 메시지를 가져간 경우), 편집 내용은 자동으로 컴포저로 돌아가 "편집 실패, 내용이 컴포저로 돌아갔습니다" 알림이 표시됩니다. 컴포저에 이미 초안이 있으면 덮어쓰지 않습니다.
140
-
141
- ### 설정 패널에 "바쁜 동안 Enter 키 동작"이 없음
142
-
143
- 정상입니다 — 플러그인이 오버라이드한 후 해당 설정 행이 숨겨지고 Enter 동작은 초록 대기열로 고정됩니다.
144
-
145
- ### 동결 후 대기열 메시지가 사라짐
146
-
147
- 정상입니다 — 동결은 대기열을 플러그인 store에 저장합니다(세션별 격리, 대기 영역에서 동결 리스트로 이동). 재개 후 다시 표시됩니다. **페이지 새로고침 시 동결 대기열은 손실됩니다** — 동결 중 새로고침하지 마세요.
148
-
149
- ### 위로/아래로 버튼 사용 불가
150
-
151
- 대기열에 이미지 등 비텍스트 메시지가 포함되어 있으면 재정렬이 비활성화됩니다(이미지 메시지는 재전송 불가). 컴포저로 되돌려 편집도 마찬가지.
152
-
153
- ## 제거
154
-
155
- ```sh
156
- dsh plugin --profile web remove dsh-input-traffic
157
- ```
158
-
159
- 재시작 후 공식 대기열 dock과 "바쁜 동안 Enter 키 동작" 설정 행이 복원됩니다.
160
-
161
- ## 호환성 및 개인정보
162
-
163
- - DeepSeek Harness와 web 프로필이 필요합니다. Windows/macOS/Linux dsh web에서 검증 완료.
164
- - 플러그인은 브라우저 측(클라이언트) 전용 — 모든 작업은 dsh 기존 RPC를 통해 수행되며 **공식 소스를 변경하지 않습니다**.
165
- - 플러그인은 세션 내용 이외의 데이터를 읽거나 업로드하지 않습니다. 동결 대기열은 브라우저 메모리에만 저장됩니다.
166
-
167
- ## drscrewdriver DSH Plugin Family
168
-
169
- 본 프로젝트는 [drscrewdriver](https://github.com/drscrewdriver)가 유지보수하는 DSH 플러그인 시리즈의 하나입니다:
170
-
171
- | 플러그인 | 한 줄 설명 |
172
- |---|---|
173
- | **[dsh-input-traffic](https://github.com/drscrewdriver/dsh-input-traffic)** | DSH Web GUI 바쁜 시간 입력 대기열: 3단계 트래픽 제어, 드래그 재정렬, 세션 동결 |
174
- | **[dsh-session-guard](https://github.com/drscrewdriver/dsh-session-guard)** | 피크 자동 세션 게이트: 주말 모드 + 피크 자동 일시정지 + 세션급 잠금 + 백엔드 자동 재시도 |
175
- | [dsh-thinking-levels](https://github.com/drscrewdriver/dsh-thinking-levels) | 라운드별 reasoning_effort 제어: Auto 스케줄링 또는 수동 고정 |
176
- | [dsh-seatbelt-sandbox](https://github.com/drscrewdriver/dsh-seatbelt-sandbox) | macOS Seatbelt 샌드박스 어댑터 |
177
- | [dsh-switch-search](https://github.com/drscrewdriver/dsh-switch-search) | 사이드바 대화 검색 강화 |
178
-
179
- ## 라이선스
180
-
181
- MIT
1
+ <p align="center">
2
+ <strong>DeepSeek Harness Web GUI용 3단계 입력 트래픽 제어</strong>
3
+ </p>
4
+ <p align="center">
5
+ <a href="README.en.md">English</a> · <a href="README.md">中文</a> · <a href="README.ja.md">日本語</a> · <strong>한국어</strong>
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
+ > 에이전트가 바쁠 때 "중단" 또는 "대기" 둘 중 하나가 아닙니다: 빨간색은 즉시 중단 후 전송, 노란색은 다음 턴에 삽입, 초록색은 끝까지 대기 — 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로 격리** — 한 세션의 동결은 다른 세션에 영향을 주지 않습니다.
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 시행)에 대한 **핵심 권장 기능**입니다 — 피크 시간대 단가 2배, 오피크는 반값. 수동 동결로 긴급하지 않은 생성을 "일시정지"하고 오피크에 재개하면 비싼 시간대를 직접 회피합니다.
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
+ - **세션 격리**: 동결 상태와 분리된 대기열은 **sessionId로 격리** — 세션 A의 동결은 세션 B의 배너/버튼/대기열에 영향 없음;
69
+ - **엔진**: 동결 = `updateQueue/remove)`로 각 행 분리(단계별 복사본은 플러그인 store에 세션별 저장), 현재 턴이 pending 없이 자연 정지; 재개 = 먼저 `sessionGuard.resume(sessionId)`, 그 후 `send(text)`로 재전송하여 드라이버 깨우기(빨간 단계는 `cancel()` 후 전송);
70
+ - 주의: 이미지 등 비텍스트 내용이 포함된 대기열 메시지는 재전송 불가하며, 동결 시 대기열에서 해제됩니다(복원되지 않음).
71
+
72
+ ## 대기열 관리
73
+
74
+ 대기영역 각 행(미동결 시)은 다음 작업을 제공:
75
+
76
+ | 작업 | 설명 |
77
+ |---|---|
78
+ | 위로/아래로 이동 | FIFO 순서 재구성(이미지 메시지가 대기열에 있으면 비활성화) |
79
+ | **드래그로 재정렬** | 행을 드래그하여 대상 위치로 이동(네이티브 HTML5 DnD) |
80
+ | 컴포저로 되돌려 편집 | 메시지 내용을 컴포저 초안으로 복귀 |
81
+ | 편집/삭제 | 멀티라인 에디터로 직접 편집/취소 |
82
+ | 빨간/노란/초록 계획 | "3단계 의미론" 참조 |
83
+ | 취소 후 전체 지우기 | 2단계 확인 후 실행 중지 + 전체 대기열 삭제 |
84
+
85
+ ## 주야 모드(자동 다크 적응)
86
+
87
+ 대기열 프레임과 동결 버튼은 모두 dsh 공식 시맨틱 토큰(`--dsw-alias-*`)을 사용하며, 다크모드에서 **다크그레이 배경 + 흰색 반전 텍스트**로 자동 전환. 설정 불필요.
88
+
89
+ ## 설치
90
+
91
+ ```sh
92
+ # 방법 1: npm에서 설치(권장, 안정 버전)
93
+ dsh plugin --profile web add dsh-input-traffic -w
94
+
95
+ # 방법 2: GitHub에서 직접 설치(drscrewdriver 포크 전용)
96
+ dsh plugin --profile web add github:drscrewdriver/dsh-input-traffic#main
97
+
98
+ # 방법 3: 로컬 경로로 조립
99
+ # dsh plugin --profile web add /absolute/path/to/dsh-input-traffic -w
100
+
101
+ # 확인
102
+ dsh web --dump-config | grep -B1 -A2 'input-traffic'
103
+
104
+ # dsh web 재시작(필수!)
105
+ dsh web
106
+ ```
107
+
108
+ > ⚠️ **GitHub 네트워크 도달성**: github: 직접 설치는 github.com 연결이 필요합니다. 네트워크 제한이 있는 경우 프록시 또는 미러 가속기를 설정하세요.
109
+
110
+ 상세는 [INSTALL.ko.md](./INSTALL.ko.md)를 참조하세요.
111
+
112
+ ## 개발(TDD + Lint)
113
+
114
+ ```sh
115
+ npm run tdd # vitest watch: 변경 시 재실행, 빨강→초록 루프
116
+ npm run lint # ESLint flat config
117
+ npm run lint:fix # 자동 수정
118
+ npm run verify # 통합 게이트: lint + test + build + verify-assembly
119
+ ```
120
+
121
+ ## 사용법
122
+
123
+ 1. 에이전트가 바쁠 때 직접 입력하여 전송 — 메시지는 **대기 영역에 진입**(기본 초록 대기열);
124
+ 2. 메시지에 계획 버튼을 누릅니다:
125
+ - 🟡 노랑 = 삽입 — 현재 액션 완료 후 삽입;
126
+ - 🔴 빨강 = 중단 — 현재 액션을 즉시 중지, 메시지가 즉시 처리;
127
+ - 🟢 초록 = 대기 유지(기본값); 삽입된 메시지에 초록 = 취소하여 대기열로 복귀;
128
+ 3. 순서 변경/재편집: 위로/아래로 이동, 컴포저로 되돌리기, 또는 멀티라인 인라인 에디터(Enter 저장, Shift+Enter 줄바꿈);
129
+ 4. **절약 핵심(권장)**: 피크 시간대(9:00-12:00, 14:00-18:00)에 가까워지면 "세션 동결"을 눌러 일시정지; 오피크에 "세션 재개"로 계속.
130
+
131
+ ## 자주 묻는 질문
132
+
133
+ ### 중단 후 메시지에 응답이 없음 / 대화 정지
134
+
135
+ 과거 문제(수정 완료). 원인: harness inbox는 이미 대기 중인 메시지의 중복 삽입을 거부합니다. 중단 후 원본 메시지를 직접 steer하면 `"message is already pending"`으로 거부되어 메시지가 대기열에 고정되고 에이전트가 정지합니다. 현재 구현은 `cancel → remove → resend`(새 메시지로 재전송)입니다. 여전히 발생하면 플러그인을 최신 빌드하고 dsh web을 재시작하세요.
136
+
137
+ ### 편집 저장 실패 후 내용은 어디로?
138
+
139
+ 손실되지 않습니다. 저장 실패 시(에이전트가 이미 메시지를 가져간 경우), 편집 내용은 자동으로 컴포저로 돌아가 "편집 실패, 내용이 컴포저로 돌아갔습니다" 알림이 표시됩니다. 컴포저에 이미 초안이 있으면 덮어쓰지 않습니다.
140
+
141
+ ### 설정 패널에 "바쁜 동안 Enter 키 동작"이 없음
142
+
143
+ 정상입니다 — 플러그인이 오버라이드한 후 해당 설정 행이 숨겨지고 Enter 동작은 초록 대기열로 고정됩니다.
144
+
145
+ ### 동결 후 대기열 메시지가 사라짐
146
+
147
+ 정상입니다 — 동결은 대기열을 플러그인 store에 저장합니다(세션별 격리, 대기 영역에서 동결 리스트로 이동). 재개 후 다시 표시됩니다. **페이지 새로고침 시 동결 대기열은 손실됩니다** — 동결 중 새로고침하지 마세요.
148
+
149
+ ### 위로/아래로 버튼 사용 불가
150
+
151
+ 대기열에 이미지 등 비텍스트 메시지가 포함되어 있으면 재정렬이 비활성화됩니다(이미지 메시지는 재전송 불가). 컴포저로 되돌려 편집도 마찬가지.
152
+
153
+ ## 제거
154
+
155
+ ```sh
156
+ dsh plugin --profile web remove dsh-input-traffic
157
+ ```
158
+
159
+ 재시작 후 공식 대기열 dock과 "바쁜 동안 Enter 키 동작" 설정 행이 복원됩니다.
160
+
161
+ ## 호환성 및 개인정보
162
+
163
+ - DeepSeek Harness와 web 프로필이 필요합니다. Windows/macOS/Linux dsh web에서 검증 완료.
164
+ - 플러그인은 브라우저 측(클라이언트) 전용 — 모든 작업은 dsh 기존 RPC를 통해 수행되며 **공식 소스를 변경하지 않습니다**.
165
+ - 플러그인은 세션 내용 이외의 데이터를 읽거나 업로드하지 않습니다. 동결 대기열은 브라우저 메모리에만 저장됩니다.
166
+
167
+ ## drscrewdriver DSH Plugin Family
168
+
169
+ 본 프로젝트는 [drscrewdriver](https://github.com/drscrewdriver)가 유지보수하는 DSH 플러그인 시리즈의 하나입니다:
170
+
171
+ | 플러그인 | 한 줄 설명 |
172
+ |---|---|
173
+ | **[dsh-input-traffic](https://github.com/drscrewdriver/dsh-input-traffic)** | DSH Web GUI 바쁜 시간 입력 대기열: 3단계 트래픽 제어, 드래그 재정렬, 세션 동결 |
174
+ | **[dsh-session-guard](https://github.com/drscrewdriver/dsh-session-guard)** | 피크 자동 세션 게이트: 주말 모드 + 피크 자동 일시정지 + 세션급 잠금 + 백엔드 자동 재시도 |
175
+ | [dsh-thinking-levels](https://github.com/drscrewdriver/dsh-thinking-levels) | 라운드별 reasoning_effort 제어: Auto 스케줄링 또는 수동 고정 |
176
+ | [dsh-seatbelt-sandbox](https://github.com/drscrewdriver/dsh-seatbelt-sandbox) | macOS Seatbelt 샌드박스 어댑터 |
177
+ | [dsh-switch-search](https://github.com/drscrewdriver/dsh-switch-search) | 사이드바 대화 검색 강화 |
178
+
179
+ ## 라이선스
180
+
181
+ MIT
package/README.md CHANGED
@@ -27,14 +27,16 @@
27
27
 
28
28
  > **▼ DSH 版本适配**
29
29
  >
30
- > 本插件(compat/0.1.5 线,0.2.12-beta.1 起)**仅支持 DSH v0.1.5+**。
30
+ > 本插件(**compat/0.2.0 线,0.6.0 起**)**仅支持 DSH 0.2.0 线**(`>=0.2.0-rc.1 <0.2.1-0`,npm dist-tag `dsh-0.2.0`)。
31
31
  >
32
32
  > | DSH 版本 | 状态 | 说明 |
33
33
  > | --- | --- | --- |
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+)或更早版本 |
34
+ > | ≥ 0.2.0-rc.1 且 < 0.2.1-0 | ✅ 支持 | 面向 0.2.0-rc.1 验证;宿主 peer 门槛强制校验该窗口 |
35
+ > | 0.1.7 线 | → 换用 `dsh-0.1.7` dist-tag(0.5.3,compat/0.1.7 分支维护) |
36
+ > | 0.1.5 线 | → 换用 `dsh-0.1.5` dist-tag(0.2.12-beta.1) |
37
+ > | < 0.2.0-rc.1 或 ≥ 0.2.1-0 | ⚠️ 不支持 | 宿主 preflight 直接拒绝安装;0.2.1 起需重新适配 |
36
38
  >
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
+ > - **0.2.0-rc.1 对插件 API 完全兼容 0.1.7**(manifest / settings 席位 / slot 机制 / 会话格式 V4 未动),服务面(`send` / `cancel` / `updateQueue` / `input.setDraft` / `input.notify`)无破坏记录。本线为**元数据换代**:peer/engines 换段、依赖树对 0.2.0 宿主重装,仅一处实配更新——`dsh-client-ui-primitives` 0.2.0 删除了图标导出的 `*14` / `*16` 尺寸后缀族,统一改用 `*Medium`(`IconProps.size` 显式像素行为不变,渲染尺寸不受影响)。
38
40
  > - **队列条位置**:注册 `order: 1000`,排在 `conversation.input.dock` 带内所有已知条目(todo 0 / goal 10 / 官方 queue 20 / dsh-perm-gate 提示 30)之后,紧贴输入卡片。DSH 没有 "last" 语义,这是约定而非结构性保证——第三方插件若注册更大的 `order` 仍可能插到它下面。
39
41
 
40
42
  > **▼ DSH 0.1.5 已知回归(宿主侧,非本插件 bug)**
package/dsh.plugin.json CHANGED
@@ -1,16 +1,16 @@
1
- {
2
- "id": "dsh-external/dsh-input-traffic",
3
- "version": "0.5.5",
4
- "main": "./lib/index.js",
5
- "description": "Busy-time input queue: three-tier planning, drag-to-reorder, interject/interrupt, batch clear, session freeze.",
6
- "engines": {
7
- "dsh": ">=0.1.7-rc.1 <0.1.8-0"
8
- },
9
- "contributes": {
10
- "tools": [],
11
- "skills": []
12
- },
13
- "client": {
14
- "main": "./lib/client.js"
15
- }
16
- }
1
+ {
2
+ "id": "dsh-external/dsh-input-traffic",
3
+ "version": "0.6.1",
4
+ "main": "./lib/index.js",
5
+ "description": "Busy-time input queue: three-tier planning, drag-to-reorder, interject/interrupt, batch clear, session freeze.",
6
+ "engines": {
7
+ "dsh": ">=0.2.0-rc.1 <0.2.1-0"
8
+ },
9
+ "contributes": {
10
+ "tools": [],
11
+ "skills": []
12
+ },
13
+ "client": {
14
+ "main": "./lib/client.js"
15
+ }
16
+ }
package/lib/client.js CHANGED
@@ -210,8 +210,8 @@ window.__ModuleLoader__.load({
210
210
  for (const listener of listeners) listener();
211
211
  }
212
212
  //#endregion
213
- //#region \0dsh-css:E:\test\rewrite-agently\mine-dsh-plugins\dsh-input-traffic\src\client\steer-queue-dock.module.css.mjs
214
- const css$1 = ".FNESVa_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}.FNESVa_panel{background:var(--dsw-alias-bg-layer-1,#fffc);border:1px solid var(--dsw-alias-border-l2,#00000014);border-radius:10px;overflow:hidden}.FNESVa_toolbar{border-bottom:1px solid var(--dsw-alias-border-l2,#0000000f);align-items:center;gap:8px;padding:4px 8px;display:flex}.FNESVa_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}.FNESVa_header:disabled{cursor:default}.FNESVa_lead{color:var(--dsw-alias-label-tertiary,#9ca3af);display:inline-flex}.FNESVa_count{font-weight:600}.FNESVa_chevron{color:var(--dsw-alias-label-tertiary,#9ca3af);display:inline-flex}.FNESVa_toolbarActions{margin-left:auto}.FNESVa_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}.FNESVa_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}.FNESVa_freeze[aria-pressed=true]{border-color:var(--dsw-alias-state-success-primary,#30a46c);color:var(--dsw-alias-state-success-primary,#30a46c)}.FNESVa_freeze:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000a)}.FNESVa_freeze:disabled{opacity:.5;cursor:default}.FNESVa_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}.FNESVa_frozenList{margin:0;padding:4px;list-style:none}.FNESVa_frozenRow{border-radius:6px;align-items:center;gap:8px;padding:4px 6px;display:flex}.FNESVa_frozenMark{color:var(--dsw-alias-label-tertiary,#9ca3af);flex:none;margin-left:auto;font-size:11px}.FNESVa_clear:hover:not(:disabled){border-color:var(--dsw-alias-border-l3,#0000001f);background:var(--dsw-alias-interactive-bg-hover,#0000000a)}.FNESVa_clear:disabled{opacity:.5;cursor:default}.FNESVa_clearConfirm{border-color:var(--dsw-alias-state-error-primary,#e5484d);color:var(--dsw-alias-state-error-primary,#e5484d)}.FNESVa_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)}.FNESVa_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}.FNESVa_clearCancel:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000a)}.FNESVa_clearLabel{font-size:12px}.FNESVa_list{margin:0;padding:4px;list-style:none}.FNESVa_row{border-radius:6px;align-items:center;gap:8px;padding:4px 6px;display:flex}.FNESVa_row[draggable=true]{cursor:grab}.FNESVa_row[draggable=true]:active{cursor:grabbing}.FNESVa_rowDragOver{outline:2px dashed var(--dsw-alias-border-l4,#00000040);outline-offset:-2px;background:var(--dsw-alias-interactive-bg-hover,#0000000d)}.FNESVa_row:hover{background:var(--dsw-alias-interactive-bg-hover,#00000008)}.FNESVa_row[data-editing]{align-items:flex-start}.FNESVa_preview{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--dsw-alias-label-primary,#1f2937);flex:1;font-size:13px;overflow:hidden}.FNESVa_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}.FNESVa_badgeLabel{color:inherit}.FNESVa_badgeNow{color:var(--dsw-alias-state-error-primary,#e5484d);background:color-mix(in srgb, var(--dsw-alias-state-error-primary,#e5484d) 10%, transparent)}.FNESVa_badgeNext{color:var(--dsw-alias-state-warn-primary,#e8a33d);background:color-mix(in srgb, var(--dsw-alias-state-warn-primary,#e8a33d) 12%, transparent)}.FNESVa_badgeLater{color:var(--dsw-alias-state-success-primary,#30a46c);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#30a46c) 12%, transparent)}.FNESVa_badgeNow .FNESVa_dot{background:var(--dsw-alias-state-error-primary,#e5484d)}.FNESVa_badgeNext .FNESVa_dot{background:var(--dsw-alias-state-warn-primary,#e8a33d)}.FNESVa_badgeLater .FNESVa_dot{background:var(--dsw-alias-state-success-primary,#30a46c)}.FNESVa_steeringList{margin:0;padding:0 4px 4px;list-style:none}.FNESVa_steeringList .FNESVa_row{opacity:.85}.FNESVa_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}.FNESVa_actions{align-items:center;gap:2px;display:inline-flex}.FNESVa_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}.FNESVa_action:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000d);color:var(--dsw-alias-label-primary,#1f2937)}.FNESVa_action:disabled{opacity:.4;cursor:default}.FNESVa_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}.FNESVa_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}.FNESVa_tier:hover:not(:disabled){border-color:var(--dsw-alias-border-l4,#0003)}.FNESVa_tier:disabled{cursor:default}.FNESVa_tierNow{background:#e5484d1f;border-color:#e5484d}.FNESVa_tierNext{background:#e8a33d1f;border-color:#e8a33d}.FNESVa_tierLater{border-color:var(--dsw-alias-state-success-primary,#30a46c);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#30a46c) 12%, transparent)}.FNESVa_dot{border-radius:50%;width:10px;height:10px}.FNESVa_tierNow .FNESVa_dot{background:#e5484d}.FNESVa_tierNext .FNESVa_dot{background:#e8a33d}.FNESVa_tierLater .FNESVa_dot{background:#30a46c}";
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_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
- "frozenRow": "FNESVa_frozenRow",
225
- "tier": "FNESVa_tier",
226
- "tierNext": "FNESVa_tierNext",
227
- "editor": "FNESVa_editor",
228
- "dock": "FNESVa_dock",
229
- "actions": "FNESVa_actions",
230
- "freeze": "FNESVa_freeze",
231
- "action": "FNESVa_action",
232
- "steeringList": "FNESVa_steeringList",
233
- "clearConfirm": "FNESVa_clearConfirm",
234
- "tierLater": "FNESVa_tierLater",
235
- "frozenList": "FNESVa_frozenList",
236
- "plan": "FNESVa_plan",
237
- "badgeNext": "FNESVa_badgeNext",
238
- "toolbar": "FNESVa_toolbar",
239
- "list": "FNESVa_list",
240
- "chevron": "FNESVa_chevron",
241
- "frozenMark": "FNESVa_frozenMark",
242
- "frozenBanner": "FNESVa_frozenBanner",
243
- "badge": "FNESVa_badge",
244
- "header": "FNESVa_header",
245
- "clearCancel": "FNESVa_clearCancel",
246
- "clearLabel": "FNESVa_clearLabel",
247
- "panel": "FNESVa_panel",
248
- "rowDragOver": "FNESVa_rowDragOver",
249
- "preview": "FNESVa_preview",
250
- "badgeLabel": "FNESVa_badgeLabel",
251
- "badgeLater": "FNESVa_badgeLater",
252
- "lead": "FNESVa_lead",
253
- "clear": "FNESVa_clear",
254
- "tierNow": "FNESVa_tierNow",
255
- "dot": "FNESVa_dot",
256
- "row": "FNESVa_row",
257
- "badgeNow": "FNESVa_badgeNow",
258
- "count": "FNESVa_count",
259
- "toolbarActions": "FNESVa_toolbarActions"
224
+ "freeze": "jJPyLG_freeze",
225
+ "clearLabel": "jJPyLG_clearLabel",
226
+ "dock": "jJPyLG_dock",
227
+ "clearConfirm": "jJPyLG_clearConfirm",
228
+ "editor": "jJPyLG_editor",
229
+ "plan": "jJPyLG_plan",
230
+ "badgeNext": "jJPyLG_badgeNext",
231
+ "frozenMark": "jJPyLG_frozenMark",
232
+ "badge": "jJPyLG_badge",
233
+ "list": "jJPyLG_list",
234
+ "badgeNow": "jJPyLG_badgeNow",
235
+ "clearCancel": "jJPyLG_clearCancel",
236
+ "preview": "jJPyLG_preview",
237
+ "steeringList": "jJPyLG_steeringList",
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",
245
+ "frozenList": "jJPyLG_frozenList",
246
+ "actions": "jJPyLG_actions",
247
+ "tierLater": "jJPyLG_tierLater",
248
+ "chevron": "jJPyLG_chevron",
249
+ "rowDragOver": "jJPyLG_rowDragOver",
250
+ "dot": "jJPyLG_dot",
251
+ "panel": "jJPyLG_panel",
252
+ "count": "jJPyLG_count",
253
+ "toolbar": "jJPyLG_toolbar",
254
+ "frozenRow": "jJPyLG_frozenRow",
255
+ "header": "jJPyLG_header",
256
+ "frozenBanner": "jJPyLG_frozenBanner",
257
+ "clear": "jJPyLG_clear",
258
+ "toolbarActions": "jJPyLG_toolbarActions",
259
+ "badgeLabel": "jJPyLG_badgeLabel"
260
260
  };
261
261
  //#endregion
262
262
  //#region src/client/steer-queue-dock.tsx
@@ -1223,8 +1223,8 @@ window.__ModuleLoader__.load({
1223
1223
  globalThis.__DSH_SESSION_GUARD_BRIDGE__ = true;
1224
1224
  } catch {}
1225
1225
  //#endregion
1226
- //#region \0dsh-css:E:\test\rewrite-agently\mine-dsh-plugins\dsh-input-traffic\src\client\freeze-button.module.css.mjs
1227
- const css = ".BUSMDW_freeze{border:1px solid var(--dsw-alias-border-l3,#0000001f);height:24px;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;white-space:nowrap;background:0 0;border-radius:6px;align-items:center;gap:4px;padding:0 8px;font-size:12px;display:inline-flex}.BUSMDW_freeze:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000a)}.BUSMDW_freeze[aria-pressed=true]{border-color:var(--dsw-alias-state-success-primary,#30a46c);color:var(--dsw-alias-state-success-primary,#30a46c);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#30a46c) 8%, transparent)}.BUSMDW_label{font-size:12px}";
1226
+ //#region \0dsh-css:E:\test\rewrite-agently\mine-dsh-plugins\_wt-020\dsh-input-traffic\src\client\freeze-button.module.css.mjs
1227
+ const css = "._5uus5a_freeze{border:1px solid var(--dsw-alias-border-l3,#0000001f);height:24px;color:var(--dsw-alias-label-secondary,#6b7280);cursor:pointer;white-space:nowrap;background:0 0;border-radius:6px;align-items:center;gap:4px;padding:0 8px;font-size:12px;display:inline-flex}._5uus5a_freeze:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover,#0000000a)}._5uus5a_freeze[aria-pressed=true]{border-color:var(--dsw-alias-state-success-primary,#30a46c);color:var(--dsw-alias-state-success-primary,#30a46c);background:color-mix(in srgb, var(--dsw-alias-state-success-primary,#30a46c) 8%, transparent)}._5uus5a_label{font-size:12px}";
1228
1228
  const tagId = "dsh-input-traffic/freeze-button.module.css";
1229
1229
  if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
1230
1230
  const tag = document.createElement("style");
@@ -1234,8 +1234,8 @@ window.__ModuleLoader__.load({
1234
1234
  document.head.appendChild(tag);
1235
1235
  }
1236
1236
  var freeze_button_module_css_default = {
1237
- "freeze": "BUSMDW_freeze",
1238
- "label": "BUSMDW_label"
1237
+ "freeze": "_5uus5a_freeze",
1238
+ "label": "_5uus5a_label"
1239
1239
  };
1240
1240
  //#endregion
1241
1241
  //#region src/client/freeze-button.tsx