@rooode/dsh-plugin-preview 0.1.11 → 0.1.12

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/lib/client.js CHANGED
@@ -1043,6 +1043,142 @@
1043
1043
  // React Components: Workspace File Tree Explorer (with DnD, Create & Move)
1044
1044
  // =========================================================================
1045
1045
 
1046
+ function IconNewFile() {
1047
+ return h('svg', {
1048
+ width: 14,
1049
+ height: 14,
1050
+ viewBox: '0 0 16 16',
1051
+ fill: 'none',
1052
+ stroke: 'currentColor',
1053
+ strokeWidth: 1.3,
1054
+ strokeLinecap: 'round',
1055
+ strokeLinejoin: 'round',
1056
+ style: { display: 'block', flexShrink: 0 }
1057
+ },
1058
+ h('path', { d: 'M9 1.5H3.5A1.5 1.5 0 0 0 2 3v10a1.5 1.5 0 0 0 1.5 1.5h9a1.5 1.5 0 0 0 1.5-1.5V6L9 1.5z' }),
1059
+ h('polyline', { points: '9 1.5 9 6 13.5 6' }),
1060
+ h('line', { x1: 5.5, y1: 10, x2: 9.5, y2: 10 }),
1061
+ h('line', { x1: 7.5, y1: 8, x2: 7.5, y2: 12 })
1062
+ );
1063
+ }
1064
+
1065
+ function IconNewFolder() {
1066
+ return h('svg', {
1067
+ width: 14,
1068
+ height: 14,
1069
+ viewBox: '0 0 16 16',
1070
+ fill: 'none',
1071
+ stroke: 'currentColor',
1072
+ strokeWidth: 1.3,
1073
+ strokeLinecap: 'round',
1074
+ strokeLinejoin: 'round',
1075
+ style: { display: 'block', flexShrink: 0 }
1076
+ },
1077
+ h('path', { d: 'M1.5 3.5A1.5 1.5 0 0 1 3 2h3.2l1.4 1.5H13A1.5 1.5 0 0 1 14.5 5v7A1.5 1.5 0 0 1 13 13.5H3A1.5 1.5 0 0 1 1.5 12V3.5z' }),
1078
+ h('line', { x1: 6, y1: 8.5, x2: 10, y2: 8.5 }),
1079
+ h('line', { x1: 8, y1: 6.5, x2: 8, y2: 10.5 })
1080
+ );
1081
+ }
1082
+
1083
+ function IconRefresh() {
1084
+ return h('svg', {
1085
+ width: 13,
1086
+ height: 13,
1087
+ viewBox: '0 0 16 16',
1088
+ fill: 'none',
1089
+ stroke: 'currentColor',
1090
+ strokeWidth: 1.4,
1091
+ strokeLinecap: 'round',
1092
+ strokeLinejoin: 'round',
1093
+ style: { display: 'block', flexShrink: 0 }
1094
+ },
1095
+ h('path', { d: 'M13.5 2.5v3.5h-3.5' }),
1096
+ h('path', { d: 'M2.5 13.5v-3.5h3.5' }),
1097
+ h('path', { d: 'M3.5 6a5.5 5.5 0 0 1 8.8-1.5l1.2 1.5' }),
1098
+ h('path', { d: 'M12.5 10a5.5 5.5 0 0 1-8.8 1.5l-1.2-1.5' })
1099
+ );
1100
+ }
1101
+
1102
+ function IconExpandAll() {
1103
+ return h('svg', {
1104
+ width: 13,
1105
+ height: 13,
1106
+ viewBox: '0 0 16 16',
1107
+ fill: 'none',
1108
+ stroke: 'currentColor',
1109
+ strokeWidth: 1.4,
1110
+ strokeLinecap: 'round',
1111
+ strokeLinejoin: 'round',
1112
+ style: { display: 'block', flexShrink: 0 }
1113
+ },
1114
+ h('polyline', { points: '3.5 5.5 8 2 12.5 5.5' }),
1115
+ h('line', { x1: 2, y1: 8, x2: 14, y2: 8 }),
1116
+ h('polyline', { points: '3.5 10.5 8 14 12.5 10.5' })
1117
+ );
1118
+ }
1119
+
1120
+ function IconCollapseAll() {
1121
+ return h('svg', {
1122
+ width: 13,
1123
+ height: 13,
1124
+ viewBox: '0 0 16 16',
1125
+ fill: 'none',
1126
+ stroke: 'currentColor',
1127
+ strokeWidth: 1.4,
1128
+ strokeLinecap: 'round',
1129
+ strokeLinejoin: 'round',
1130
+ style: { display: 'block', flexShrink: 0 }
1131
+ },
1132
+ h('polyline', { points: '3.5 3 8 6.5 12.5 3' }),
1133
+ h('line', { x1: 2, y1: 8, x2: 14, y2: 8 }),
1134
+ h('polyline', { points: '3.5 13 8 9.5 12.5 13' })
1135
+ );
1136
+ }
1137
+
1138
+ function IconChevronRight() {
1139
+ return h('svg', {
1140
+ width: 9,
1141
+ height: 9,
1142
+ viewBox: '0 0 16 16',
1143
+ fill: 'none',
1144
+ stroke: 'currentColor',
1145
+ strokeWidth: 2.2,
1146
+ strokeLinecap: 'round',
1147
+ strokeLinejoin: 'round',
1148
+ style: { display: 'block' }
1149
+ }, h('polyline', { points: '5 3 10 8 5 13' }));
1150
+ }
1151
+
1152
+ function IconChevronDown() {
1153
+ return h('svg', {
1154
+ width: 9,
1155
+ height: 9,
1156
+ viewBox: '0 0 16 16',
1157
+ fill: 'none',
1158
+ stroke: 'currentColor',
1159
+ strokeWidth: 2.2,
1160
+ strokeLinecap: 'round',
1161
+ strokeLinejoin: 'round',
1162
+ style: { display: 'block' }
1163
+ }, h('polyline', { points: '3 5 8 10 13 5' }));
1164
+ }
1165
+
1166
+ function IconClose() {
1167
+ return h('svg', {
1168
+ width: 12,
1169
+ height: 12,
1170
+ viewBox: '0 0 16 16',
1171
+ fill: 'none',
1172
+ stroke: 'currentColor',
1173
+ strokeWidth: 1.6,
1174
+ strokeLinecap: 'round',
1175
+ style: { display: 'block', flexShrink: 0 }
1176
+ },
1177
+ h('line', { x1: 3, y1: 3, x2: 13, y2: 13 }),
1178
+ h('line', { x1: 13, y1: 3, x2: 3, y2: 13 })
1179
+ );
1180
+ }
1181
+
1046
1182
  function isValidDropTarget(draggedItem, targetNode) {
1047
1183
  if (!draggedItem || !targetNode) return false;
1048
1184
  if (!targetNode.isDir) return false;
@@ -1373,7 +1509,7 @@
1373
1509
  isDir ? h('span', {
1374
1510
  className: `dsh-tree-chevron ${isExpanded ? 'expanded' : ''}`,
1375
1511
  onClick: (e) => { e.stopPropagation(); onToggleExpand(node.path); },
1376
- }, isExpanded ? '▼' : '▶') : h('span', { className: 'dsh-tree-chevron-placeholder' }),
1512
+ }, isExpanded ? h(IconChevronDown) : h(IconChevronRight)) : h('span', { className: 'dsh-tree-chevron-placeholder' }),
1377
1513
 
