@michengai/dsh-codex-ui 0.2.76 → 0.2.78

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/dist/client.js CHANGED
@@ -590,10 +590,59 @@ window.__ModuleLoader__.load({
590
590
  //#region src/client/pinned-workspaces.ts
591
591
  /** 浏览器本地持久化键;置顶只影响本插件中的工作区分区。 */
592
592
  const PINNED_WORKSPACES_STORAGE_KEY = "dsh-codex-ui.pinned-workspace-ids";
593
+ const WORKSPACE_PREFERENCES_ENDPOINT = "/api/michengai/codex-ui/preferences";
593
594
  /** 清理无效或重复的工作区标识。 */
594
595
  function normalizePinnedWorkspaceIds(ids) {
595
596
  return [...new Set(ids.filter((id) => id.trim() !== ""))];
596
597
  }
598
+ /** 仅在宿主完整基线就绪后清理已经不存在的工作区,避免加载中的临时列表抹掉持久化置顶。 */
599
+ function prunePinnedWorkspaceIds(ids, validIds) {
600
+ const valid = new Set(validIds);
601
+ const next = ids.filter((id) => valid.has(id));
602
+ return next.length === ids.length ? [...ids] : next;
603
+ }
604
+ /** Host 数据优先;首次升级没有 Host 文件时迁移旧 origin 的 localStorage;读取期间的用户操作永远优先。 */
605
+ function resolvePinnedWorkspaceHydration(localIds, host, dirtyIds) {
606
+ if (dirtyIds !== void 0) return {
607
+ ids: normalizePinnedWorkspaceIds(dirtyIds),
608
+ writeHost: true
609
+ };
610
+ if (host.exists) return {
611
+ ids: normalizePinnedWorkspaceIds(host.pinnedWorkspaceIds),
612
+ writeHost: false
613
+ };
614
+ const ids = normalizePinnedWorkspaceIds(localIds);
615
+ return {
616
+ ids,
617
+ writeHost: ids.length > 0
618
+ };
619
+ }
620
+ async function readHostPinnedWorkspaceIds(fetcher = fetch) {
621
+ const response = await fetcher(WORKSPACE_PREFERENCES_ENDPOINT, {
622
+ method: "GET",
623
+ cache: "no-store",
624
+ signal: AbortSignal.timeout(5e3)
625
+ });
626
+ if (!response.ok) throw new Error(`读取置顶偏好失败:HTTP ${response.status}`);
627
+ const payload = await response.json();
628
+ if (payload === null || typeof payload !== "object") throw new Error("置顶偏好响应格式无效。");
629
+ const record = payload;
630
+ if (typeof record.exists !== "boolean" || !Array.isArray(record.pinnedWorkspaceIds) || !record.pinnedWorkspaceIds.every((id) => typeof id === "string")) throw new Error("置顶偏好响应格式无效。");
631
+ return {
632
+ exists: record.exists,
633
+ pinnedWorkspaceIds: normalizePinnedWorkspaceIds(record.pinnedWorkspaceIds)
634
+ };
635
+ }
636
+ async function writeHostPinnedWorkspaceIds(ids, fetcher = fetch) {
637
+ const response = await fetcher(WORKSPACE_PREFERENCES_ENDPOINT, {
638
+ method: "PUT",
639
+ cache: "no-store",
640
+ headers: { "content-type": "application/json" },
641
+ body: JSON.stringify({ pinnedWorkspaceIds: normalizePinnedWorkspaceIds(ids) }),
642
+ signal: AbortSignal.timeout(5e3)
643
+ });
644
+ if (!response.ok) throw new Error(`保存置顶偏好失败:HTTP ${response.status}`);
645
+ }
597
646
  /** 在置顶列表中切换一个工作区。 */
598
647
  /** 把工作区插入置顶列表的指定位置;省略锚点时追加到末尾。 */
599
648
  function insertPinnedWorkspace(ids, id, beforeId) {
@@ -1231,7 +1280,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
1231
1280
  .dcu-wb *{box-sizing:border-box}
1232
1281
  .dcu-wb-tree{flex:1;min-height:0;overflow-y:auto;padding-bottom:16px;scrollbar-gutter:stable;user-select:none;-webkit-user-select:none}
1233
1282
  .dcu-wb-section+.dcu-wb-section{margin-top:12px}
1234
- .dcu-wb-section-head{position:relative;display:flex;align-items:center;min-height:24px;padding:0 4px;border-radius:6px}.dcu-wb-section-head:hover .dcu-wb-actions{display:flex}.dcu-wb-section-label{display:flex;align-items:center;gap:4px;flex:1;min-width:0;min-height:24px;border:0;padding:2px 4px;background:transparent;color:var(--dcu-sidebar-tertiary);font:13px/20px var(--dcu-font,inherit);font-weight:400;letter-spacing:.02em;text-align:left;cursor:pointer}.dcu-wb-section-caret{display:grid;place-items:center;flex:none;width:12px;height:12px;color:currentColor;opacity:0;transform:rotate(0deg);transform-origin:50% 50%;transition:opacity 140ms ease,transform 180ms ease}.dcu-wb-section-caret svg{display:block}.dcu-wb-section-head:hover .dcu-wb-section-caret,.dcu-wb-section-label:focus-visible .dcu-wb-section-caret{opacity:.78}.dcu-wb-section-label[aria-expanded=true] .dcu-wb-section-caret{transform:rotate(90deg)}.dcu-wb-section-body{display:grid;grid-template-rows:0fr;transition:grid-template-rows 220ms ease}.dcu-wb-section-body[data-open=true]{grid-template-rows:1fr}.dcu-wb-section-body>div{overflow:hidden;min-height:0}@media (prefers-reduced-motion:reduce){.dcu-wb-section-caret,.dcu-wb-section-body{transition:none}}
1283
+ .dcu-wb-section-head{position:relative;display:flex;align-items:center;min-height:24px;padding:0 4px;border-radius:6px}.dcu-wb-section-head:hover .dcu-wb-actions{display:flex}.dcu-wb-section-label{display:flex;align-items:center;gap:4px;flex:1;min-width:0;min-height:24px;border:0;padding:2px 4px;background:transparent;color:var(--dcu-sidebar-tertiary);font:13px/20px var(--dcu-font,inherit);font-weight:400;letter-spacing:.02em;text-align:left;cursor:pointer}.dcu-wb-section-caret{display:grid;place-items:center;flex:none;width:12px;height:12px;color:currentColor;opacity:0;transform:rotate(0deg);transform-origin:50% 50%;transition:opacity 120ms ease,transform 160ms ease}.dcu-wb-section-caret svg{display:block}.dcu-wb-section-head:hover .dcu-wb-section-caret,.dcu-wb-section-label:focus-visible .dcu-wb-section-caret{opacity:.78}.dcu-wb-section-label[aria-expanded=true] .dcu-wb-section-caret{transform:rotate(90deg)}.dcu-wb-section-body{display:block}.dcu-wb-section-body[data-open=false]{display:none}.dcu-wb-section-body>div{min-height:0}.dcu-wb-section-body[data-open=true]>div{animation:dcu-wb-section-in 140ms cubic-bezier(.16,1,.3,1)}@keyframes dcu-wb-section-in{from{opacity:0;transform:translateY(-3px)}to{opacity:1;transform:none}}@media (prefers-reduced-motion:reduce){.dcu-wb-section-caret{transition:none}.dcu-wb-section-body[data-open=true]>div{animation:none}}
1235
1284
  .dcu-wb-project{position:relative}
1236
1285
  .dcu-wb-project-head,.dcu-wb-session{position:relative;display:flex;align-items:center;gap:6px;width:100%;border-radius:8px;padding:0 8px;color:var(--dcu-sidebar-primary);cursor:pointer}
1237
1286
  .dcu-wb-project-head{height:28px;background:transparent;font:inherit;text-align:left}
@@ -1269,7 +1318,15 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
1269
1318
  const typographyStyles = `.dcu-wb{font:14px/20px var(--dcu-font,var(--dsw-font-family))}.dcu-wb-section-label{color:var(--dcu-sidebar-tertiary);font-size:13px;font-weight:400;letter-spacing:.02em}.dcu-wb-project-title{font-size:14px;line-height:20px;font-weight:400;color:var(--dcu-sidebar-primary)}.dcu-wb-session-title{font-size:14px;line-height:20px;font-weight:400;color:var(--dcu-sidebar-secondary)}.dcu-wb-session.dcu-wb-selected .dcu-wb-session-title,.dcu-wb-session:hover .dcu-wb-session-title{color:var(--dcu-sidebar-primary)}.dcu-wb-empty{color:var(--dcu-sidebar-tertiary);font-size:13px;line-height:18px}.dcu-wb-nochat{padding:0 8px 4px 28px;color:var(--dcu-sidebar-tertiary);font-size:14px;line-height:20px}`;
1270
1319
  const WORKSPACE_TREE_STYLE = stylesheet$4 + runningStyles + typographyStyles;
1271
1320
  function storage$1() {
1272
- return typeof window === "undefined" ? void 0 : window.localStorage;
1321
+ if (typeof window === "undefined") return void 0;
1322
+ try {
1323
+ return window.localStorage;
1324
+ } catch {
1325
+ return;
1326
+ }
1327
+ }
1328
+ function sameIds(left, right) {
1329
+ return left.length === right.length && left.every((id, index) => id === right[index]);
1273
1330
  }
1274
1331
  function browserBase() {
1275
1332
  return typeof window === "undefined" || window.location.origin === "null" ? "http://dsh.internal/" : `${window.location.origin}/`;
@@ -1287,7 +1344,33 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
1287
1344
  const sessions = useSessions((state) => state);
1288
1345
  const workspaces = useWorkspaces((state) => state);
1289
1346
  const [expanded, setExpanded] = (0, react.useState)({});
1290
- const [pinnedWorkspaceIds, setPinnedWorkspaceIds] = (0, react.useState)(() => readPinnedWorkspaceIds(storage$1()));
1347
+ const [pinnedWorkspaceIds, setPinnedWorkspaceIdsState] = (0, react.useState)(() => readPinnedWorkspaceIds(storage$1()));
1348
+ const pinnedWorkspaceIdsRef = (0, react.useRef)(pinnedWorkspaceIds);
1349
+ pinnedWorkspaceIdsRef.current = pinnedWorkspaceIds;
1350
+ const pinnedHostHydratedRef = (0, react.useRef)(false);
1351
+ const pinnedHostDirtyRef = (0, react.useRef)(false);
1352
+ const pinnedHostSkipWriteRef = (0, react.useRef)();
1353
+ const pinnedHostWriteRef = (0, react.useRef)(Promise.resolve());
1354
+ const workspaceBaselineRef = (0, react.useRef)({
1355
+ ready: false,
1356
+ validIds: []
1357
+ });
1358
+ workspaceBaselineRef.current = {
1359
+ ready: workspaces.baselinesReady === true,
1360
+ validIds: workspaces.items.map((workspace) => String(workspace.workspaceId))
1361
+ };
1362
+ const queuePinnedHostWrite = (ids) => {
1363
+ const snapshot = [...ids];
1364
+ const pending = pinnedHostWriteRef.current.then(() => writeHostPinnedWorkspaceIds(snapshot));
1365
+ pinnedHostWriteRef.current = pending.catch(() => void 0);
1366
+ };
1367
+ const setPinnedWorkspaceIds = (update) => {
1368
+ pinnedHostDirtyRef.current = true;
1369
+ const current = pinnedWorkspaceIdsRef.current;
1370
+ const next = typeof update === "function" ? update(current) : update;
1371
+ pinnedWorkspaceIdsRef.current = next;
1372
+ setPinnedWorkspaceIdsState(next);
1373
+ };
1291
1374
  const [pinnedSessionIds, setPinnedSessionIds] = (0, react.useState)(() => readSessionIds(storage$1(), SESSION_PINS_STORAGE_KEY));
1292
1375
  const [unreadSessionIds, setUnreadSessionIds] = (0, react.useState)(() => readSessionIds(storage$1(), SESSION_UNREAD_STORAGE_KEY));
1293
1376
  const [menu, setMenu] = (0, react.useState)();
@@ -1303,7 +1386,12 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
1303
1386
  const busyRef = (0, react.useRef)();
1304
1387
  const [error, setError] = (0, react.useState)();
1305
1388
  const [workspaceDragId, setWorkspaceDragId] = (0, react.useState)();
1306
- const [workspaceDropTarget, setWorkspaceDropTarget] = (0, react.useState)();
1389
+ const [workspaceDropTarget, setWorkspaceDropTargetState] = (0, react.useState)();
1390
+ const workspaceDropTargetRef = (0, react.useRef)();
1391
+ const setWorkspaceDropTarget = (target) => {
1392
+ workspaceDropTargetRef.current = target;
1393
+ setWorkspaceDropTargetState(target);
1394
+ };
1307
1395
  const [headerMenu, setHeaderMenu] = (0, react.useState)();
1308
1396
  const headerMenuRef = (0, react.useRef)();
1309
1397
  headerMenuRef.current = headerMenu;
@@ -1312,7 +1400,34 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
1312
1400
  const [sessionDropTarget, setSessionDropTarget] = (0, react.useState)();
1313
1401
  (0, react.useEffect)(() => {
1314
1402
  savePinnedWorkspaceIds(storage$1(), pinnedWorkspaceIds);
1403
+ if (!pinnedHostHydratedRef.current) return;
1404
+ const skippedHydration = pinnedHostSkipWriteRef.current;
1405
+ pinnedHostSkipWriteRef.current = void 0;
1406
+ if (skippedHydration !== void 0 && sameIds(skippedHydration, pinnedWorkspaceIds)) return;
1407
+ queuePinnedHostWrite(pinnedWorkspaceIds);
1315
1408
  }, [pinnedWorkspaceIds]);
1409
+ (0, react.useEffect)(() => {
1410
+ let alive = true;
1411
+ const localIds = [...pinnedWorkspaceIdsRef.current];
1412
+ readHostPinnedWorkspaceIds().then((host) => {
1413
+ if (!alive) return;
1414
+ const hydration = resolvePinnedWorkspaceHydration(localIds, host, pinnedHostDirtyRef.current ? pinnedWorkspaceIdsRef.current : void 0);
1415
+ const baseline = workspaceBaselineRef.current;
1416
+ const ids = baseline.ready ? prunePinnedWorkspaceIds(hydration.ids, baseline.validIds) : hydration.ids;
1417
+ const writeHost = hydration.writeHost || !sameIds(ids, hydration.ids);
1418
+ pinnedHostHydratedRef.current = true;
1419
+ if (!sameIds(pinnedWorkspaceIdsRef.current, ids)) {
1420
+ pinnedHostSkipWriteRef.current = [...ids];
1421
+ pinnedWorkspaceIdsRef.current = ids;
1422
+ setPinnedWorkspaceIdsState(ids);
1423
+ }
1424
+ savePinnedWorkspaceIds(storage$1(), ids);
1425
+ if (writeHost) queuePinnedHostWrite(ids);
1426
+ }).catch(() => {});
1427
+ return () => {
1428
+ alive = false;
1429
+ };
1430
+ }, []);
1316
1431
  (0, react.useEffect)(() => {
1317
1432
  writeSessionIds(storage$1(), SESSION_PINS_STORAGE_KEY, pinnedSessionIds);
1318
1433
  }, [pinnedSessionIds]);
@@ -1320,10 +1435,12 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
1320
1435
  writeSessionIds(storage$1(), SESSION_UNREAD_STORAGE_KEY, unreadSessionIds);
1321
1436
  }, [unreadSessionIds]);
1322
1437
  (0, react.useEffect)(() => {
1323
- if (workspaces.items.length === 0) return;
1324
- const valid = new Set(workspaces.items.map((workspace) => String(workspace.workspaceId)));
1325
- setPinnedWorkspaceIds((ids) => ids.filter((id) => valid.has(id)));
1326
- }, [workspaces.items]);
1438
+ if (workspaces.baselinesReady !== true) return;
1439
+ const next = prunePinnedWorkspaceIds(pinnedWorkspaceIdsRef.current, workspaces.items.map((workspace) => String(workspace.workspaceId)));
1440
+ if (sameIds(pinnedWorkspaceIdsRef.current, next)) return;
1441
+ pinnedWorkspaceIdsRef.current = next;
1442
+ setPinnedWorkspaceIdsState(next);
1443
+ }, [workspaces.baselinesReady, workspaces.items]);
1327
1444
  (0, react.useEffect)(() => {
1328
1445
  const current = sessions.current;
1329
1446
  if (current !== void 0) setUnreadSessionIds((ids) => ids.filter((id) => id !== current));
@@ -1972,7 +2089,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
1972
2089
  onDrop: (event) => {
1973
2090
  event.preventDefault();
1974
2091
  const draggedWorkspace = readWorkspaceDrag(event.dataTransfer, workspaceDragId);
1975
- const target = workspaceDropTarget;
2092
+ const target = workspaceDropTargetRef.current;
1976
2093
  setWorkspaceDragId(void 0);
1977
2094
  setWorkspaceDropTarget(void 0);
1978
2095
  if (draggedWorkspace !== void 0 && target?.zone === "pinned") pinWorkspaceAt(draggedWorkspace, target.beforeId);
@@ -2994,18 +3111,20 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
2994
3111
  //#region src/client/CodexSidebar.tsx
2995
3112
  const subscribeEmptyCompanionTabs = () => () => {};
2996
3113
  const getEmptyCompanionTabs = () => EMPTY_COMPANION_TABS;
3114
+ const SIDEBAR_COLUMN_TRANSITION_MS = 300;
2997
3115
  const stylesheet$3 = `
2998
3116
  .dcu-root{--dcu-font:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","Microsoft YaHei UI",sans-serif;--dcu-sidebar-primary:#393d3e;--dcu-sidebar-secondary:#676b6c;--dcu-sidebar-tertiary:#9a9f9f;--dcu-sidebar-navigation:#4e5253;--dcu-sidebar-icon:#4e5253;--dcu-sidebar-hover:#dfe8e5;--dcu-sidebar-border:rgba(37,46,41,.10);--dcu-tip-bg:#ffffff;--dcu-tip-shadow:0 10px 32px rgba(31,39,36,.22);height:100%;min-width:0;box-sizing:border-box;display:flex;flex-direction:column;background:#eef7f5;color:var(--dcu-sidebar-primary);font:14px/20px var(--dcu-font)}body[data-ds-dark-theme] .dcu-root{background:#1d2120;--dcu-sidebar-primary:#b9bab9;--dcu-sidebar-secondary:#909191;--dcu-sidebar-tertiary:#666867;--dcu-sidebar-navigation:#b9bab9;--dcu-sidebar-icon:#afafaf;--dcu-sidebar-hover:#303432;--dcu-sidebar-border:rgba(255,255,255,.08);--dcu-tip-bg:#2a2e2c;--dcu-tip-shadow:0 10px 30px rgba(0,0,0,.28)}
3117
+ .dcu-expanded-shell{display:flex;min-height:0;flex:1;flex-direction:column;animation:dcu-sidebar-expanded-in 140ms cubic-bezier(.16,1,.3,1)}.dcu-compact-shell{display:none}.dcu-root.dcu-compact .dcu-expanded-shell{display:none}.dcu-root.dcu-compact .dcu-compact-shell{display:flex;min-height:0;flex:1;flex-direction:column;align-items:center;animation:dcu-sidebar-compact-in 120ms ease-out}@keyframes dcu-sidebar-expanded-in{from{opacity:0;transform:translateX(-4px)}to{opacity:1;transform:none}}@keyframes dcu-sidebar-compact-in{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}
2999
3118
  .dcu-root *{box-sizing:border-box}.dcu-head{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;column-gap:8px;height:60px;padding:8px 8px 8px 12px}.dcu-brand{border:0;background:transparent;color:inherit;padding:0;display:flex;align-items:center;min-width:0;overflow:hidden}.dcu-brand svg{display:block;width:auto;max-width:100%;height:24px;min-width:0}.dcu-head-actions{display:grid;grid-auto-flow:column;grid-auto-columns:28px;align-items:center;column-gap:8px;height:28px}
3000
3119
  .dcu-icon,.dcu-menu button,.dcu-footer-link{appearance:none;border:0;background:transparent;color:inherit;font:inherit;cursor:pointer}.dcu-icon{display:grid;place-items:center;width:36px;height:36px;border-radius:8px;color:var(--dcu-sidebar-icon)}.dcu-head .dcu-icon{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;margin:0;padding:0;border-radius:50%;line-height:0}.dcu-head .dcu-icon svg{display:block;width:16px;height:16px}
3001
3120
  .dcu-icon:hover,.dcu-menu button:hover:not(:disabled),.dcu-footer-link:hover{background:var(--dcu-sidebar-hover);color:var(--dcu-sidebar-primary)}
3002
3121
  .dcu-menu{padding:0 6px 8px;display:grid;gap:2px}.dcu-menu button,.dcu-footer-link{display:grid;grid-template-columns:20px minmax(0,1fr);column-gap:8px;align-items:center;width:100%;min-height:36px;padding:0 4px;border-radius:8px;color:var(--dcu-sidebar-navigation);font-size:14px;line-height:20px;text-align:left;font-weight:400}
3003
3122
  .dcu-menu-icon{display:grid;place-items:center start;width:20px;height:20px}.dcu-menu-icon svg,.dcu-footer-link svg{display:block;width:16px;height:16px;color:var(--dcu-sidebar-icon)}.dcu-menu button:disabled{color:var(--dcu-sidebar-secondary);cursor:default;opacity:1}.dcu-menu button:disabled svg{color:var(--dcu-sidebar-secondary)}
3004
3123
  .dcu-extension-items{display:grid;gap:1px;margin:1px 0 4px 28px}.dcu-extension-items button{min-height:32px;color:var(--dcu-sidebar-secondary);font-size:13px;font-weight:400}
3005
- .dcu-workspaces{display:flex;min-height:0;flex:1;flex-direction:column;margin-top:2px;padding-top:8px;border-top:1px solid var(--dcu-sidebar-border)}.dcu-workspaces.dcu-workspaces-tabs{padding-top:0;border-top:0}.dcu-im-tabs{display:flex;gap:16px;margin:0 8px 12px;padding:0;border-bottom:1px solid var(--dcu-sidebar-border)}.dcu-im-tab{appearance:none;border:0;background:transparent;color:var(--dcu-sidebar-secondary);padding:8px 0 7px;font:14px/22px var(--dcu-font);font-weight:500;cursor:pointer}.dcu-im-tab[data-on=true]{color:var(--dcu-sidebar-primary);font-weight:600;box-shadow:inset 0 -2px 0 currentColor}.dcu-native-workspaces{display:flex;min-height:0;flex:1}.dcu-native-workspaces>*{min-width:0;flex:1}.dcu-native-workspaces .ima-tabs,.dcu-native-workspaces [role=tablist]{display:none!important}.dcu-foot{display:grid;gap:4px;padding:8px 6px 12px;border-top:1px solid var(--dcu-sidebar-border)}.dcu-footer-actions:empty,.dcu-settings-seat:empty{display:none}.dcu-settings-seat>button{width:100%;min-height:36px;padding-left:4px!important;color:var(--dcu-sidebar-navigation);font:14px/20px var(--dcu-font);font-weight:400}.dcu-compact{width:100%;align-items:center;overflow:hidden;padding:10px 0 8px}.dcu-compact-nav{display:flex;flex:1;min-height:0;flex-direction:column;align-items:center;gap:2px;overflow:auto;padding:6px 0}.dcu-compact .dcu-icon{width:36px;height:36px;flex:none}.dcu-compact .dcu-head,.dcu-compact .dcu-menu,.dcu-compact .dcu-workspaces,.dcu-compact .dcu-brand,.dcu-compact .dcu-im-tabs{display:none}.dcu-compact .dcu-foot{width:36px;margin-top:auto;padding:8px 0;border-top:0}.dcu-compact .dcu-settings-seat{width:36px;overflow:hidden}.dcu-compact .dcu-settings-seat>button{display:grid;place-items:center;width:36px;min-height:36px;padding:0!important;font-size:0!important;line-height:0}.dcu-compact .dcu-settings-seat>button svg{width:16px;height:16px}.dcu-compact .dcu-footer-link{display:flex;justify-content:center;width:36px;padding:0;font-size:0}.dcu-compact .dcu-footer-link svg{width:16px;height:16px}
3124
+ .dcu-workspaces{display:flex;min-height:0;flex:1;flex-direction:column;margin-top:2px;padding-top:8px;border-top:1px solid var(--dcu-sidebar-border)}.dcu-workspaces.dcu-workspaces-tabs{padding-top:0;border-top:0}.dcu-im-tabs{display:flex;gap:16px;margin:0 8px 12px;padding:0;border-bottom:1px solid var(--dcu-sidebar-border)}.dcu-im-tab{appearance:none;border:0;background:transparent;color:var(--dcu-sidebar-secondary);padding:8px 0 7px;font:14px/22px var(--dcu-font);font-weight:500;cursor:pointer}.dcu-im-tab[data-on=true]{color:var(--dcu-sidebar-primary);font-weight:600;box-shadow:inset 0 -2px 0 currentColor}.dcu-native-workspaces{display:flex;min-height:0;flex:1}.dcu-native-workspaces>*{min-width:0;flex:1}.dcu-native-workspaces .ima-tabs,.dcu-native-workspaces [role=tablist]{display:none!important}.dcu-foot{display:grid;gap:4px;padding:8px 6px 12px;border-top:1px solid var(--dcu-sidebar-border)}.dcu-footer-actions:empty,.dcu-settings-seat:empty{display:none}.dcu-settings-seat>button{width:100%;min-height:36px;padding-left:4px!important;color:var(--dcu-sidebar-navigation);font:14px/20px var(--dcu-font);font-weight:400}.dcu-compact{width:100%;align-items:center;overflow:hidden;padding:10px 0 8px}.dcu-compact-nav{display:flex;flex:1;min-height:0;flex-direction:column;align-items:center;gap:2px;overflow:auto;padding:6px 0}.dcu-compact .dcu-icon{width:36px;height:36px;flex:none}.dcu-compact .dcu-foot{width:36px;margin-top:auto;padding:8px 0;border-top:0}.dcu-compact .dcu-settings-seat{width:36px;overflow:hidden}.dcu-compact .dcu-settings-seat>button{display:grid;place-items:center;width:36px;min-height:36px;padding:0!important;font-size:0!important;line-height:0}.dcu-compact .dcu-settings-seat>button svg{width:16px;height:16px}.dcu-compact .dcu-footer-link{display:flex;justify-content:center;width:36px;padding:0;font-size:0}.dcu-compact .dcu-footer-link svg{width:16px;height:16px}
3006
3125
  .dcu-dependency-notice{margin:0 10px 8px;border:1px solid var(--dcu-sidebar-border);border-radius:8px;padding:8px;color:var(--dcu-sidebar-secondary);font-size:12px;line-height:18px}
3007
3126
  [role="dialog"][aria-labelledby]{width:min(1000px,calc(100vw - 48px));max-width:calc(100vw - 48px);height:min(800px,calc(100vh - 48px))}
3008
- .dcu-search-scrim{position:fixed;z-index:10020;inset:0;display:flex;justify-content:center;align-items:flex-start;padding:72px 20px;background:color-mix(in srgb,#000 48%,transparent)}.dcu-search-dialog{width:min(560px,100%);max-height:min(640px,calc(100vh - 120px));overflow:auto;border:1px solid var(--dcu-sidebar-border);border-radius:16px;padding:10px;background:var(--dsw-specific-menu);box-shadow:var(--dsw-shadow-lv4)}.dcu-search-input{margin-bottom:8px}.dcu-search-section{padding:6px 0}.dcu-search-title{padding:0 8px 4px;color:var(--dcu-sidebar-tertiary);font-size:12px;font-weight:600}.dcu-search-row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;width:100%;min-height:34px;border:0;border-radius:8px;padding:6px 8px;background:transparent;color:var(--dcu-sidebar-primary);font:inherit;text-align:left;cursor:pointer}.dcu-search-row:hover,.dcu-search-row[data-active=true]{background:var(--dcu-sidebar-hover)}.dcu-search-main{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dcu-search-detail{max-width:160px;overflow:hidden;color:var(--dcu-sidebar-tertiary);font-size:12px;text-overflow:ellipsis;white-space:nowrap}.dcu-search-empty{padding:18px 8px;color:var(--dcu-sidebar-tertiary);font-size:13px}
3127
+ .dcu-search-scrim{position:fixed;z-index:10020;inset:0;display:flex;justify-content:center;align-items:flex-start;padding:72px 20px;background:color-mix(in srgb,#000 48%,transparent);animation:dcu-search-scrim-in 140ms ease-out}.dcu-search-dialog{width:min(560px,100%);max-height:min(640px,calc(100vh - 120px));overflow:auto;border:1px solid var(--dcu-sidebar-border);border-radius:16px;padding:10px;background:var(--dsw-specific-menu);box-shadow:var(--dsw-shadow-lv4);animation:dcu-search-dialog-in 180ms cubic-bezier(.16,1,.3,1)}@keyframes dcu-search-scrim-in{from{opacity:0}to{opacity:1}}@keyframes dcu-search-dialog-in{from{opacity:0;transform:translateY(-6px) scale(.985)}to{opacity:1;transform:none}}.dcu-search-input{margin-bottom:8px}.dcu-search-section{padding:6px 0}.dcu-search-title{padding:0 8px 4px;color:var(--dcu-sidebar-tertiary);font-size:12px;font-weight:600}.dcu-search-row{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;width:100%;min-height:34px;border:0;border-radius:8px;padding:6px 8px;background:transparent;color:var(--dcu-sidebar-primary);font:inherit;text-align:left;cursor:pointer}.dcu-search-row:hover,.dcu-search-row[data-active=true]{background:var(--dcu-sidebar-hover)}.dcu-search-main{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dcu-search-detail{max-width:160px;overflow:hidden;color:var(--dcu-sidebar-tertiary);font-size:12px;text-overflow:ellipsis;white-space:nowrap}.dcu-search-empty{padding:18px 8px;color:var(--dcu-sidebar-tertiary);font-size:13px}@media (prefers-reduced-motion:reduce){.dcu-expanded-shell,.dcu-root.dcu-compact .dcu-compact-shell,.dcu-search-scrim,.dcu-search-dialog{animation:none}}
3009
3128
  [data-conversation-scroll]{--dsh-chat-content-width:800px;--dsh-composer-card-max-width:calc(var(--dsh-chat-content-width) + 32px);--dsh-composer-side-clearance:24px}[data-conversation-scroll] [data-chat-flow]{gap:20px}[data-conversation-scroll] [data-composer-card]{min-height:96px;padding-top:10px;border-radius:16px;box-shadow:var(--dsw-shadow-lv3);transition:border-color 180ms ease,box-shadow 180ms ease}[data-conversation-scroll] [data-composer-card]:focus-within{border-color:var(--dsw-alias-button-info-fill);box-shadow:0 0 0 2px var(--dsw-static-deepseek-50),var(--dsw-shadow-lv3)}[data-conversation-scroll] [data-input-mirror]{min-height:44px}@media (prefers-reduced-motion:reduce){[data-conversation-scroll] [data-composer-card]{transition:none}}
3010
3129
  `;
3011
3130
  function MenuIcon({ children }) {
@@ -3043,40 +3162,41 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3043
3162
  })
3044
3163
  });
