@philomelcc/dsh-workbench 0.1.7 → 0.1.8

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 (2) hide show
  1. package/client.js +52 -13
  2. package/package.json +1 -1
package/client.js CHANGED
@@ -470,6 +470,11 @@ window.__ModuleLoader__.load({
470
470
  '--dsw-specific-input-major': '#f2ece0',
471
471
  '--dsw-specific-tip': '#f7f2e7',
472
472
  '--dsw-specific-menu': '#fcf9f3',
473
+ // Scrollbars read their own alias pair and default to neutral grey.
474
+ '--dsw-alias-scrollbar-bg-l1': '#d8cfba',
475
+ '--dsw-alias-scrollbar-bg-l2': '#d8cfba',
476
+ '--dsw-alias-scrollbar-hover-l1': '#c6bba2',
477
+ '--dsw-alias-scrollbar-hover-l2': '#c6bba2',
473
478
  // The neutral greys are blue-tinted. Buttons ("load earlier"), inputs,
474
479
  // chips and cards read their pale surfaces from this ramp, so warm it up
475
480
  // too; deep steps stay untouched because they are text/borders.
@@ -555,12 +560,15 @@ window.__ModuleLoader__.load({
555
560
  return;
556
561
  }
557
562
  const rect = settings.getBoundingClientRect();
558
- if (rect.width > 0) box.style.right = (rect.width + 16 + 12) + 'px';
559
- // Same box as the account block, so `align-items: center` lands on
560
- // the account's optical center instead of a guessed offset.
561
- if (rect.height > 0) {
563
+ if (rect.width > 0) {
564
+ box.style.right = (rect.width + 16 + 12) + 'px';
562
565
  box.style.top = rect.top + 'px';
563
566
  box.style.height = rect.height + 'px';
567
+ } else {
568
+ // Narrow screens hide the account block; pin the swatches right.
569
+ box.style.right = '12px';
570
+ box.style.top = '2px';
571
+ box.style.height = '40px';
564
572
  }
565
573
  };
566
574
  place();
@@ -777,12 +785,32 @@ window.__ModuleLoader__.load({
777
785
  if (wsRoot) {
778
786
  Array.from(wsRoot.children).forEach((g, i) => { if (i > 0) g.style.display = 'none'; });
779
787
  }
788
+ // Narrow screens keep the official sidebar toggle: the workbench has no
789
+ // session list of its own, so hiding it strands phone users.
790
+ const narrowScreen = typeof window !== 'undefined' && window.innerWidth < 768;
780
791
  document.querySelectorAll('button[aria-label]').forEach((b) => {
781
792
  const label = b.getAttribute('aria-label') || '';
782
- if (label.includes('侧栏') || label.includes('侧边栏') || label.includes('折叠') || label.includes('collapse') || label.includes('toggle')) {
793
+ if (!narrowScreen && (label.includes('侧栏') || label.includes('侧边栏') || label.includes('折叠') || label.includes('collapse') || label.includes('toggle'))) {
783
794
  b.style.display = 'none';
784
795
  }
785
796
  });
797
+ if (narrowScreen) {
798
+ // The official toggle lives inside the translated sidebar container,
799
+ // so a fixed copy would ride along with it. Own button in <body>,
800
+ // clicks delegated to the official one.
801
+ const original = Array.from(document.querySelectorAll('button[aria-label]'))
802
+ .find((b) => b.getAttribute('aria-label') === '打开侧边栏');
803
+ if (original) {
804
+ const toggle = document.createElement('button');
805
+ toggle.type = 'button';
806
+ toggle.className = 'wb-mobile-sidebar-toggle';
807
+ toggle.setAttribute('aria-label', '显示会话列表');
808
+ toggle.textContent = '☰';
809
+ toggle.addEventListener('click', () => original.click());
810
+ document.body.appendChild(toggle);
811
+ cleanup.push(() => toggle.remove());
812
+ }
813
+ }
786
814
  const settings = document.querySelector('[class*="settingsArea"]');
787
815
  if (settings) {
788
816
  settings.style.position = 'fixed';
@@ -858,8 +886,8 @@ window.__ModuleLoader__.load({
858
886
 
859
887
  return h('div', { ref: rootRef, style: { position: 'fixed', top: 0, left: 0, right: 0, height: TOPBAR_HEIGHT, zIndex: 100, pointerEvents: 'auto', display: 'flex', flexDirection: 'column', background: 'var(--dsw-alias-bg-base)', borderBottom: '1px solid var(--dsw-alias-border-l1)' } },
860
888
  h('div', { style: { height: 56, display: 'flex', alignItems: 'center', gap: 10, padding: '0 14px' } },
861
- h('div', { style: { width: 214, flex: '0 0 auto' } }),
862
- h('div', { style: { display: 'flex', gap: 2, flex: 1, overflow: 'hidden' } },
889
+ h('div', { className: 'wb-topbar-brand', style: { width: 214, flex: '0 0 auto' } }),
890
+ h('div', { className: 'wb-topbar-icons', style: { display: 'flex', gap: 2, flex: 1, overflow: 'hidden' } },
863
891
  iconBtn('workbench', '工作台', IconGrid),
864
892
  iconBtn('plugins', '插件', IconPlugins),
865
893
  iconBtn('schedules', '自动化任务', IconClock),
@@ -1184,6 +1212,9 @@ window.__ModuleLoader__.load({
1184
1212
  z-index: 1;
1185
1213
  filter: drop-shadow(0 0 2px rgba(170, 200, 255, 0.65));
1186
1214
  }
1215
+ body[data-wb-paper="1"] .dsh-glow-canvas {
1216
+ filter: drop-shadow(0 0 2px rgba(198, 156, 96, 0.6));
1217
+ }
1187
1218
  /* 隐藏运行中会话左侧的转圈:不依赖 JS 加的 class,React 重建行时也能兜底 */
1188
1219
  div[data-row-key^="session:"]:has(svg[data-state="ongoing"]) svg[data-state="ongoing"],
1189
1220
  .dsh-glow-on svg[data-state="ongoing"],
@@ -1378,12 +1409,18 @@ body[data-wb-paper="1"] [class*="_hoverPath"] {
1378
1409
  var breath = 0.5 + 0.5 * Math.sin((now / 2800) * Math.PI * 2);
1379
1410
  var dim = entry.lights === 1 ? 0.35 : 1;
1380
1411
  var edgeAlpha = (0.12 + breath * 0.33) * dim;
1412
+ // Paper turns the blue streak into a bronze one; blue reads as ink
1413
+ // smear on a warm sheet.
1414
+ var paperNow = false;
1415
+ try { paperNow = document.body.hasAttribute("data-wb-paper"); } catch (_error) { paperNow = false; }
1416
+ var glowBase = paperNow ? [138, 106, 69] : [99, 149, 255];
1417
+ var glowHot = paperNow ? [198, 156, 96] : [205, 180, 255];
1381
1418
 
1382
1419
  context.save();
1383
1420
  context.lineWidth = 1;
1384
- context.strokeStyle = "rgba(99, 149, 255, " + edgeAlpha.toFixed(3) + ")";
1421
+ context.strokeStyle = "rgba(" + glowBase[0] + ", " + glowBase[1] + ", " + glowBase[2] + ", " + edgeAlpha.toFixed(3) + ")";
1385
1422
  context.shadowBlur = (4 + breath * 10) * dim;
1386
- context.shadowColor = "rgba(99, 149, 255, " + ((0.2 + breath * 0.35) * dim).toFixed(3) + ")";
1423
+ context.shadowColor = "rgba(" + glowBase[0] + ", " + glowBase[1] + ", " + glowBase[2] + ", " + ((0.2 + breath * 0.35) * dim).toFixed(3) + ")";
1387
1424
  context.beginPath();
1388
1425
  if (typeof context.roundRect === "function") {
1389
1426
  context.roundRect(0.5, 0.5, width - 1, height - 1, r);
@@ -1400,9 +1437,9 @@ body[data-wb-paper="1"] [class*="_hoverPath"] {
1400
1437
  if (weight < 0.02) continue;
1401
1438
  var p0 = pointOnRect(width, height, phase);
1402
1439
  var p1 = pointOnRect(width, height, (i + 1) / count);
1403
- var rChannel = Math.round(99 + (205 - 99) * weight);
1404
- var gChannel = Math.round(149 + (180 - 149) * weight);
1405
- var bChannel = 255;
1440
+ var rChannel = Math.round(glowBase[0] + (glowHot[0] - glowBase[0]) * weight);
1441
+ var gChannel = Math.round(glowBase[1] + (glowHot[1] - glowBase[1]) * weight);
1442
+ var bChannel = Math.round(glowBase[2] + (glowHot[2] - glowBase[2]) * weight);
1406
1443
  // lights === 1 表示「只有后台任务」,整体压暗。
1407
1444
  var alpha = (0.05 + 0.95 * weight) * (entry.lights === 1 ? 0.35 : 1);
1408
1445
  context.strokeStyle =
@@ -1475,7 +1512,9 @@ body[data-wb-paper="1"] [class*="_hoverPath"] {
1475
1512
  + '\n.wb-session-row { display: flex; align-items: center; gap: 6px; width: 100%; padding: 5px 8px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary); cursor: pointer; text-align: left; font-size: 12px; }'
1476
1513
  + '\n.wb-session-row:hover { background: var(--dsw-alias-bg-layer-2); }'
1477
1514
  + '\n.wb-session-row .wb-session-more { opacity: 0; transition: opacity .12s; }'
1478
- + '\n.wb-balance-tip { position: absolute; top: calc(100% + 6px); right: 0; z-index: 500; padding: 8px 10px; border-radius: 8px; background: #23262c; border: 1px solid #2f333b; color: var(--dsw-alias-label-primary); font-size: 11px; line-height: 1.7; white-space: nowrap; max-width: 240px; box-sizing: border-box; box-shadow: 0 6px 20px rgba(0,0,0,.28); pointer-events: none; }'
1515
+ + '\n.wb-balance-tip { position: absolute; top: calc(100% + 6px); right: 0; z-index: 500; padding: 8px 10px; border-radius: 8px; background: var(--dsw-alias-bg-overlay, #23262c); border: 1px solid var(--dsw-alias-border-l2, #2f333b); color: var(--dsw-alias-label-primary); font-size: 11px; line-height: 1.7; white-space: nowrap; max-width: 240px; box-sizing: border-box; box-shadow: 0 6px 20px rgba(0,0,0,.28); pointer-events: none; }'
1516
+ + '\n.wb-mobile-sidebar-toggle { position: fixed; left: 10px; top: 10px; z-index: 5000; width: 30px; height: 30px; border-radius: 8px; border: 1px solid var(--dsw-alias-border-l2); background: var(--dsw-alias-bg-layer-1); color: var(--dsw-alias-label-primary); font-size: 15px; line-height: 1; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; padding: 0; box-shadow: 0 1px 4px rgba(0,0,0,.12); }'
1517
+ + '\n@media (max-width: 767px) { .wb-topbar-brand, [class*="settingsArea"] { display: none !important; } .wb-topbar-icons { margin-left: 42px; } [class*="sidebarCol"] [class*="brand"] { display: none !important; } [class*="sidebarCol"] { padding-top: 44px !important; } [aria-label="收起侧边栏"] { display: none !important; } }'
1479
1518
  + '\n.wb-balance:hover { border-color: #4ade80 !important; background: rgba(74,222,128,.12) !important; }'
1480
1519
  + '\n.wb-nav-item { position: relative; }'
1481
1520
  + '\n.wb-nav-label { max-width: 0; opacity: 0; overflow: hidden; white-space: nowrap; font-size: 12px; transition: max-width .18s ease, opacity .18s ease; }'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@philomelcc/dsh-workbench",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "type": "module",
5
5
  "description": "Workbench shell for DeepSeek Harness: a view/page module API, shared UI primitives and a top-bar switcher.",
6
6
  "license": "MIT",