dsh-remote-plugin 0.6.4 → 0.6.6

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.
@@ -15,12 +15,29 @@ 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); }
@@ -146,7 +163,7 @@ a.ds-btn { text-decoration: none; }
146
163
  .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
164
  .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
165
  .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; }
166
+ .ds-composer-left { display: flex; align-items: center; gap: 8px; min-width: 0; flex-wrap: wrap; }
150
167
  .ds-composer-right { display: flex; align-items: center; flex: none; }
151
168
  .ds-composer .ds-btn { min-height: 34px; box-sizing: border-box; }
152
169
  .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 +286,11 @@ a.ds-btn { text-decoration: none; }
269
286
  .ds-modal-card { width: min(520px, 100%); background: var(--dsr-panel); border: 1px solid var(--dsr-line); border-radius: 14px; padding: 16px; }
270
287
  .ds-modal-title { font-weight: 700; margin-bottom: 10px; }
271
288
  .ds-modal-body { display: flex; flex-direction: column; gap: 10px; max-height: 60vh; overflow-y: auto; }
289
+ .ds-workspace-create-desc { margin: 0; color: var(--dsr-muted); line-height: 1.55; }
290
+ .ds-workspace-create-location { display: flex; align-items: center; gap: 8px; min-width: 0; color: var(--dsr-muted); font-size: 12px; }
291
+ .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; }
292
+ .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; }
293
+ .ds-workspace-name:focus { border-color: var(--dsr-accent-line); }
272
294
  .ds-modal-actions { display: flex; gap: 8px; justify-content: flex-end; margin-top: 12px; }
273
295
  .ds-q-item { border: 1px solid var(--dsr-line); border-radius: 10px; padding: 9px 11px; }
274
296
  .ds-q-text { font-size: 13.5px; margin-bottom: 6px; }
@@ -332,3 +354,12 @@ a.ds-btn { text-decoration: none; }
332
354
  .ds-toast-stack { left: 10px; right: 10px; width: auto; }
333
355
  .mobile-only { display: block; }
334
356
  }
357
+
358
+ @media (max-width: 520px) {
359
+ .ds-topbar { gap: 6px; padding: 0 8px; }
360
+ .ds-top-right { gap: 5px; }
361
+ .ds-composer-actions { align-items: stretch; flex-wrap: wrap; gap: 6px; }
362
+ .ds-composer-left { flex: 1 1 100%; gap: 5px; }
363
+ .ds-composer-left .ds-btn { flex: 1 1 0; min-width: 0; padding-left: 7px; padding-right: 7px; overflow: hidden; text-overflow: ellipsis; }
364
+ .ds-composer-right { margin-left: auto; }
365
+ }
@@ -20,7 +20,14 @@
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">
26
33
  <button class="ds-nav-item" data-view="view-files"><span class="ds-nav-ico">⇅</span><span data-i18n="ds.files">文件传输</span></button>
@@ -116,6 +123,7 @@
116
123
  <div class="ds-fs-bar">
117
124
  <button id="fs-up" class="ds-btn" data-i18n="ds.fsUp">上级</button>
118
125
  <span id="fs-path" class="ds-fs-path">/</span>
126
+ <button id="fs-new-workspace" class="ds-btn" data-i18n="ds.fsNewWorkspace">新建工作区</button>
119
127
  <button id="fs-refresh" class="ds-btn" data-i18n="ds.fsRefresh">刷新</button>
120
128
  </div>
121
129
  <div id="fs-list" class="ds-fs-list"></div>
@@ -266,6 +274,22 @@
266
274
  </div>
267
275
  </div>
268
276
 
277
+ <!-- 新建工作区模态 -->
278
+ <div id="modal-workspace" class="ds-modal hidden">
279
+ <div class="ds-modal-card">
280
+ <div class="ds-modal-title" data-i18n="ds.workspaceCreateTitle">新建工作区</div>
281
+ <div class="ds-modal-body">
282
+ <p class="ds-workspace-create-desc" data-i18n="ds.workspaceCreateDesc">将在当前文件目录下创建文件夹,并自动打开新会话。</p>
283
+ <div class="ds-workspace-create-location"><span data-i18n="ds.workspaceParent">父目录</span><code id="workspace-parent-path">~</code></div>
284
+ <input id="workspace-name" class="ds-workspace-name" maxlength="120" autocomplete="off" data-i18n-placeholder="ds.workspaceNamePlaceholder" placeholder="例如:my-project">
285
+ </div>
286
+ <div class="ds-modal-actions">
287
+ <button id="workspace-cancel" class="ds-btn" data-i18n="ds.cancel">取消</button>
288
+ <button id="workspace-create" class="ds-btn primary" data-i18n="ds.workspaceCreate">创建并打开</button>
289
+ </div>
290
+ </div>
291
+ </div>
292
+
269
293
  <!-- 预设提示词管理模态 -->