3045
3164
  }
3046
- /** Codex 风格的 DSH 侧栏,只替换导航外观,项目浏览和设置仍由 DSH 官方组件提供。 */
3047
- function CodexSidebar({ collapsed, width, openSession, startSession, toggleSidebar, archiveSession, deleteSession, forkSession, renameSession, openPath, companionSlots, renderSlot, t, useSessions, useWorkspaces }) {
3048
- const settingsSeat = (0, react.useRef)(null);
3049
- const [extensionsOpen, setExtensionsOpen] = (0, react.useState)(true);
3050
- const [searchOpen, setSearchOpen] = (0, react.useState)(false);
3051
- const [searchQuery, setSearchQuery] = (0, react.useState)("");
3052
- const [activeSearchIndex, setActiveSearchIndex] = (0, react.useState)(0);
3053
- const [imTab, setImTab] = (0, react.useState)("tasks");
3054
- const companionTabs = (0, react.useSyncExternalStore)(companionSlots?.subscribe ?? subscribeEmptyCompanionTabs, companionSlots?.getSnapshot ?? getEmptyCompanionTabs, companionSlots?.getSnapshot ?? getEmptyCompanionTabs);
3055
- const showChannels = companionTabs.channels;
3056
- const showSchedule = companionTabs.schedule;
3057
- const showCompanionTabs = showChannels || showSchedule;
3165
+ /** 搜索状态与大侧栏隔离:输入、悬停和开关弹窗都不能让工作区树跟着重渲染。 */
3166
+ const SidebarSearch = (0, react.forwardRef)(function SidebarSearch({ openSession, startSession, t, useSessions, useWorkspaces, settingsSeat }, ref) {
3167
+ const [open, setOpen] = (0, react.useState)(false);
3168
+ const [query, setQuery] = (0, react.useState)("");
3169
+ const [activeIndex, setActiveIndex] = (0, react.useState)(0);
3170
+ const deferredQuery = (0, react.useDeferredValue)(query);
3058
3171
  const sessions = useSessions((state) => state);
3059
3172
  const workspaces = useWorkspaces((state) => state);
3060
- const selectSection = (label) => {
3173
+ const close = (0, react.useCallback)(() => {
3174
+ setOpen(false);
3175
+ setQuery("");
3176
+ setActiveIndex(0);
3177
+ }, []);
3178
+ (0, react.useImperativeHandle)(ref, () => ({ open: () => {
3179
+ setOpen(true);
3180
+ } }), []);
3181
+ const selectSection = (0, react.useCallback)((label) => {
3061
3182
  openSettingsSection(settingsSeat.current, label);
3062
- };
3063
- const selectPluginSection = () => {
3183
+ }, [settingsSeat]);
3184
+ const selectPluginSection = (0, react.useCallback)(() => {
3064
3185
  openSettingsSection(settingsSeat.current, [t("sidebar.marketplace"), t("sidebar.plugins")]);
3065
- };
3066
- const selectExternalSection = (label) => {
3186
+ }, [settingsSeat, t]);
3187
+ const selectExternalSection = (0, react.useCallback)((label) => {
3067
3188
  openSettingsSection(settingsSeat.current, label, () => {
3068
3189
  selectSection(t("about.nav"));
3069
3190
  });
3070
- };
3071
- const openSettings = () => {
3191
+ }, [
3192
+ selectSection,
3193
+ settingsSeat,
3194
+ t
3195
+ ]);
3196
+ const openSettings = (0, react.useCallback)(() => {
3072
3197
  settingsSeat.current?.querySelector("[aria-haspopup=\"dialog\"]")?.click();
3073
- };
3074
- const closeSearch = () => {
3075
- setSearchOpen(false);
3076
- setSearchQuery("");
3077
- setActiveSearchIndex(0);
3078
- };
3079
- const searchEntries = (0, react.useMemo)(() => {
3198
+ }, [settingsSeat]);
3199
+ const entries = (0, react.useMemo)(() => {
3080
3200
  const archived = new Set(workspaces.archivedSessionIds);
3081
3201
  const workspaceTitles = new Map(workspaces.items.flatMap((workspace) => workspace.sessionIds.map((sessionId) => [String(sessionId), workspace.title])));
3082
3202
  const sessionEntries = sessions.ids.map((id) => sessions.byId[id]).filter((session) => session !== void 0 && !archived.has(session.id) && isTaskSession(session)).sort((left, right) => right.updatedAt - left.updatedAt).map((session) => ({
@@ -3086,7 +3206,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3086
3206
  keywords: `${session.cwd ?? ""} ${session.id}`,
3087
3207
  detail: workspaceTitles.get(String(session.id)) ?? session.cwd,
3088
3208
  run: () => {
3089
- closeSearch();
3209
+ close();
3090
3210
  openSession(session.id);
3091
3211
  }
3092
3212
  }));
@@ -3097,7 +3217,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3097
3217
  label: t("search.settings"),
3098
3218
  keywords: t("search.settings"),
3099
3219
  run: () => {
3100
- closeSearch();
3220
+ close();
3101
3221
  openSettings();
3102
3222
  }
3103
3223
  },
@@ -3107,7 +3227,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3107
3227
  label: t("sidebar.experts"),
3108
3228
  keywords: t("search.settings"),
3109
3229
  run: () => {
3110
- closeSearch();
3230
+ close();
3111
3231
  selectExternalSection(t("sidebar.experts"));
3112
3232
  }
3113
3233
  },
@@ -3117,7 +3237,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3117
3237
  label: t("sidebar.skills"),
3118
3238
  keywords: t("search.settings"),
3119
3239
  run: () => {
3120
- closeSearch();
3240
+ close();
3121
3241
  selectExternalSection(t("sidebar.skills"));
3122
3242
  }
3123
3243
  },
@@ -3127,7 +3247,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3127
3247
  label: t("sidebar.plugins"),
3128
3248
  keywords: t("search.settings"),
3129
3249
  run: () => {
3130
- closeSearch();
3250
+ close();
3131
3251
  selectPluginSection();
3132
3252
  }
3133
3253
  },
@@ -3137,7 +3257,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3137
3257
  label: t("sidebar.connectors"),
3138
3258
  keywords: t("search.settings"),
3139
3259
  run: () => {
3140
- closeSearch();
3260
+ close();
3141
3261
  selectSection(t("sidebar.connectors"));
3142
3262
  }
3143
3263
  },
@@ -3147,7 +3267,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3147
3267
  label: t("sidebar.schedule"),
3148
3268
  keywords: t("search.settings"),
3149
3269
  run: () => {
3150
- closeSearch();
3270
+ close();
3151
3271
  selectExternalSection(t("sidebar.schedule"));
3152
3272
  }
3153
3273
  },
@@ -3157,7 +3277,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3157
3277
  label: t("sidebar.assistant"),
3158
3278
  keywords: t("search.settings"),
3159
3279
  run: () => {
3160
- closeSearch();
3280
+ close();
3161
3281
  selectExternalSection([t("sidebar.imSettings"), "IM助理"]);
3162
3282
  }
3163
3283
  },