1378
1514
  // File / Directory Icon
1379
1515
  h('span', {
@@ -1554,6 +1690,17 @@
1554
1690
  }
1555
1691
  }, [searchQuery, treeData]);
1556
1692
 
1693
+ // Listen to external workspace switch events (e.g. from Git plugin)
1694
+ useEffect(() => {
1695
+ const handleWsSwitch = (e) => {
1696
+ if (e.detail?.path && e.detail.path !== globalManualWorkspace) {
1697
+ setManualWorkspace(e.detail.path);
1698
+ }
1699
+ };
1700
+ window.addEventListener('dsh:workspace:switch', handleWsSwitch);
1701
+ return () => window.removeEventListener('dsh:workspace:switch', handleWsSwitch);
1702
+ }, []);
1703
+
1557
1704
  const availableWorkspaces = useMemo(() => {
1558
1705
  return getAllAvailableWorkspaces();
1559
1706
  }, [isSelectorOpen, globalManualWorkspace]);
@@ -1562,6 +1709,9 @@
1562
1709
  setManualWorkspace(wsPath);
1563
1710
  setIsSelectorOpen(false);
1564
1711
  showToast(`已切换工作区: ${getFileName(wsPath)}`, 'success');
1712
+ if (typeof window !== 'undefined') {
1713
+ window.dispatchEvent(new CustomEvent('dsh:workspace:switch', { detail: { path: wsPath } }));
1714
+ }
1565
1715
  };
1566
1716
 
1567
1717
  const handleCustomSubmit = async (e) => {
@@ -1581,6 +1731,9 @@
1581
1731
  setCustomPathInput('');
1582
1732
  setIsSelectorOpen(false);
1583
1733
  showToast(`已切换工作空间: ${json.name}`, 'success');
1734
+ if (typeof window !== 'undefined') {
1735
+ window.dispatchEvent(new CustomEvent('dsh:workspace:switch', { detail: { path: json.path } }));
1736
+ }
1584
1737
  } else {
1585
1738
  showToast(json?.error?.message || '指定目录不存在或不是文件夹', 'error');
1586
1739
  }
