dsh-remote-plugin 0.6.5 → 0.6.7

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.
@@ -2,7 +2,7 @@
2
2
  html, body { height: 100%; margin: 0; overflow: hidden; overscroll-behavior: none; background: var(--dsr-bg); color: var(--dsr-text); }
3
3
  .hidden { display: none !important; }
4
4
  .ds-app { position: fixed; inset: 0; display: flex; overflow: hidden; }
5
- .ds-sidebar { width: 280px; flex: none; display: flex; flex-direction: column; border-right: 1px solid var(--dsr-line); background: var(--dsr-panel); }
5
+ .ds-sidebar { width: 280px; flex: none; display: flex; flex-direction: column; border-right: 1px solid var(--dsr-line); background: var(--dsr-panel); overflow: hidden; }
6
6
  .ds-brand { display: flex; align-items: center; gap: 8px; padding: 14px 14px 10px; font-weight: 700; font-size: 15px; }
7
7
  .ds-logo { color: var(--dsr-accent-strong); }
8
8
  .ds-brand-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
@@ -15,16 +15,34 @@ html, body { height: 100%; margin: 0; overflow: hidden; overscroll-behavior: non
15
15
  .ds-btn:active { filter: brightness(.96); }
16
16
  a.ds-btn { text-decoration: none; }
17
17
  .ds-new-session .ds-btn { width: 100%; justify-content: center; }
18
- .ds-section-label { font-size: 11px; color: var(--dsr-muted); letter-spacing: .8px; padding: 10px 14px 6px; font-weight: 700; }
18
+ .ds-section-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; min-width: 0; padding-right: 10px; }
19
+ .ds-section-label { min-width: 0; flex: 1; font-size: 11px; color: var(--dsr-muted); letter-spacing: .8px; padding: 10px 14px 6px; font-weight: 700; }
20
+ .ds-session-sort {
21
+ width: 92px; min-width: 0; height: 26px; padding: 0 5px; color: var(--dsr-muted);
22
+ background: var(--dsr-bg-2); border: 1px solid var(--dsr-line); border-radius: 7px;
23
+ font: inherit; font-size: 10.5px; outline: none;
24
+ }
25
+ .ds-session-sort:focus { border-color: var(--dsr-accent-line); color: var(--dsr-text); }
19
26
  .ds-session-list { flex: 1; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 0 8px; display: flex; flex-direction: column; gap: 3px; }
20
- .ds-session-item { width: 100%; text-align: left; border: none; background: transparent; color: var(--dsr-text); font: inherit; font-size: 13px; padding: 8px 9px; border-radius: 9px; cursor: pointer; display: flex; flex-direction: column; gap: 3px; }
27
+ .ds-session-group {
28
+ display: flex; align-items: center; gap: 6px; flex: 0 0 auto; min-width: 0; min-height: 28px;
29
+ box-sizing: border-box; padding: 8px 10px 4px; border-bottom: 1px solid var(--dsr-line);
30
+ color: var(--dsr-accent-strong); font-size: 10px; font-weight: 700; line-height: 1.2;
31
+ }
32
+ .ds-session-group-icon { flex: 0 0 auto; color: var(--dsr-accent-2); font-size: 11px; }
33
+ .ds-session-group-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
34
+ .ds-session-item { width: 100%; flex: 0 0 auto; text-align: left; border: none; background: transparent; color: var(--dsr-text); font: inherit; font-size: 13px; padding: 8px 9px; border-radius: 9px; cursor: pointer; display: flex; flex-direction: column; gap: 3px; }
21
35
  .ds-session-item:hover { background: var(--dsr-bg-2); }
22
36
  .ds-session-item.current { background: var(--dsr-accent-soft); color: var(--dsr-accent-strong); }
23
37
  .ds-session-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
38
+ .ds-session-workspace { min-width: 0; color: var(--dsr-muted); font-size: 10.5px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
39
+ .ds-session-list.workspace-sorted .ds-session-workspace { display: none; }
40
+ .ds-session-list.workspace-sorted .ds-session-item { padding-top: 9px; padding-bottom: 9px; }
24
41
  .ds-session-meta { display: flex; gap: 7px; font-size: 11px; color: var(--dsr-muted); align-items: center; }
25
42
  .ds-session-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--dsr-line); }