@@ -3167,7 +3287,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3167
3287
  label: t("about.nav"),
3168
3288
  keywords: t("search.settings"),
3169
3289
  run: () => {
3170
- closeSearch();
3290
+ close();
3171
3291
  selectSection(t("about.nav"));
3172
3292
  }
3173
3293
  }
@@ -3181,13 +3301,18 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3181
3301
  label: t("sidebar.newTask"),
3182
3302
  keywords: t("search.actions"),
3183
3303
  run: () => {
3184
- closeSearch();
3304
+ close();
3185
3305
  startSession();
3186
3306
  }
3187
3307
  }
3188
3308
  ];
3189
3309
  }, [
3310
+ close,
3190
3311
  openSession,
3312
+ openSettings,
3313
+ selectExternalSection,
3314
+ selectPluginSection,
3315
+ selectSection,
3191
3316
  sessions.byId,
3192
3317
  sessions.ids,
3193
3318
  startSession,
@@ -3195,38 +3320,30 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3195
3320
  workspaces.archivedSessionIds,
3196
3321
  workspaces.items
3197
3322
  ]);
3198
- const searchResults = (0, react.useMemo)(() => filterSidebarSearchItems(searchEntries, searchQuery).slice(0, 12), [searchEntries, searchQuery]);
3323
+ const results = (0, react.useMemo)(() => filterSidebarSearchItems(entries, deferredQuery).slice(0, 12), [deferredQuery, entries]);
3199
3324
  (0, react.useEffect)(() => {
3200
- setActiveSearchIndex(0);
3201
- }, [searchQuery, searchOpen]);
3202
- (0, react.useEffect)(() => {
3203
- if (imTab === "channels" && !showChannels) setImTab("tasks");
3204
- if (imTab === "schedule" && !showSchedule) setImTab("tasks");
3205
- }, [
3206
- imTab,
3207
- showChannels,
3208
- showSchedule
3209
- ]);
3325
+ setActiveIndex(0);
3326
+ }, [query, open]);
3210
3327
  (0, react.useEffect)(() => {
3211
- if (!searchOpen) return;
3328
+ if (!open) return;
3212
3329
  const onKeyDown = (event) => {
3213
3330
  if (event.key === "Escape") {
3214
3331
  event.preventDefault();
3215
- closeSearch();
3332
+ close();
3216
3333
  return;
3217
3334
  }
3218
3335
  if (event.key === "ArrowDown") {
3219
3336
  event.preventDefault();
3220
- setActiveSearchIndex((index) => Math.min(index + 1, Math.max(0, searchResults.length - 1)));
3337
+ setActiveIndex((index) => Math.min(index + 1, Math.max(0, results.length - 1)));
3221
3338
  return;
3222
3339
  }
3223
3340
  if (event.key === "ArrowUp") {
3224
3341
  event.preventDefault();
3225
- setActiveSearchIndex((index) => Math.max(index - 1, 0));
3342
+ setActiveIndex((index) => Math.max(index - 1, 0));
3226
3343
  return;
3227
3344
  }
3228
3345
  if (event.key === "Enter") {
3229
- const entry = searchResults[activeSearchIndex];
3346
+ const entry = results[activeIndex];
3230
3347
  if (entry !== void 0) {
3231
3348
  event.preventDefault();
3232
3349
  entry.run();
@@ -3238,9 +3355,107 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3238
3355
  window.removeEventListener("keydown", onKeyDown);
3239
3356
  };
3240
3357
  }, [
3241
- activeSearchIndex,
3242
- searchOpen,
3243
- searchResults
3358
+ activeIndex,
3359
+ close,
3360
+ open,
3361
+ results
3362
+ ]);
3363
+ if (!open) return null;
3364
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3365
+ className: "dcu-search-scrim",
3366
+ onMouseDown: (event) => {
3367
+ if (event.target === event.currentTarget) close();
3368
+ },
3369
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3370
+ className: "dcu-search-dialog",
3371
+ role: "dialog",
3372
+ "aria-modal": "true",
3373
+ "aria-label": t("sidebar.search"),
3374
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3375
+ className: "dcu-search-input",
3376
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
3377
+ autoFocus: true,
3378
+ icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSearchOutline16, { size: 16 }),
3379
+ value: query,
3380
+ placeholder: t("search.placeholder"),
3381
+ onChange: (event) => {
3382
+ setQuery(event.target.value);
3383
+ }
3384
+ })
3385
+ }), results.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3386
+ className: "dcu-search-empty",
3387
+ children: t("search.empty")
3388
+ }) : [
3389
+ "sessions",
3390
+ "settings",
3391
+ "actions"
3392
+ ].map((group) => {
3393
+ const grouped = results.filter((entry) => entry.group === group);
3394
+ if (grouped.length === 0) return null;
3395
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3396
+ className: "dcu-search-section",
3397
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3398
+ className: "dcu-search-title",
3399
+ children: t(`search.${group}`)
3400
+ }), grouped.map((entry) => {
3401
+ const index = results.indexOf(entry);
3402
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3403
+ type: "button",
3404
+ className: "dcu-search-row",
3405
+ "data-active": index === activeIndex,
3406
+ onMouseEnter: () => {
3407
+ setActiveIndex(index);
3408
+ },
3409
+ onClick: entry.run,
3410
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3411
+ className: "dcu-search-main",
3412
+ children: entry.label
3413
+ }), entry.detail !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3414
+ className: "dcu-search-detail",
3415
+ children: entry.detail
3416
+ })]
3417
+ }, entry.id);
3418
+ })]
3419
+ }, group);
3420
+ })]
3421
+ })
3422
+ });
3423
+ });
3424
+ /** Codex 风格的 DSH 侧栏,只替换导航外观,项目浏览和设置仍由 DSH 官方组件提供。 */
3425
+ function CodexSidebar({ collapsed, width, openSession, startSession, toggleSidebar, archiveSession, deleteSession, forkSession, renameSession, openPath, companionSlots, renderSlot, t, useSessions, useWorkspaces }) {
3426
+ const compact = collapsed || width < 80;
3427
+ const [visualCompact, setVisualCompact] = (0, react.useState)(compact);
3428
+ const settingsSeat = (0, react.useRef)(null);
3429
+ const search = (0, react.useRef)(null);
3430
+ const toggleSidebarRef = (0, react.useRef)(toggleSidebar);
3431
+ toggleSidebarRef.current = toggleSidebar;
3432
+ const expandSidebar = (0, react.useCallback)(() => {
3433
+ toggleSidebarRef.current();
3434
+ }, []);
3435
+ const [extensionsOpen, setExtensionsOpen] = (0, react.useState)(true);
3436
+ const [imTab, setImTab] = (0, react.useState)("tasks");
3437
+ const companionTabs = (0, react.useSyncExternalStore)(companionSlots?.subscribe ?? subscribeEmptyCompanionTabs, companionSlots?.getSnapshot ?? getEmptyCompanionTabs, companionSlots?.getSnapshot ?? getEmptyCompanionTabs);
3438
+ const showChannels = companionTabs.channels;
3439
+ const showSchedule = companionTabs.schedule;
3440
+ const showCompanionTabs = showChannels || showSchedule;
3441
+ const selectSection = (label) => {
3442
+ openSettingsSection(settingsSeat.current, label);
3443
+ };
3444
+ const selectPluginSection = () => {
3445
+ openSettingsSection(settingsSeat.current, [t("sidebar.marketplace"), t("sidebar.plugins")]);
3446
+ };
3447
+ const selectExternalSection = (label) => {
3448
+ openSettingsSection(settingsSeat.current, label, () => {
3449
+ selectSection(t("about.nav"));
3450
+ });
3451
+ };
3452
+ (0, react.useEffect)(() => {
3453
+ if (imTab === "channels" && !showChannels) setImTab("tasks");
3454
+ if (imTab === "schedule" && !showSchedule) setImTab("tasks");
3455
+ }, [
3456
+ imTab,
3457
+ showChannels,
3458
+ showSchedule
3244
3459
  ]);
3245
3460
  (0, react.useEffect)(() => {
3246
3461
  let startX = 0;
@@ -3277,403 +3492,301 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3277
3492
  window.removeEventListener("pointercancel", onCancel, true);
3278
3493
  };
3279
3494
  }, [toggleSidebar]);