@@ -1778,39 +1931,39 @@
1778
1931
  h('button', {
1779
1932
  type: 'button',
1780
1933
  className: 'dsh-tree-action-btn',
1781
- onClick: () => loadTree(true),
1782
- title: '刷新文件树',
1783
- }, '🔄'),
1934
+ onClick: () => handleStartCreate(rootPath, 'file'),
1935
+ title: '新建文件 (在根目录)',
1936
+ }, h(IconNewFile)),
1784
1937
  h('button', {
1785
1938
  type: 'button',
1786
1939
  className: 'dsh-tree-action-btn',
1787
- onClick: () => handleStartCreate(rootPath, 'file'),
1788
- title: '在根目录新建文件',
1789
- }, '📄➕'),
1940
+ onClick: () => handleStartCreate(rootPath, 'dir'),
1941
+ title: '新建文件夹 (在根目录)',
1942
+ }, h(IconNewFolder)),
1790
1943
  h('button', {
1791
1944
  type: 'button',
1792
1945
  className: 'dsh-tree-action-btn',
1793
- onClick: () => handleStartCreate(rootPath, 'dir'),
1794
- title: '在根目录新建文件夹',
1795
- }, '📁➕'),
1946
+ onClick: () => loadTree(true),
1947
+ title: '刷新文件树',
1948
+ }, h(IconRefresh)),
1796
1949
  h('button', {
1797
1950
  type: 'button',
1798
1951
  className: 'dsh-tree-action-btn',
1799
1952
  onClick: handleExpandAll,
1800
1953
  title: '全部展开',
1801
- }, '📂'),
1954
+ }, h(IconExpandAll)),
1802
1955
  h('button', {
1803
1956
  type: 'button',
1804
1957
  className: 'dsh-tree-action-btn',
1805
1958
  onClick: handleCollapseAll,
1806
1959
  title: '全部折叠',
1807
- }, '📁'),
1960
+ }, h(IconCollapseAll)),
1808
1961
  onCloseSidebar ? h('button', {
1809
1962
  type: 'button',
1810
1963
  className: 'dsh-tree-action-btn',
1811
1964
  onClick: onCloseSidebar,
1812
1965
  title: '收起目录树 (快捷键 Ctrl/Cmd+B)',
1813
- }, '✕') : null
1966
+ }, h(IconClose)) : null
1814
1967
  )
1815
1968
  ),
1816
1969
 
@@ -5226,6 +5379,7 @@
5226
5379
  align-items: center;
5227
5380
  gap: 2px;
5228
5381
  flex-shrink: 0;
5382
+ white-space: nowrap;
5229
5383
  }
5230
5384
 
5231
5385
  .dsh-tree-action-btn {
@@ -5239,16 +5393,25 @@
5239
5393
  display: inline-flex;
5240
5394
  align-items: center;
5241
5395
  justify-content: center;
5242
- font-size: 11px;
5243
5396
  padding: 0;
5244
- transition: all 0.1s;
5397
+ flex-shrink: 0;
5398
+ white-space: nowrap;
5399
+ transition: background 0.12s ease, color 0.12s ease;
5400
+ }
5401
+ body[data-ds-dark-theme] .dsh-tree-action-btn {
5402
+ color: #94a3b8;
5403
+ }
5404
+ .dsh-tree-action-btn svg {
5405
+ display: block;
5406
+ flex-shrink: 0;
5407
+ pointer-events: none;
5245
5408
  }
5246
5409
  .dsh-tree-action-btn:hover {
5247
- background: rgba(0, 0, 0, 0.06);
5410
+ background: var(--dsw-alias-bg-hover, rgba(0, 0, 0, 0.07));
5248
5411
  color: var(--dsw-alias-label-primary, #0f172a);
5249
5412
  }
5250
5413
  body[data-ds-dark-theme] .dsh-tree-action-btn:hover {
5251
- background: rgba(255, 255, 255, 0.08);
5414
+ background: rgba(255, 255, 255, 0.1);
5252
5415
  color: #ffffff;
5253
5416
  }
5254
5417
 
package/lib/index.js CHANGED
@@ -29,7 +29,7 @@ export class PreviewService extends Service {
29
29
  handler: this.handleHttpRequest.bind(this),
30
30
  });
31
31
  });
32
- console.log('[PreviewService] Registered /api/preview route on webServer (v0.1.11)');
32
+ console.log('[PreviewService] Registered /api/preview route on webServer (v0.1.12)');
33
33
  } else {
34
34
  console.warn('[PreviewService] webServer not available yet in ctx');
35
35
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rooode/dsh-plugin-preview",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "description": "DeepSeek Harness Markdown 文档与工作空间文件浏览器右侧预览插件 (支持工作区文件树、文件夹创建与文件移动、JSON 交互结构树/格式化、Java/C++/Python/JS/TS/YAML/Go/Rust 多语言语法高亮与符号大纲、自动换行与多标签 FileTabs)",
5
5
  "type": "module",
6
6
  "main": "lib/index.js",