270
294
  <div id="modal-presets" class="ds-modal hidden">
271
295
  <div class="ds-modal-card">
@@ -321,14 +345,16 @@
321
345
  <script>
322
346
  window.DESKTOP_STR = {
323
347
  zh: {
324
- 'ds.repo': 'GitHub 仓库', 'ds.newSession': '+ 新会话', 'ds.sessions': '会话',
348
+ 'ds.repo': 'GitHub 仓库', 'ds.newSession': '+ 新会话', 'ds.newWorkspace': '新建工作区', 'ds.sessions': '会话',
349
+ 'ds.sortLabel': '会话排序', 'ds.sortTime': '按时间', 'ds.sortWorkspace': '按工作区', 'ds.workspace': '工作区', 'ds.workspaceUnknown': '未指定工作区',
325
350
  'ds.files': '文件传输', 'ds.settings': '设置', 'ds.stats': '统计', 'ds.menu': '导航',
326
351
  'ds.send': '发送', 'ds.composerPlaceholder': '输入消息,Enter 发送…', 'ds.presets': '预设',
327
352
  'ds.commands': '指令',
328
353
  'ds.cmdCompact': '/compact 压缩对话历史', 'ds.cmdExport': '/export 导出会话日志 ZIP',
329
354
  'ds.cmdFeedback': '/feedback 反馈当前会话', 'ds.cmdGoal': '/goal 设置/查看任务目标',
330
355
  'ds.cmdPermission': '/permission 切换权限预设', 'ds.cmdPlan': '/plan 进入/退出计划模式',
331
- 'ds.fsUp': '上级', 'ds.fsRefresh': '刷新', 'ds.fsEmpty': '目录为空',
356
+ 'ds.fsUp': '上级', 'ds.fsNewWorkspace': '新建工作区', 'ds.fsRefresh': '刷新', 'ds.fsEmpty': '目录为空',
357
+ '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
358
  'ds.groupGeneral': '通用', 'ds.groupGeneralDesc': '工具调用、预设提示词',
333
359
  'ds.groupServers': '服务器', 'ds.groupServersDesc': '服务器地址',
334
360
  'ds.groupNotify': '通知', 'ds.groupNotifyDesc': '通知与提醒',
@@ -354,6 +380,7 @@
354
380
  'ds.feedbackRateLimited': '提交太频繁,请 5 分钟后再试', 'ds.feedbackSubmitFailed': '提交失败:{msg}', 'ds.feedbackNetworkError': '网络错误',
355
381
  'ds.questionTitle': '回答问题', 'ds.ignore': '忽略', 'ds.submit': '提交',
356
382
  'ds.connOn': '已连接', 'ds.connOff': '未连接', 'ds.connIng': '连接中',
383
+ 'ds.connReconnecting': '重连中…', 'ds.connReconnectIn': '重连中 {n}s', 'ds.connOffline': '离线', 'ds.connFailed': '连接失败',
357
384
  'ds.connPollTitle': '当前网络不支持实时推送,已降级为轮询(延迟数秒)',
358
385
  'ds.currentServer': '{group} · {url}', 'ds.origin': '当前页面',
359
386
  'ds.toastSent': '已发送', 'ds.toastCopied': '令牌已复制', 'ds.toastAuth': '令牌无效',
@@ -364,7 +391,7 @@
364
391
  'ds.approvalTitle': '工具审批', 'ds.questionNotify': '需要回答',
365
392
  'ds.approvalBody': '{tool} · {server}', 'ds.approvalReason': '原因:{reason}',
366
393
  'ds.allowed': '已允许', 'ds.rejected': '已拒绝', 'ds.ignored': '已忽略',
367
- 'ds.stale': '请求已失效',
394
+ 'ds.stale': '请求已失效', 'ds.pendingSubmitFailed': '提交失败:{msg}',
368
395
  'ds.statsTodayTokens': '今日 Token', 'ds.statsTodayCost': '今日费用', 'ds.statsPeakShare': '高峰占比',
369
396
  'ds.statsInput': '未缓存输入', 'ds.statsCacheRead': '缓存命中', 'ds.statsCacheWrite': '缓存写入', 'ds.statsOutput': '输出',
370
397
  'ds.statsPeak': '高峰', 'ds.statsOff': '空闲', 'ds.statsDays': '近 {n} 天',
@@ -415,14 +442,16 @@
415
442
  'menu.modelTitle': '模型切换', 'menu.effortTitle': '思考深度',
416
443
  },
417
444
  en: {
418
- 'ds.repo': 'GitHub repo', 'ds.newSession': '+ New session', 'ds.sessions': 'Sessions',
445
+ 'ds.repo': 'GitHub repo', 'ds.newSession': '+ New session', 'ds.newWorkspace': 'New workspace', 'ds.sessions': 'Sessions',
446
+ 'ds.sortLabel': 'Session sort', 'ds.sortTime': 'By time', 'ds.sortWorkspace': 'By workspace', 'ds.workspace': 'Workspace', 'ds.workspaceUnknown': 'No workspace',
419
447
  'ds.files': 'Files', 'ds.settings': 'Settings', 'ds.stats': 'Stats', 'ds.menu': 'Menu',
420
448
  'ds.send': 'Send', 'ds.composerPlaceholder': 'Type a message, Enter to send…', 'ds.presets': 'Presets',
421
449
  'ds.commands': 'Commands',
422
450
  'ds.cmdCompact': '/compact Compress conversation history', 'ds.cmdExport': '/export Export session log ZIP',
423
451
  'ds.cmdFeedback': '/feedback Feedback current session', 'ds.cmdGoal': '/goal Set/view task goal',
424
452
  'ds.cmdPermission': '/permission Switch permission preset', 'ds.cmdPlan': '/plan Enter/exit plan mode',
425
- 'ds.fsUp': 'Up', 'ds.fsRefresh': 'Refresh', 'ds.fsEmpty': 'Empty directory',
453
+ 'ds.fsUp': 'Up', 'ds.fsNewWorkspace': 'New workspace', 'ds.fsRefresh': 'Refresh', 'ds.fsEmpty': 'Empty directory',
454
+ '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',
426
455
  'ds.groupGeneral': 'General', 'ds.groupGeneralDesc': 'Tool calls, prompt presets',
427
456
  'ds.groupServers': 'Servers', 'ds.groupServersDesc': 'Server address',
428
457
  'ds.groupNotify': 'Notifications', 'ds.groupNotifyDesc': 'Notifications & reminders',
@@ -448,6 +477,7 @@
448
477
  'ds.feedbackRateLimited': 'Too frequent, try again in 5 minutes', 'ds.feedbackSubmitFailed': 'Submit failed: {msg}', 'ds.feedbackNetworkError': 'Network error',
449
478
  'ds.questionTitle': 'Answer question', 'ds.ignore': 'Ignore', 'ds.submit': 'Submit',
450
479
  'ds.connOn': 'Connected', 'ds.connOff': 'Offline', 'ds.connIng': 'Connecting',
480
+ 'ds.connReconnecting': 'Reconnecting…', 'ds.connReconnectIn': 'Reconnecting {n}s', 'ds.connOffline': 'Offline', 'ds.connFailed': 'Connection failed',
451
481
  'ds.connPollTitle': 'Realtime push is unavailable on this network; degraded to polling (a few seconds delay)',
452
482
  'ds.currentServer': '{group} · {url}', 'ds.origin': 'this page',
453
483
  'ds.toastSent': 'Sent', 'ds.toastCopied': 'Token copied', 'ds.toastAuth': 'Invalid token',
@@ -458,7 +488,7 @@
458
488
  'ds.approvalTitle': 'Tool approval', 'ds.questionNotify': 'Question',
459
489
  'ds.approvalBody': '{tool} · {server}', 'ds.approvalReason': 'Reason: {reason}',
460
490
  'ds.allowed': 'Allowed', 'ds.rejected': 'Rejected', 'ds.ignored': 'Ignored',
461
- 'ds.stale': 'Request is stale',
491
+ 'ds.stale': 'Request is stale', 'ds.pendingSubmitFailed': 'Submit failed: {msg}',
462
492
  'ds.statsTodayTokens': 'Tokens today', 'ds.statsTodayCost': 'Cost today', 'ds.statsPeakShare': 'Peak share',
463
493
  'ds.statsInput': 'Uncached input', 'ds.statsCacheRead': 'Cache read', 'ds.statsCacheWrite': 'Cache write', 'ds.statsOutput': 'Output',
464
494
  'ds.statsPeak': 'Peak', 'ds.statsOff': 'Off-peak', 'ds.statsDays': 'Last {n} days',