3280
- if (collapsed || width < 80) return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
3281
- className: "dcu-root dcu-compact",
3282
- "aria-label": t("sidebar.label"),
3283
- children: [
3284
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: stylesheet$3 }),
3285
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3286
- type: "button",
3287
- className: "dcu-icon",
3288
- "aria-label": t("sidebar.expand"),
3289
- onClick: toggleSidebar,
3290
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPanelLeftOutline16, { size: 16 })
3291
- }),
3292
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
3293
- className: "dcu-compact-nav",
3294
- "aria-label": t("sidebar.mainMenu"),
3295
- children: [
3296
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3297
- type: "button",
3298
- className: "dcu-icon",
3299
- "aria-label": t("sidebar.newTask"),
3300
- onClick: () => {
3301
- startSession();
3302
- },
3303
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconNewChatOutline16, { size: 16 })
3304
- }),
3305
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3306
- type: "button",
3307
- className: "dcu-icon",
3308
- "aria-label": t("sidebar.search"),
3309
- onClick: () => {
3310
- setSearchOpen(true);
3311
- },
3312
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSearchOutline16, { size: 16 })
3313
- }),
3314
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3315
- type: "button",
3316
- className: "dcu-icon",
3317
- "aria-label": t("sidebar.experts"),
3318
- onClick: () => {
3319
- selectExternalSection(t("sidebar.experts"));
3320
- },
3321
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconUserOutline16, { size: 16 })
3322
- }),
3323
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3324
- type: "button",
3325
- className: "dcu-icon",
3326
- "aria-label": t("sidebar.skills"),
3327
- onClick: () => {
3328
- selectExternalSection(t("sidebar.skills"));
3329
- },
3330
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSkillOutline16, { size: 16 })
3331
- }),
3332
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3333
- type: "button",
3334
- className: "dcu-icon",
3335
- "aria-label": t("sidebar.plugins"),
3336
- onClick: () => {
3337
- selectPluginSection();
3338
- },
3339
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPersonalizationOutline16, { size: 16 })
3340
- }),
3341
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3342
- type: "button",
3343
- className: "dcu-icon",
3344
- "aria-label": t("sidebar.connectors"),
3345
- onClick: () => {
3346
- selectSection(t("sidebar.connectors"));
3347
- },
3348
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconLinkOutline16, { size: 16 })
3349
- }),
3350
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3351
- type: "button",
3352
- className: "dcu-icon",
3353
- "aria-label": t("sidebar.schedule"),
3354
- onClick: () => {
3355
- selectExternalSection(t("sidebar.schedule"));
3356
- },
3357
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScheduleIcon, {})
3358
- }),
3359
- /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3360
- type: "button",
3361
- className: "dcu-icon",
3362
- "aria-label": t("sidebar.assistant"),
3363
- onClick: () => {
3364
- selectExternalSection([t("sidebar.imSettings"), "IM助理"]);
3365
- },
3366
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImAssistantIcon, {})
3367
- })
3368
- ]
3369
- }),
3370
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("footer", {
3371
- className: "dcu-foot",
3372
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3373
- className: "dcu-footer-actions",
3374
- children: renderSlot("sidebar.footer.action", { wide: false })
3375
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3376
- ref: settingsSeat,
3377
- className: "dcu-settings-seat",
3378
- children: renderSlot("sidebar.settings", { wide: false })
3379
- })]
3380
- }),
3381
- searchOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3382
- className: "dcu-search-scrim",
3383
- onMouseDown: (event) => {
3384
- if (event.target === event.currentTarget) closeSearch();
3385
- },
3386
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3387
- className: "dcu-search-dialog",
3388
- role: "dialog",
3389
- "aria-modal": "true",
3390
- "aria-label": t("sidebar.search"),
3391
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3392
- className: "dcu-search-input",
3393
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
3394
- autoFocus: true,
3395
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSearchOutline16, { size: 16 }),
3396
- value: searchQuery,
3397
- placeholder: t("search.placeholder"),
3398
- onChange: (event) => {
3399
- setSearchQuery(event.target.value);
3400
- }
3401
- })
3402
- }), searchResults.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3403
- className: "dcu-search-empty",
3404
- children: t("search.empty")
3405
- }) : [
3406
- "sessions",
3407
- "settings",
3408
- "actions"
3409
- ].map((group) => {
3410
- const entries = searchResults.filter((entry) => entry.group === group);
3411
- if (entries.length === 0) return null;
3412
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3413
- className: "dcu-search-section",
3414
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3415
- className: "dcu-search-title",
3416
- children: t(`search.${group}`)
3417
- }), entries.map((entry) => {
3418
- const index = searchResults.indexOf(entry);
3419
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3420
- type: "button",
3421
- className: "dcu-search-row",
3422
- "data-active": index === activeSearchIndex,
3423
- onMouseEnter: () => {
3424
- setActiveSearchIndex(index);
3425
- },
3426
- onClick: entry.run,
3427
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3428
- className: "dcu-search-main",
3429
- children: entry.label
3430
- }), entry.detail !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3431
- className: "dcu-search-detail",
3432
- children: entry.detail
3433
- })]
3434
- }, entry.id);
3435
- })]
3436
- }, group);
3437
- })]
3438
- })
3439
- })
3440
- ]
3441
- });
3495
+ (0, react.useLayoutEffect)(() => {
3496
+ if (compact) {
3497
+ setVisualCompact(true);
3498
+ return;
3499
+ }
3500
+ if (!visualCompact) return;
3501
+ if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches === true) {
3502
+ setVisualCompact(false);
3503
+ return;
3504
+ }
3505
+ const timer = window.setTimeout(() => {
3506
+ setVisualCompact(false);
3507
+ }, SIDEBAR_COLUMN_TRANSITION_MS);
3508
+ return () => {
3509
+ window.clearTimeout(timer);
3510
+ };
3511
+ }, [compact, visualCompact]);
3512
+ const workspaceSlot = (0, react.useMemo)(() => renderSlot("sidebar.workspaces", {
3513
+ wide: true,
3514
+ expandSidebar
3515
+ }), [expandSidebar, renderSlot]);
3442
3516
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
3443
- className: "dcu-root",
3517
+ className: `dcu-root${visualCompact ? " dcu-compact" : ""}`,
3444
3518
  "aria-label": t("sidebar.label"),