26
43
  .ds-session-dot.running { background: var(--dsr-warning); }
27
- .ds-sidebar-foot { border-top: 1px solid var(--dsr-line); padding: 8px; display: flex; flex-direction: column; gap: 3px; }
44
+ .ds-sidebar-foot { border-top: 1px solid var(--dsr-line); padding: 8px; display: flex; flex-direction: column; gap: 3px; max-height: 58vh; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: thin; scrollbar-color: var(--dsr-line) transparent; }
45
+ .ds-sidebar-foot > * { flex-shrink: 0; }
28
46
  .ds-nav-item { display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; border: none; background: transparent; color: var(--dsr-text); font: inherit; font-size: 13px; padding: 9px 10px; border-radius: 9px; cursor: pointer; }
29
47
  .ds-nav-item:hover { background: var(--dsr-bg-2); }
30
48
  .ds-nav-item.active { background: var(--dsr-accent-soft); color: var(--dsr-accent-strong); }
@@ -63,6 +81,48 @@ a.ds-btn { text-decoration: none; }
63
81
  .ds-feedback-desc { font-size: 11px; color: var(--dsr-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
64
82
  @keyframes ds-feedback-in { from { opacity: 0; transform: translateY(6px) } to { opacity: 1; transform: translateY(0) } }
65
83
 
84
+ /* ---------- 工作台 ---------- */
85
+ .ds-workbench { border: 1px solid var(--dsr-line); border-radius: 12px; background: var(--dsr-bg-2); padding: 8px; display: flex; flex-direction: column; gap: 6px; }
86
+ .ds-wb-badge { font-size: 11.5px; font-weight: 700; color: var(--dsr-accent-strong); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
87
+ .ds-wb-unbound, .ds-wb-bound { display: flex; flex-direction: column; gap: 6px; }
88
+ .ds-wb-bind-btn { justify-content: center; width: 100%; }
89
+ .ds-wb-api-hint { font-size: 10.5px; color: var(--dsr-warning); line-height: 1.4; }
90
+ .ds-wb-head { display: flex; align-items: center; gap: 6px; width: 100%; text-align: left; border: none; background: transparent; color: var(--dsr-text); font: inherit; font-size: 12.5px; font-weight: 700; padding: 2px; cursor: pointer; }
91
+ .ds-wb-caret { flex: none; color: var(--dsr-muted); font-size: 10px; width: 12px; text-align: center; }
92
+ .ds-wb-head-text { flex: 1; min-width: 0; }
93
+ .ds-wb-actions { display: flex; gap: 6px; }
94
+ .ds-wb-actions .ds-mini-btn { flex: 1; }
95
+ .ds-wb-panel { border-top: 1px solid var(--dsr-divider); padding-top: 6px; display: flex; flex-direction: column; gap: 5px; max-height: 42vh; overflow-y: auto; scrollbar-width: thin; scrollbar-color: var(--dsr-line) transparent; }
96
+ .ds-wb-panel > * { flex-shrink: 0; }
97
+ .ds-wb-panel-title { font-size: 10.5px; font-weight: 700; color: var(--dsr-muted); letter-spacing: .6px; text-transform: uppercase; }
98
+ .ds-wb-project { border: 1px solid var(--dsr-line); border-radius: 9px; background: var(--dsr-panel); overflow: hidden; }
99
+ .ds-wb-project-head { width: 100%; display: flex; align-items: center; gap: 6px; border: none; background: transparent; color: var(--dsr-text); font: inherit; font-size: 12.5px; padding: 6px 8px; cursor: pointer; text-align: left; }
100
+ .ds-wb-project-title { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
101
+ .ds-wb-project-count { flex: none; font-size: 10.5px; color: var(--dsr-muted); background: var(--dsr-bg-2); border-radius: 999px; padding: 0 7px; line-height: 16px; }
102
+ .ds-wb-project-body { display: flex; flex-direction: column; gap: 3px; padding: 2px 6px 7px; }
103
+ .ds-wb-new-session { align-self: flex-start; margin: 2px 0 3px; }
104
+ .ds-wb-session { display: flex; align-items: center; gap: 6px; width: 100%; text-align: left; border: none; background: transparent; color: var(--dsr-text); font: inherit; font-size: 12px; padding: 5px 7px; border-radius: 7px; cursor: pointer; }
105
+ .ds-wb-session.current { background: var(--dsr-accent-soft); color: var(--dsr-accent-strong); }
106
+ .ds-wb-session-dot { flex: none; width: 6px; height: 6px; border-radius: 50%; background: var(--dsr-line); }
107
+ .ds-wb-session-dot.running { background: var(--dsr-warning); }
108
+ .ds-wb-session-title { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
109
+ .ds-wb-session-empty, .ds-wb-empty { font-size: 11px; color: var(--dsr-muted); padding: 5px 7px; line-height: 1.5; }
110
+ .ds-wb-unbind-panel { align-self: flex-end; }
111
+ .ds-archived-toggle { width: 100%; border: none; background: transparent; color: var(--dsr-muted); font: inherit; font-size: 11px; letter-spacing: .4px; padding: 7px 4px; cursor: pointer; text-align: center; }
112
+
113
+ /* ---------- 工作台绑定弹窗 ---------- */
114
+ .ds-wb-modal-card { width: min(620px, 100%); }
115
+ .ds-wb-modal-desc { font-size: 12.5px; color: var(--dsr-muted); line-height: 1.5; }
116
+ .ds-wb-fsbar, .ds-wb-manual { display: flex; align-items: center; gap: 8px; }
117
+ .ds-wb-fs-path { flex: 1; min-width: 0; font-size: 12px; color: var(--dsr-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
118
+ .ds-wb-fs-list { border: 1px solid var(--dsr-line); border-radius: 12px; background: var(--dsr-panel); max-height: 42vh; overflow-y: auto; }
119
+ .ds-wb-fs-row { display: flex; align-items: center; gap: 9px; padding: 8px 11px; border-bottom: 1px solid var(--dsr-divider); font-size: 13px; cursor: pointer; }
120
+ .ds-wb-fs-row:last-child { border-bottom: none; }
121
+ .ds-wb-fs-name { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
122
+ .ds-wb-select { flex: none; }
123
+ .ds-wb-manual input { flex: 1; min-width: 0; background: var(--dsr-panel); color: var(--dsr-text); border: 1px solid var(--dsr-line); border-radius: 10px; padding: 8px 10px; font: inherit; font-size: 13px; outline: none; }
124
+ .ds-wb-manual input:focus { border-color: var(--dsr-accent-line); }
125
+
66
126
  /* 写反馈弹层 */
67
127
  .ds-fb-chips { display: flex; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
68
128
  .ds-fb-chip {
@@ -146,7 +206,7 @@ a.ds-btn { text-decoration: none; }
146
206
  .ds-composer { flex: none; display: flex; flex-direction: column; gap: 8px; padding: 12px 16px; border-top: 1px solid var(--dsr-line); background: var(--dsr-panel); }
147
207
  .ds-composer textarea { width: 100%; min-width: 0; resize: none; background: var(--dsr-bg-2); color: var(--dsr-text); border: 1px solid var(--dsr-line); border-radius: 12px; padding: 10px 14px; font: inherit; font-size: 13.5px; line-height: 1.5; outline: none; min-height: 44px; max-height: 120px; box-sizing: border-box; }
148
208
  .ds-composer-actions { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
149
- .ds-composer-left { display: flex; align-items: center; gap: 8px; min-width: 0; }
209
+ .ds-composer-left { display: flex; align-items: center; gap: 8px; min-width: 0; flex-wrap: wrap; }
150
210
  .ds-composer-right { display: flex; align-items: center; flex: none; }
151
211
  .ds-composer .ds-btn { min-height: 34px; box-sizing: border-box; }
152
212
  .ds-send-btn { width: 36px; height: 36px; min-height: 36px; padding: 0; border-radius: 50%; background: var(--dsr-accent-strong); border-color: var(--dsr-accent-strong); color: var(--dsr-on-accent); font-size: 18px; line-height: 1; justify-content: center; }
@@ -269,6 +329,11 @@ a.ds-btn { text-decoration: none; }
269
329
  .ds-modal-card { width: min(520px, 100%); background: var(--dsr-panel); border: 1px solid var(--dsr-line); border-radius: 14px; padding: 16px; }
270
330
  .ds-modal-title { font-weight: 700; margin-bottom: 10px; }
271
331
  .ds-modal-body { display: flex; flex-direction: column; gap: 10px; max-height: 60vh; overflow-y: auto; }
332
+ .ds-workspace-create-desc { margin: 0; color: var(--dsr-muted); line-height: 1.55; }
333
+ .ds-workspace-create-location { display: flex; align-items: center; gap: 8px; min-width: 0; color: var(--dsr-muted); font-size: 12px; }
334
+ .ds-workspace-create-location code { min-width: 0; flex: 1; padding: 7px 9px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsr-text); background: var(--dsr-bg-2); border: 1px solid var(--dsr-line); border-radius: 9px; }
335
+ .ds-workspace-name { width: 100%; box-sizing: border-box; background: var(--dsr-bg-2); color: var(--dsr-text); border: 1px solid var(--dsr-line); border-radius: 9px; padding: 8px 10px; font: inherit; outline: none; }
336
+ .ds-workspace-name:focus { border-color: var(--dsr-accent-line); }
272
337
  .ds-modal-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 12px; }
273
338
  .ds-q-item { border: 1px solid var(--dsr-line); border-radius: 10px; padding: 9px 11px; }
274
339
  .ds-q-text { font-size: 13.5px; margin-bottom: 6px; }
@@ -332,3 +397,12 @@ a.ds-btn { text-decoration: none; }
332
397
  .ds-toast-stack { left: 10px; right: 10px; width: auto; }
333
398
  .mobile-only { display: block; }
334
399
  }
400
+
401
+ @media (max-width: 520px) {
402
+ .ds-topbar { gap: 6px; padding: 0 8px; }
403
+ .ds-top-right { gap: 5px; }
404
+ .ds-composer-actions { align-items: stretch; flex-wrap: wrap; gap: 6px; }
405
+ .ds-composer-left { flex: 1 1 100%; gap: 5px; }
406
+ .ds-composer-left .ds-btn { flex: 1 1 0; min-width: 0; padding-left: 7px; padding-right: 7px; overflow: hidden; text-overflow: ellipsis; }
407
+ .ds-composer-right { margin-left: auto; }
408
+ }
@@ -20,9 +20,34 @@
20
20
  <div class="ds-new-session">
21
21
  <button id="btn-new-session" class="ds-btn primary" data-i18n="ds.newSession">+ 新会话</button>
22
22
  </div>
23
- <div class="ds-section-label" data-i18n="ds.sessions">会话</div>
23
+ <div class="ds-section-head">
24
+ <div class="ds-section-label" data-i18n="ds.sessions">会话</div>
25
+ <select id="session-sort" class="ds-session-sort" data-i18n-aria="ds.sortLabel">
26
+ <option value="time" data-i18n="ds.sortTime">按时间</option>
27
+ <option value="workspace" data-i18n="ds.sortWorkspace">按工作区</option>
28
+ </select>
29
+ <button id="btn-new-workspace" class="ds-icon-btn ds-workspace-create" data-i18n-title="ds.newWorkspace" data-i18n-aria="ds.newWorkspace">+</button>
30
+ </div>
24
31
  <div class="ds-session-list" id="session-list"></div>
25
32
  <div class="ds-sidebar-foot">
33
+ <div id="workbench-box" class="ds-workbench">
34
+ <div id="wb-unbound" class="ds-wb-unbound">
35
+ <div class="ds-wb-badge" data-i18n="wb.unbound">DSH Remote(未绑定)</div>
36
+ <button id="btn-wb-bind" class="ds-btn ds-wb-bind-btn" data-i18n="wb.bind">绑定工作台</button>
37
+ <div id="wb-api-hint" class="ds-wb-api-hint hidden" data-i18n="wb.apiMissing">工作台接口不可用(需更新网关)</div>
38
+ </div>
39
+ <div id="wb-bound" class="ds-wb-bound hidden">
40
+ <button id="wb-head" class="ds-wb-head" type="button" aria-expanded="false">
41
+ <span id="wb-caret" class="ds-wb-caret" aria-hidden="true">▸</span>
42
+ <span id="wb-head-text" class="ds-wb-head-text"></span>
43
+ </button>
44
+ <div class="ds-wb-actions">
45
+ <button id="btn-wb-path" class="ds-mini-btn" data-i18n="wb.viewPath">已绑定 workspace</button>
46
+ <button id="btn-wb-unbind" class="ds-mini-btn" data-i18n="wb.unbind">解绑</button>
47
+ </div>
48
+ <div id="wb-panel" class="ds-wb-panel hidden"></div>
49
+ </div>
50
+ </div>
26
51
  <button class="ds-nav-item" data-view="view-files"><span class="ds-nav-ico">⇅</span><span data-i18n="ds.files">文件传输</span></button>
27
52
  <button class="ds-nav-item" data-view="view-settings"><span class="ds-nav-ico">⚙</span><span data-i18n="ds.settings">设置</span></button>
28
53
  <div class="ds-feedback">
@@ -116,6 +141,7 @@
116
141
  <div class="ds-fs-bar">
117
142
  <button id="fs-up" class="ds-btn" data-i18n="ds.fsUp">上级</button>
118
143
  <span id="fs-path" class="ds-fs-path">/</span>
144
+ <button id="fs-new-workspace" class="ds-btn" data-i18n="ds.fsNewWorkspace">新建工作区</button>
119
145
  <button id="fs-refresh" class="ds-btn" data-i18n="ds.fsRefresh">刷新</button>
120
146
  </div>
121
147
  <div id="fs-list" class="ds-fs-list"></div>
@@ -266,6 +292,22 @@
266
292
  </div>
267
293
  </div>
268
294
 
295
+ <!-- 新建工作区模态 -->
296
+ <div id="modal-workspace" class="ds-modal hidden">
297
+ <div class="ds-modal-card">
298
+ <div class="ds-modal-title" data-i18n="ds.workspaceCreateTitle">新建工作区</div>
299
+ <div class="ds-modal-body">
300
+ <p class="ds-workspace-create-desc" data-i18n="ds.workspaceCreateDesc">将在当前文件目录下创建文件夹,并自动打开新会话。</p>
301
+ <div class="ds-workspace-create-location"><span data-i18n="ds.workspaceParent">父目录</span><code id="workspace-parent-path">~</code></div>
302
+ <input id="workspace-name" class="ds-workspace-name" maxlength="120" autocomplete="off" data-i18n-placeholder="ds.workspaceNamePlaceholder" placeholder="例如:my-project">
303
+ </div>
304
+ <div class="ds-modal-actions">
305
+ <button id="workspace-cancel" class="ds-btn" data-i18n="ds.cancel">取消</button>
306
+ <button id="workspace-create" class="ds-btn primary" data-i18n="ds.workspaceCreate">创建并打开</button>
307
+ </div>
308
+ </div>
309
+ </div>
310
+
269
311
  <!-- 预设提示词管理模态 -->
270
312
  <div id="modal-presets" class="ds-modal hidden">
271
313
  <div class="ds-modal-card">
@@ -283,6 +325,28 @@
283
325
  </div>
284
326
  </div>
285
327
 
328
+ <div id="modal-workbench" class="ds-modal hidden">
329
+ <div class="ds-modal-card ds-wb-modal-card">
330
+ <div class="ds-modal-title" data-i18n="wb.modalTitle">绑定工作台</div>
331
+ <div class="ds-modal-body">
332
+ <div class="ds-wb-modal-desc" data-i18n="wb.modalDesc">选择工作台根目录,其下每个子文件夹会自动成为项目工作区。</div>
333
+ <div class="ds-wb-fsbar">
334
+ <button id="wb-fs-up" class="ds-btn" data-i18n="wb.up">上级</button>
335
+ <span id="wb-fs-path" class="ds-wb-fs-path">~</span>
336
+ <button id="wb-fs-home" class="ds-btn" data-i18n="wb.home">根目录</button>
337
+ </div>
338
+ <div id="wb-fs-list" class="ds-wb-fs-list"></div>
339
+ <div class="ds-wb-manual">
340
+ <input id="wb-path-input" type="text" autocomplete="off" data-i18n-placeholder="wb.pathPlaceholder" placeholder="或手动输入绝对路径…">
341
+ <button id="btn-wb-bind-manual" class="ds-btn primary" data-i18n="wb.bind">绑定</button>
342
+ </div>
343
+ </div>
344
+ <div class="ds-modal-actions">
345
+ <button id="btn-wb-modal-close" class="ds-btn" data-i18n="ds.cancel">取消</button>
346
+ </div>
347
+ </div>
348
+ </div>
349
+
286
350
  <!-- 赞赏支持模态 -->
287
351
  <div id="modal-donate" class="ds-modal hidden">
288
352
  <div class="ds-modal-card">
@@ -321,14 +385,16 @@
321
385
  <script>
322
386
  window.DESKTOP_STR = {
323
387
  zh: {
324
- 'ds.repo': 'GitHub 仓库', 'ds.newSession': '+ 新会话', 'ds.sessions': '会话',
388
+ 'ds.repo': 'GitHub 仓库', 'ds.newSession': '+ 新会话', 'ds.newWorkspace': '新建工作区', 'ds.sessions': '会话',
389
+ 'ds.sortLabel': '会话排序', 'ds.sortTime': '按时间', 'ds.sortWorkspace': '按工作区', 'ds.workspace': '工作区', 'ds.workspaceUnknown': '未指定工作区',
325
390
  'ds.files': '文件传输', 'ds.settings': '设置', 'ds.stats': '统计', 'ds.menu': '导航',
326
391
  'ds.send': '发送', 'ds.composerPlaceholder': '输入消息,Enter 发送…', 'ds.presets': '预设',
327
392
  'ds.commands': '指令',
328
393
  'ds.cmdCompact': '/compact 压缩对话历史', 'ds.cmdExport': '/export 导出会话日志 ZIP',
329
394
  'ds.cmdFeedback': '/feedback 反馈当前会话', 'ds.cmdGoal': '/goal 设置/查看任务目标',
330
395
  'ds.cmdPermission': '/permission 切换权限预设', 'ds.cmdPlan': '/plan 进入/退出计划模式',
331
- 'ds.fsUp': '上级', 'ds.fsRefresh': '刷新', 'ds.fsEmpty': '目录为空',
396
+ 'ds.fsUp': '上级', 'ds.fsNewWorkspace': '新建工作区', 'ds.fsRefresh': '刷新', 'ds.fsEmpty': '目录为空',
397
+ 'ds.workspaceCreateTitle': '新建工作区', 'ds.workspaceCreateDesc': '将在当前文件目录下创建文件夹,并自动打开新会话。', 'ds.workspaceParent': '父目录', 'ds.workspaceNamePlaceholder': '例如:my-project', 'ds.workspaceCreate': '创建并打开', 'ds.cancel': '取消', 'ds.workspaceNameRequired': '请输入工作区名称', 'ds.workspaceExists': '该目录已存在', 'ds.workspaceInvalidName': '名称不能包含路径分隔符', 'ds.workspaceCreateFailed': '创建工作区失败', 'ds.workspaceCreated': '工作区已创建', 'ds.workspaceCreatedNoSession': '工作区已创建,但新会话未能打开',
332
398
  'ds.groupGeneral': '通用', 'ds.groupGeneralDesc': '工具调用、预设提示词',
333
399
  'ds.groupServers': '服务器', 'ds.groupServersDesc': '服务器地址',
334
400
  'ds.groupNotify': '通知', 'ds.groupNotifyDesc': '通知与提醒',
@@ -365,7 +431,7 @@
365
431
  'ds.approvalTitle': '工具审批', 'ds.questionNotify': '需要回答',
366
432
  'ds.approvalBody': '{tool} · {server}', 'ds.approvalReason': '原因:{reason}',
367
433
  'ds.allowed': '已允许', 'ds.rejected': '已拒绝', 'ds.ignored': '已忽略',
368
- 'ds.stale': '请求已失效',
434
+ 'ds.stale': '请求已失效', 'ds.pendingSubmitFailed': '提交失败:{msg}',
369
435
  'ds.statsTodayTokens': '今日 Token', 'ds.statsTodayCost': '今日费用', 'ds.statsPeakShare': '高峰占比',
370
436
  'ds.statsInput': '未缓存输入', 'ds.statsCacheRead': '缓存命中', 'ds.statsCacheWrite': '缓存写入', 'ds.statsOutput': '输出',
371
437
  'ds.statsPeak': '高峰', 'ds.statsOff': '空闲', 'ds.statsDays': '近 {n} 天',
@@ -416,14 +482,16 @@
416
482
  'menu.modelTitle': '模型切换', 'menu.effortTitle': '思考深度',
417
483
  },
418
484
  en: {
419
- 'ds.repo': 'GitHub repo', 'ds.newSession': '+ New session', 'ds.sessions': 'Sessions',
485
+ 'ds.repo': 'GitHub repo', 'ds.newSession': '+ New session', 'ds.newWorkspace': 'New workspace', 'ds.sessions': 'Sessions',
486
+ 'ds.sortLabel': 'Session sort', 'ds.sortTime': 'By time', 'ds.sortWorkspace': 'By workspace', 'ds.workspace': 'Workspace', 'ds.workspaceUnknown': 'No workspace',
420
487
  'ds.files': 'Files', 'ds.settings': 'Settings', 'ds.stats': 'Stats', 'ds.menu': 'Menu',
421
488
  'ds.send': 'Send', 'ds.composerPlaceholder': 'Type a message, Enter to send…', 'ds.presets': 'Presets',
422
489
  'ds.commands': 'Commands',
423
490
  'ds.cmdCompact': '/compact Compress conversation history', 'ds.cmdExport': '/export Export session log ZIP',
424
491
  'ds.cmdFeedback': '/feedback Feedback current session', 'ds.cmdGoal': '/goal Set/view task goal',
425
492
  'ds.cmdPermission': '/permission Switch permission preset', 'ds.cmdPlan': '/plan Enter/exit plan mode',
426
- 'ds.fsUp': 'Up', 'ds.fsRefresh': 'Refresh', 'ds.fsEmpty': 'Empty directory',
493
+ 'ds.fsUp': 'Up', 'ds.fsNewWorkspace': 'New workspace', 'ds.fsRefresh': 'Refresh', 'ds.fsEmpty': 'Empty directory',
494
+ 'ds.workspaceCreateTitle': 'New workspace', 'ds.workspaceCreateDesc': 'Create a folder in the current file directory and open a new session there.', 'ds.workspaceParent': 'Parent folder', 'ds.workspaceNamePlaceholder': 'For example: my-project', 'ds.workspaceCreate': 'Create & open', 'ds.cancel': 'Cancel', 'ds.workspaceNameRequired': 'Enter a workspace name', 'ds.workspaceExists': 'That folder already exists', 'ds.workspaceInvalidName': 'The name cannot contain path separators', 'ds.workspaceCreateFailed': 'Could not create workspace', 'ds.workspaceCreated': 'Workspace created', 'ds.workspaceCreatedNoSession': 'Workspace created, but the new session could not be opened',
427
495
  'ds.groupGeneral': 'General', 'ds.groupGeneralDesc': 'Tool calls, prompt presets',
428
496
  'ds.groupServers': 'Servers', 'ds.groupServersDesc': 'Server address',
429
497
  'ds.groupNotify': 'Notifications', 'ds.groupNotifyDesc': 'Notifications & reminders',
@@ -460,7 +528,7 @@
460
528
  'ds.approvalTitle': 'Tool approval', 'ds.questionNotify': 'Question',
461
529
  'ds.approvalBody': '{tool} · {server}', 'ds.approvalReason': 'Reason: {reason}',
462
530
  'ds.allowed': 'Allowed', 'ds.rejected': 'Rejected', 'ds.ignored': 'Ignored',
463
- 'ds.stale': 'Request is stale',
531
+ 'ds.stale': 'Request is stale', 'ds.pendingSubmitFailed': 'Submit failed: {msg}',
464
532
  'ds.statsTodayTokens': 'Tokens today', 'ds.statsTodayCost': 'Cost today', 'ds.statsPeakShare': 'Peak share',
465
533
  'ds.statsInput': 'Uncached input', 'ds.statsCacheRead': 'Cache read', 'ds.statsCacheWrite': 'Cache write', 'ds.statsOutput': 'Output',
466
534
  'ds.statsPeak': 'Peak', 'ds.statsOff': 'Off-peak', 'ds.statsDays': 'Last {n} days',