3445
3519
  children: [
3446
3520
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: stylesheet$3 }),
3447
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
3448
- className: "dcu-head",
3449
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3450
- type: "button",
3451
- className: "dcu-brand",
3452
- "aria-label": t("sidebar.newTask"),
3453
- onClick: () => {
3454
- startSession();
3455
- },
3456
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.BrandWordmark, { size: 24 })
3457
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3458
- className: "dcu-head-actions",
3459
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3460
- type: "button",
3461
- className: "dcu-icon",
3462
- "aria-label": t("sidebar.collapse"),
3463
- onClick: toggleSidebar,
3464
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPanelLeftOutline16, { size: 16 })
3465
- }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3466
- type: "button",
3467
- className: "dcu-icon",
3468
- "aria-label": t("sidebar.search"),
3469
- onClick: () => {
3470
- setSearchOpen(true);
3471
- },
3472
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSearchOutline16, { size: 16 })
3473
- })]
3474
- })]
3475
- }),
3476
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
3477
- className: "dcu-menu",
3478
- "aria-label": t("sidebar.mainMenu"),
3521
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3522
+ className: "dcu-expanded-shell",
3479
3523
  children: [
3480
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3481
- type: "button",
3482
- onClick: () => {
3483
- startSession();
3484
- },
3485
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconNewChatOutline16, { size: 16 }) }), t("sidebar.newTask")]
3486
- }),
3487
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3488
- type: "button",
3489
- "aria-expanded": extensionsOpen,
3490
- onClick: () => {
3491
- setExtensionsOpen((open) => !open);
3492
- },
3493
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEnhanceOutline16, { size: 16 }) }), t("sidebar.extensions")]
3524
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
3525
+ className: "dcu-head",
3526
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3527
+ type: "button",
3528
+ className: "dcu-brand",
3529
+ "aria-label": t("sidebar.newTask"),
3530
+ onClick: () => {
3531
+ startSession();
3532
+ },
3533
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.BrandWordmark, { size: 24 })
3534
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3535
+ className: "dcu-head-actions",
3536
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3537
+ type: "button",
3538
+ className: "dcu-icon",
3539
+ "aria-label": t("sidebar.collapse"),
3540
+ onClick: toggleSidebar,
3541
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPanelLeftOutline16, { size: 16 })
3542
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3543
+ type: "button",
3544
+ className: "dcu-icon",
3545
+ "aria-label": t("sidebar.search"),
3546
+ onClick: () => {
3547
+ search.current?.open();
3548
+ },
3549
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSearchOutline16, { size: 16 })
3550
+ })]
3551
+ })]
3494
3552
  }),
3495
- extensionsOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3496
- className: "dcu-extension-items",
3553
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
3554
+ className: "dcu-menu",
3555
+ "aria-label": t("sidebar.mainMenu"),
3497
3556
  children: [
3498
3557
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3499
3558
  type: "button",
3500
3559
  onClick: () => {
3501
- selectExternalSection(t("sidebar.experts"));
3560
+ startSession();
3502
3561
  },
3503
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconUserOutline16, { size: 16 }) }), t("sidebar.experts")]
3562
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconNewChatOutline16, { size: 16 }) }), t("sidebar.newTask")]
3504
3563
  }),
3505
3564
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3506
3565
  type: "button",
3566
+ "aria-expanded": extensionsOpen,
3507
3567
  onClick: () => {
3508
- selectExternalSection(t("sidebar.skills"));
3568
+ setExtensionsOpen((open) => !open);
3509
3569
  },
3510
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSkillOutline16, { size: 16 }) }), t("sidebar.skills")]
3570
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconEnhanceOutline16, { size: 16 }) }), t("sidebar.extensions")]
3571
+ }),
3572
+ extensionsOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3573
+ className: "dcu-extension-items",
3574
+ children: [
3575
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3576
+ type: "button",
3577
+ onClick: () => {
3578
+ selectExternalSection(t("sidebar.experts"));
3579
+ },
3580
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconUserOutline16, { size: 16 }) }), t("sidebar.experts")]
3581
+ }),
3582
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3583
+ type: "button",
3584
+ onClick: () => {
3585
+ selectExternalSection(t("sidebar.skills"));
3586
+ },
3587
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSkillOutline16, { size: 16 }) }), t("sidebar.skills")]
3588
+ }),
3589
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3590
+ type: "button",
3591
+ onClick: () => {
3592
+ selectPluginSection();
3593
+ },
3594
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPersonalizationOutline16, { size: 16 }) }), t("sidebar.plugins")]
3595
+ }),
3596
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3597
+ type: "button",
3598
+ onClick: () => {
3599
+ selectSection(t("sidebar.connectors"));
3600
+ },
3601
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconLinkOutline16, { size: 16 }) }), t("sidebar.connectors")]
3602
+ })
3603
+ ]
3511
3604
  }),
3512
3605
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3513
3606
  type: "button",
3514
3607
  onClick: () => {
3515
- selectPluginSection();
3608
+ selectExternalSection(t("sidebar.schedule"));
3516
3609
  },
3517
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPersonalizationOutline16, { size: 16 }) }), t("sidebar.plugins")]
3610
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScheduleIcon, {}) }), t("sidebar.schedule")]
3518
3611
  }),
3519
3612
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3520
3613
  type: "button",
3521
3614
  onClick: () => {
3522
- selectSection(t("sidebar.connectors"));
3615
+ selectExternalSection([t("sidebar.imSettings"), "IM助理"]);
3523
3616
  },
3524
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconLinkOutline16, { size: 16 }) }), t("sidebar.connectors")]
3617
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImAssistantIcon, {}) }), t("sidebar.assistant")]
3525
3618
  })
3526
3619
  ]
3527
3620
  }),
3528
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3529
- type: "button",
3530
- onClick: () => {
3531
- selectExternalSection(t("sidebar.schedule"));
3532
- },
3533
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScheduleIcon, {}) }), t("sidebar.schedule")]
3534
- }),
3535
- /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3536
- type: "button",
3537
- onClick: () => {
3538
- selectExternalSection([t("sidebar.imSettings"), "IM助理"]);
3539
- },
3540
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(MenuIcon, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImAssistantIcon, {}) }), t("sidebar.assistant")]
3621
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3622
+ className: showCompanionTabs ? "dcu-workspaces dcu-workspaces-tabs" : "dcu-workspaces",
3623
+ children: [showCompanionTabs && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3624
+ className: "dcu-im-tabs",
3625
+ children: [
3626
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3627
+ type: "button",
3628
+ className: "dcu-im-tab",
3629
+ "data-on": imTab === "tasks",
3630
+ onClick: () => {
3631
+ setImTab("tasks");
3632
+ },
3633
+ children: t("sidebar.tasksTab")
3634
+ }),
3635
+ showChannels && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3636
+ type: "button",
3637
+ className: "dcu-im-tab",
3638
+ "data-on": imTab === "channels",
3639
+ onClick: () => {
3640
+ setImTab("channels");
3641
+ },
3642
+ children: t("sidebar.channelsTab")
3643
+ }),
3644
+ showSchedule && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3645
+ type: "button",
3646
+ className: "dcu-im-tab",
3647
+ "data-on": imTab === "schedule",
3648
+ onClick: () => {
3649
+ setImTab("schedule");
3650
+ },
3651
+ children: t("sidebar.scheduleTab")
3652
+ })
3653
+ ]
3654
+ }), imTab === "channels" && showChannels ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3655
+ className: "dcu-native-workspaces",
3656
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChannelBrowser, {
3657
+ openSession,
3658
+ archiveSession,
3659
+ deleteSession,
3660
+ forkSession,
3661
+ renameSession,
3662
+ useSessions,
3663
+ t
3664
+ })
3665
+ }) : imTab === "schedule" && showSchedule ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3666
+ className: "dcu-native-workspaces",
3667
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScheduleBrowser, {
3668
+ openSession,
3669
+ archiveSession,
3670
+ deleteSession,
3671
+ forkSession,
3672
+ renameSession,
3673
+ useSessions,
3674
+ useWorkspaces,
3675
+ t
3676
+ })
3677
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3678
+ className: "dcu-native-workspaces",
3679
+ children: workspaceSlot
3680
+ })]
3541
3681
  })
3542
3682
  ]
3543
3683
  }),
3544
3684
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3545
- className: showCompanionTabs ? "dcu-workspaces dcu-workspaces-tabs" : "dcu-workspaces",
3546
- children: [showCompanionTabs && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3547
- className: "dcu-im-tabs",
3685
+ className: "dcu-compact-shell",
3686
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3687
+ type: "button",
3688
+ className: "dcu-icon",
3689
+ "aria-label": t("sidebar.expand"),
3690
+ onClick: toggleSidebar,
3691
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPanelLeftOutline16, { size: 16 })
3692
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("nav", {
3693
+ className: "dcu-compact-nav",
3694
+ "aria-label": t("sidebar.mainMenu"),
3548
3695
  children: [
3549
3696
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3550
3697
  type: "button",
3551
- className: "dcu-im-tab",
3552
- "data-on": imTab === "tasks",
3698
+ className: "dcu-icon",
3699
+ "aria-label": t("sidebar.newTask"),
3700
+ onClick: () => {
3701
+ startSession();
3702
+ },
3703
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconNewChatOutline16, { size: 16 })
3704
+ }),
3705
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3706
+ type: "button",
3707
+ className: "dcu-icon",
3708
+ "aria-label": t("sidebar.search"),
3709
+ onClick: () => {
3710
+ search.current?.open();
3711
+ },
3712
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSearchOutline16, { size: 16 })
3713
+ }),
3714
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3715
+ type: "button",
3716
+ className: "dcu-icon",
3717
+ "aria-label": t("sidebar.experts"),
3718
+ onClick: () => {
3719
+ selectExternalSection(t("sidebar.experts"));
3720
+ },
3721
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconUserOutline16, { size: 16 })
3722
+ }),
3723
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3724
+ type: "button",
3725
+ className: "dcu-icon",
3726
+ "aria-label": t("sidebar.skills"),
3727
+ onClick: () => {
3728
+ selectExternalSection(t("sidebar.skills"));
3729
+ },
3730
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSkillOutline16, { size: 16 })
3731
+ }),
3732
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3733
+ type: "button",
3734
+ className: "dcu-icon",
3735
+ "aria-label": t("sidebar.plugins"),
3736
+ onClick: () => {
3737
+ selectPluginSection();
3738
+ },
3739
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPersonalizationOutline16, { size: 16 })
3740
+ }),
3741
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3742
+ type: "button",
3743
+ className: "dcu-icon",
3744
+ "aria-label": t("sidebar.connectors"),
3553
3745
  onClick: () => {
3554
- setImTab("tasks");
3746
+ selectSection(t("sidebar.connectors"));
3555
3747
  },
3556
- children: t("sidebar.tasksTab")
3748
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconLinkOutline16, { size: 16 })
3557
3749
  }),
3558
- showChannels && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3750
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3559
3751
  type: "button",
3560
- className: "dcu-im-tab",
3561
- "data-on": imTab === "channels",
3752
+ className: "dcu-icon",
3753
+ "aria-label": t("sidebar.schedule"),
3562
3754
  onClick: () => {
3563
- setImTab("channels");
3755
+ selectExternalSection(t("sidebar.schedule"));
3564
3756
  },
3565
- children: t("sidebar.channelsTab")
3757
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScheduleIcon, {})
3566
3758
  }),
3567
- showSchedule && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3759
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
3568
3760
  type: "button",
3569
- className: "dcu-im-tab",
3570
- "data-on": imTab === "schedule",
3761
+ className: "dcu-icon",
3762
+ "aria-label": t("sidebar.assistant"),
3571
3763
  onClick: () => {
3572
- setImTab("schedule");
3764
+ selectExternalSection([t("sidebar.imSettings"), "IM助理"]);
3573
3765
  },
3574
- children: t("sidebar.scheduleTab")
3766
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ImAssistantIcon, {})
3575
3767
  })
3576
3768
  ]
3577
- }), imTab === "channels" && showChannels ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3578
- className: "dcu-native-workspaces",
3579
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChannelBrowser, {
3580
- openSession,
3581
- archiveSession,
3582
- deleteSession,
3583
- forkSession,
3584
- renameSession,
3585
- useSessions,
3586
- t
3587
- })
3588
- }) : imTab === "schedule" && showSchedule ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3589
- className: "dcu-native-workspaces",
3590
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ScheduleBrowser, {
3591
- openSession,
3592
- archiveSession,
3593
- deleteSession,
3594
- forkSession,
3595
- renameSession,
3596
- useSessions,
3597
- useWorkspaces,
3598
- t
3599
- })
3600
- }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3601
- className: "dcu-native-workspaces",
3602
- children: renderSlot("sidebar.workspaces", {
3603
- wide: true,
3604
- expandSidebar: toggleSidebar
3605
- })
3606
3769
  })]
3607
3770
  }),
3608
3771
  /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("footer", {
3609
3772
  className: "dcu-foot",
3610
3773
  children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3611
3774
  className: "dcu-footer-actions",
3612
- children: renderSlot("sidebar.footer.action", { wide: true })
3775
+ children: renderSlot("sidebar.footer.action", { wide: !visualCompact })
3613
3776
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3614
3777
  ref: settingsSeat,
3615
3778
  className: "dcu-settings-seat",
3616
- children: renderSlot("sidebar.settings", { wide: true })
3779
+ children: renderSlot("sidebar.settings", { wide: !visualCompact })
3617
3780
  })]
3618
3781
  }),
3619
- searchOpen && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3620
- className: "dcu-search-scrim",
3621
- onMouseDown: (event) => {
3622
- if (event.target === event.currentTarget) closeSearch();
3623
- },
3624
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3625
- className: "dcu-search-dialog",
3626
- role: "dialog",
3627
- "aria-modal": "true",
3628
- "aria-label": t("sidebar.search"),
3629
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3630
- className: "dcu-search-input",
3631
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
3632
- autoFocus: true,
3633
- icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconSearchOutline16, { size: 16 }),
3634
- value: searchQuery,
3635
- placeholder: t("search.placeholder"),
3636
- onChange: (event) => {
3637
- setSearchQuery(event.target.value);
3638
- }
3639
- })
3640
- }), searchResults.length === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3641
- className: "dcu-search-empty",
3642
- children: t("search.empty")
3643
- }) : [
3644
- "sessions",
3645
- "settings",
3646
- "actions"
3647
- ].map((group) => {
3648
- const entries = searchResults.filter((entry) => entry.group === group);
3649
- if (entries.length === 0) return null;
3650
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("section", {
3651
- className: "dcu-search-section",
3652
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
3653
- className: "dcu-search-title",
3654
- children: t(`search.${group}`)
3655
- }), entries.map((entry) => {
3656
- const index = searchResults.indexOf(entry);
3657
- return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("button", {
3658
- type: "button",
3659
- className: "dcu-search-row",
3660
- "data-active": index === activeSearchIndex,
3661
- onMouseEnter: () => {
3662
- setActiveSearchIndex(index);
3663
- },
3664
- onClick: entry.run,
3665
- children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3666
- className: "dcu-search-main",
3667
- children: entry.label
3668
- }), entry.detail !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3669
- className: "dcu-search-detail",
3670
- children: entry.detail
3671
- })]
3672
- }, entry.id);
3673
- })]
3674
- }, group);
3675
- })]
3676
- })
3782
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SidebarSearch, {
3783
+ ref: search,
3784
+ settingsSeat,
3785
+ openSession,
3786
+ startSession,
3787
+ t,
3788
+ useSessions,
3789
+ useWorkspaces
3677
3790
  })
3678
3791
  ]
3679
3792
  });