@michengai/dsh-codex-ui 1.1.8 → 1.1.9

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/CHANGELOG.md CHANGED
@@ -4,6 +4,32 @@
4
4
 
5
5
  This changelog records recent releases of DSH Codex UI and its one-click installer. Earlier changes remain available in the [Git history](https://github.com/MichengAI/dsh-codex-ui/commits/main).
6
6
 
7
+ ## 1.1.9 - 2026-09-16
8
+
9
+ - Session title type words follow the Chinese or English UI locale.
10
+ - Hide Delete conversation when archive delete is unavailable.
11
+ - Changing the current session expands its project folder or Recent.
12
+ - The workspace tree uses official open and closed folder glyphs, and the running indicator aligns with project titles.
13
+ - Moving a session to another project works on DSH 0.1.6. A missing artifact is reported as not found, and leftover generation files get their working directory rewritten.
14
+
15
+ ## suite-installer-v1.0.11 - 2026-09-15
16
+
17
+ Install or maintain 11 first-party plugins in one step. Included plugins and versions:
18
+
19
+ - `@michengai/dsh-archive-manager@0.1.42`
20
+ - `@michengai/dsh-codex-ui@1.1.8`
21
+ - `@michengai/dsh-skills-manager@0.1.50`
22
+ - `@michengai/dsh-agency-agents@0.1.42`
23
+ - `@michengai/dsh-im-connect@0.1.49`
24
+ - `@michengai/dsh-automation@0.1.42`
25
+ - `@michengai/dsh-btw@0.1.7`
26
+ - `@michengai/dsh-simplify@0.1.4`
27
+ - `@michengai/dsh-pua@0.3.11`
28
+ - `@michengai/dsh-code-review@0.1.0`
29
+ - `@michengai/dsh-codex-pet@0.1.5`
30
+
31
+ The installer uses these exact versions for reproducible installation.
32
+
7
33
  ## 1.1.8 - 2026-09-15
8
34
 
9
35
  - After the first user message, new chats are titled once as emoji, type, and theme, for example `⚡ 优化|批次文字显示`. Dates are not written.
@@ -4,6 +4,32 @@
4
4
 
5
5
  本日志记录 DSH Codex UI 及其一键安装器的最近发布;更早的变更可查看 [Git 提交历史](https://github.com/MichengAI/dsh-codex-ui/commits/main)。
6
6
 
7
+ ## 1.1.9 - 2026-09-16
8
+
9
+ - 会话标题的类型词跟随中英界面语言。
10
+ - 未安装归档删除能力时不再显示「删除会话」。
11
+ - 切换当前会话时,自动展开所属项目或「最近」。
12
+ - 工作区树改用官方打开/闭合文件夹图标,运行指示与项目标题对齐。
13
+ - 会话跨项目移动兼容 DSH 0.1.6;磁盘上没有工件时返回不存在,双代际目录会一并改写旧代际的工作目录。
14
+
15
+ ## suite-installer-v1.0.11 - 2026-09-15
16
+
17
+ 一键维护安装 11 个自研插件。包含以下插件及版本:
18
+
19
+ - `@michengai/dsh-archive-manager@0.1.42`
20
+ - `@michengai/dsh-codex-ui@1.1.8`
21
+ - `@michengai/dsh-skills-manager@0.1.50`
22
+ - `@michengai/dsh-agency-agents@0.1.42`
23
+ - `@michengai/dsh-im-connect@0.1.49`
24
+ - `@michengai/dsh-automation@0.1.42`
25
+ - `@michengai/dsh-btw@0.1.7`
26
+ - `@michengai/dsh-simplify@0.1.4`
27
+ - `@michengai/dsh-pua@0.3.11`
28
+ - `@michengai/dsh-code-review@0.1.0`
29
+ - `@michengai/dsh-codex-pet@0.1.5`
30
+
31
+ 安装器使用这些精确版本执行安装,确保可复现。
32
+
7
33
  ## 1.1.8 - 2026-09-15
8
34
 
9
35
  - 新会话在第一条用户消息后,按「表情 + 类型|主题」自动命名一次,例如「⚡ 优化|批次文字显示」。不再写入日期。
package/lib/client.js CHANGED
@@ -1366,7 +1366,8 @@ window.__ModuleLoader__.load({
1366
1366
  label: t("sessions.copyPath"),
1367
1367
  icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCopyOutline16, { size: 16 }),
1368
1368
  disabled: options.path === void 0
1369
- }] : [], {
1369
+ }] : []);
1370
+ if (options.canDelete !== false) items.push({
1370
1371
  type: "separator",
1371
1372
  id: "delete-separator"
1372
1373
  }, {
@@ -1417,6 +1418,7 @@ window.__ModuleLoader__.load({
1417
1418
  }
1418
1419
  function SessionRow({ id, title, selected, menuOpen, unread, running, pendingInteraction, t, menuItems, onOpen, onMenuChange, onSelectAction, onArchive, onHover, onLeave, onContextMenu, menuPoint, subtitle, flat, draggable, dropActive, onDragStart, onDragEnd, onDragOver, onDrop }) {
1419
1420
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
1421
+ "data-dcu-session": id,
1420
1422
  className: `dcu-wb-session${selected ? " dcu-wb-selected" : ""}${menuOpen ? " dcu-wb-menu-open" : ""}${dropActive === true ? " dcu-wb-drop" : ""}${flat === true ? " dcu-wb-session-flat" : ""}`,
1421
1423
  role: "treeitem",
1422
1424
  "aria-selected": selected,
@@ -2471,6 +2473,32 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
2471
2473
  else if (target.hasGroups) next["workspace-group:ungrouped"] = true;
2472
2474
  return next;
2473
2475
  }
2476
+ function workspaceIdForSession(workspaces, sessionId) {
2477
+ return workspaces.find((workspace) => workspace.sessionIds.some((id) => String(id) === sessionId))?.workspaceId;
2478
+ }
2479
+ /** 打开或闭合只跟展开状态走;当前会话所在项目额外使用当前色。 */
2480
+ function projectFolderPresentation(isExpanded, containsCurrent) {
2481
+ return {
2482
+ open: isExpanded,
2483
+ current: containsCurrent
2484
+ };
2485
+ }
2486
+ /** 当前会话变化时展开所属项目或「最近」;会话尚未进入树则保持原展开状态。 */
2487
+ function expandedForCurrentSession(current, sessionId, tree) {
2488
+ if (sessionId === void 0 || sessionId === "") return { ...current };
2489
+ const workspaceId = workspaceIdForSession(tree.workspaces, sessionId);
2490
+ if (workspaceId !== void 0) return expandedForSessionMove(current, {
2491
+ workspaceId: String(workspaceId),
2492
+ pinned: tree.pinnedWorkspaceIds.includes(String(workspaceId)),
2493
+ groupId: tree.groups.find((group) => group.workspaceIds.includes(String(workspaceId)))?.id,
2494
+ hasGroups: tree.groups.length > 0
2495
+ });
2496
+ if (tree.recentIds.includes(sessionId)) return {
2497
+ ...current,
2498
+ "section:recent": true
2499
+ };
2500
+ return { ...current };
2501
+ }
2474
2502
  /** 仅提供真正改变归属的目标;未分组目标固定排在自定义分组之后。 */
2475
2503
  function workspaceGroupMoveTargets(groups, workspaceId) {
2476
2504
  const currentGroupId = groups.find((group) => group.workspaceIds.includes(workspaceId))?.id;
@@ -2846,6 +2874,9 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
2846
2874
  strokeWidth: 1.5
2847
2875
  });
2848
2876
  }
2877
+ function CreateGroupIcon() {
2878
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconProjectAddOutline16, { size: 16 });
2879
+ }
2849
2880
  /** 使用独立节点生成稳定的拖拽预览,避免浏览器把目标高亮和操作按钮截入默认快照。 */
2850
2881
  function setDragPreview(dataTransfer, title, icon) {
2851
2882
  const preview = document.createElement("div");
@@ -2969,15 +3000,15 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
2969
3000
  .dcu-wb-project-head[draggable=true],.dcu-wb-session[draggable=true]{cursor:grab}
2970
3001
  .dcu-wb-project-head[draggable=true]:active,.dcu-wb-session[draggable=true]:active{cursor:grabbing}
2971
3002
  .dcu-wb-section,.dcu-wb-section:focus,.dcu-wb-section:focus-visible,.dcu-wb-project-head:focus,.dcu-wb-session:focus{outline:0}.dcu-wb-pin-end,.dcu-wb-pin-start{position:relative;height:8px}.dcu-wb-project.dcu-wb-drop::before,.dcu-wb-session.dcu-wb-drop::before,.dcu-wb-pin-end.dcu-wb-drop::before,.dcu-wb-pin-start.dcu-wb-drop::before{content:"";position:absolute;z-index:2;left:7px;right:8px;top:-8px;height:8px;pointer-events:none;background:radial-gradient(circle at 4px 50%,transparent 1.75px,var(--dsw-alias-state-business-primary) 2px 3.75px,transparent 4px),linear-gradient(var(--dsw-alias-state-business-primary),var(--dsw-alias-state-business-primary)) 10px 50%/calc(100% - 10px) 2px no-repeat}.dcu-wb-pin-start.dcu-wb-drop::before{top:0}.dcu-wb-pinned-list>.dcu-wb-project:first-child.dcu-wb-drop::before{top:-4px}.dcu-wb-project.dcu-wb-drop-after::before,.dcu-wb-session.dcu-wb-drop-after::before{top:auto;bottom:-8px}.dcu-wb-dragging{opacity:.28}.dcu-wb-drag-ghost{position:fixed;top:0;left:0;transform:translate(-200vw,-200vh);z-index:10040;display:flex;align-items:center;gap:8px;max-width:220px;height:30px;padding:0 10px;border:1px solid var(--dcu-sidebar-border);border-radius:8px;background:var(--dcu-sidebar-hover);box-shadow:0 4px 12px rgba(0,0,0,.24);color:var(--dcu-sidebar-primary);font:14px/20px var(--dcu-font,inherit);white-space:nowrap;pointer-events:none}.dcu-wb-drag-ghost-icon{display:grid;place-items:center;flex:none;width:16px;height:16px;color:var(--dcu-sidebar-icon)}.dcu-wb-drag-ghost-icon svg{display:block;width:16px;height:16px}.dcu-wb-drag-ghost-title{min-width:0;overflow:hidden;text-overflow:ellipsis}
2972
- .dcu-wb-folder{display:grid;place-items:center;flex:none;width:16px;height:20px;color:var(--dcu-sidebar-icon)}.dcu-wb-brand{display:block;width:16px;height:16px}
3003
+ .dcu-wb-folder{display:grid;place-items:center;flex:none;width:16px;height:20px;color:var(--dcu-sidebar-icon)}.dcu-wb-folder.dcu-wb-folder-current{color:var(--dsw-alias-state-business-primary)}.dcu-wb-brand{display:block;width:16px;height:16px}
2973
3004
  .dcu-wb-project-title,.dcu-wb-session-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px;line-height:20px}
2974
3005
  .dcu-wb-project-title{flex:1;font-weight:400;color:var(--dcu-sidebar-primary)}
2975
- .dcu-wb-session{position:relative;min-width:0;min-height:30px;gap:0;overflow:hidden;padding-left:28px;padding-right:28px}
2976
- .dcu-wb-session-title{flex:1;margin-left:0}.dcu-wb-session-copy{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center}.dcu-wb-session-sub{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dcu-sidebar-tertiary);font-size:12px;line-height:16px}.dcu-wb-session-flat,.dcu-wb-session-top{padding-left:8px}
3006
+ .dcu-wb-session{position:relative;min-width:0;min-height:30px;gap:0;overflow:hidden;padding-left:30px;padding-right:28px}
3007
+ .dcu-wb-session-title{flex:1;margin-left:0}.dcu-wb-session-copy{flex:1;min-width:0;display:flex;flex-direction:column;justify-content:center}.dcu-wb-session-sub{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--dcu-sidebar-tertiary);font-size:12px;line-height:16px}.dcu-wb-session-flat,.dcu-wb-session-top{padding-left:8px}.dcu-wb-session-flat:has(.dcu-wb-running),.dcu-wb-session-top:has(.dcu-wb-running){padding-left:30px}
2977
3008
  .dcu-wb-actions{display:none;align-items:center;gap:8px;flex:none}
2978
3009
  .dcu-wb-quick-actions{position:absolute;right:8px;top:50%;display:flex;align-items:center;gap:2px;opacity:0;pointer-events:none;transform:translateY(-50%);background:var(--dcu-sidebar-hover);border-radius:6px}
2979
3010
  .dcu-wb-project-head:hover .dcu-wb-actions,.dcu-wb-project-head.dcu-wb-menu-open .dcu-wb-actions,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-actions{display:flex}
2980
- .dcu-wb-session:hover .dcu-wb-quick-actions,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-quick-actions{opacity:1;pointer-events:auto}.dcu-wb-session:hover .dcu-wb-running,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-running,.dcu-wb-session:hover .dcu-wb-pending,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-pending,.dcu-wb-session:hover .dcu-wb-unread,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-unread{visibility:hidden}
3011
+ .dcu-wb-session:hover .dcu-wb-quick-actions,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-quick-actions{opacity:1;pointer-events:auto}.dcu-wb-session:hover .dcu-wb-pending,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-pending,.dcu-wb-session:hover .dcu-wb-unread,.dcu-wb-session.dcu-wb-menu-open .dcu-wb-unread{visibility:hidden}
2981
3012
  .dcu-wb-more{display:grid;place-items:center;width:20px;height:20px;border:0;border-radius:4px;padding:0;background:transparent;color:var(--dcu-sidebar-tertiary);cursor:pointer}
2982
3013
  .dcu-wb-more:hover{color:var(--dcu-sidebar-primary)}
2983
3014
  .dcu-wb-context-anchor{opacity:0;pointer-events:none}
@@ -2995,7 +3026,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
2995
3026
  .dcu-wb-rename-input:hover{border-color:color-mix(in srgb,var(--dsw-alias-label-primary) 32%,var(--dsw-alias-border-l2))}
2996
3027
  .dcu-wb-rename-input:focus{border-color:var(--dsw-alias-state-business-primary);box-shadow:0 0 0 1px color-mix(in srgb,var(--dsw-alias-state-business-primary) 28%,transparent)}
2997
3028
  `;
2998
- const runningStyles = `.dcu-wb-running{position:absolute;right:10px;top:50%;flex:none;width:12px;height:12px;margin-top:-6px;border:2px solid color-mix(in srgb,var(--dcu-sidebar-secondary) 25%,transparent);border-top-color:var(--dcu-sidebar-secondary);border-radius:50%;animation:dcu-wb-spin .8s linear infinite}@keyframes dcu-wb-spin{to{transform:rotate(360deg)}}@media (prefers-reduced-motion:reduce){.dcu-wb-running{animation:none}}`;
3029
+ const runningStyles = `.dcu-wb-running{position:absolute;left:8px;top:50%;display:grid;place-items:center;flex:none;width:16px;height:20px;margin-top:-10px;border:0;background:transparent}.dcu-wb-running::after{content:"";box-sizing:border-box;width:12px;height:12px;border:2px solid color-mix(in srgb,var(--dcu-sidebar-secondary) 25%,transparent);border-top-color:var(--dcu-sidebar-secondary);border-radius:50%;animation:dcu-wb-spin .8s linear infinite}@keyframes dcu-wb-spin{to{transform:rotate(360deg)}}@media (prefers-reduced-motion:reduce){.dcu-wb-running::after{animation:none}}`;
2999
3030
  const typographyStyles = `.dcu-wb{--dcu-wb-disclosure-duration:180ms;--dcu-wb-disclosure-ease:cubic-bezier(.16,1,.3,1);font:14px/20px var(--dcu-font,var(--dsw-font-family))}.dcu-wb-section-label{color:var(--dcu-sidebar-secondary);font:13px/20px var(--dcu-font,var(--dsw-font-family));font-weight:400;letter-spacing:0;padding-left:0}.dcu-wb-section-caret{transition:opacity var(--dcu-wb-disclosure-duration) var(--dcu-wb-disclosure-ease),transform var(--dcu-wb-disclosure-duration) var(--dcu-wb-disclosure-ease)}.dcu-wb-section-head .dcu-wb-section-caret{position:static;left:auto;top:auto;opacity:.78}.dcu-wb-section-body,.dcu-wb-project-body,.dcu-wb-collection-body{display:block;min-height:0;height:auto;overflow:clip;opacity:1;transform:none;visibility:visible}.dcu-wb-section-body[data-open=false],.dcu-wb-project-body[data-open=false],.dcu-wb-collection-body[data-open=false]{display:block;height:0;opacity:0;transform:translateY(-2px);pointer-events:none}.dcu-wb-section-body[data-open=true]:has(.dcu-wb-drop),.dcu-wb-project-body[data-open=true]:has(.dcu-wb-drop),.dcu-wb-collection-body[data-open=true]:has(.dcu-wb-drop){overflow:visible}.dcu-wb-section-body[data-open=true]>div{animation:none}@media (prefers-reduced-motion:reduce){.dcu-wb-section-caret{transition:none}}.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}`;
3000
3031
  const collectionLayoutStyles = `
3001
3032
  .dcu-wb-tree{position:relative}
@@ -3010,7 +3041,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3010
3041
  .dcu-wb-collection-body .dcu-wb-project-head{padding-left:8px}
3011
3042
  .dcu-wb-collection-body>.dcu-wb-empty{padding:8px 8px 8px 26px}
3012
3043
  .dcu-wb-collection-body>.dcu-wb-empty,.dcu-wb-nochat{font-size:13px;line-height:18px;color:var(--dcu-sidebar-tertiary)}
3013
- .dcu-wb-nochat{padding:1px 8px 5px 28px}
3044
+ .dcu-wb-nochat{padding:1px 8px 5px 30px}
3014
3045
  .dcu-wb-collection:has(+.dcu-wb-collection)>.dcu-wb-collection-body>.dcu-wb-empty,.dcu-wb-collection:has(+.dcu-wb-ungrouped)>.dcu-wb-collection-body>.dcu-wb-empty{padding-top:14px;padding-bottom:2px}
3015
3046
  .dcu-wb-collection-body::before,.dcu-wb-group-member::after{display:none}
3016
3047
  .dcu-wb-collections{gap:12px}
@@ -3046,7 +3077,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3046
3077
  function CodexWorkspaceBrowser(props) {
3047
3078
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(HoverShell, { children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodexWorkspaceTree, { ...props }) });
3048
3079
  }
3049
- function CodexWorkspaceTree({ wide, useSessions, useSessionPendingInteraction, useWorkspaces, t, archiveSession, deleteSession, deleteWorkspace, forkSession, insertSessionBefore, insertWorkspaceBefore, moveSession, openPath, openSession, renameSession, renameWorkspace, startSession }) {
3080
+ function CodexWorkspaceTree({ wide, useSessions, useSessionPendingInteraction, useWorkspaces, t, archiveSession, deleteSession, deleteWorkspace, forkSession, insertSessionBefore, insertWorkspaceBefore, moveSession, openPath, openSession, renameSession, renameWorkspace, startSession, canDeleteSession }) {
3050
3081
  const sessions = useSessions((state) => state);
3051
3082
  const pendingInteractions = (useSessionPendingInteraction ?? useEmptySessionPendingInteraction)((state) => state);
3052
3083
  const workspaces = useWorkspaces((state) => state);
@@ -3156,6 +3187,8 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3156
3187
  const [renameGroupError, setRenameGroupError] = (0, react.useState)();
3157
3188
  const groupActionTriggerRef = (0, react.useRef)();
3158
3189
  const projectsSectionButtonRef = (0, react.useRef)(null);
3190
+ const lastRevealedSessionIdRef = (0, react.useRef)();
3191
+ const pendingRevealScrollRef = (0, react.useRef)(false);
3159
3192
  (0, react.useEffect)(() => {
3160
3193
  writeTreeExpansionState(storage$1(), WORKSPACE_EXPANSION_STORAGE_KEY, expanded);
3161
3194
  }, [expanded]);
@@ -3539,6 +3572,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3539
3572
  setMenu(void 0);
3540
3573
  }
3541
3574
  };
3575
+ const canDelete = canDeleteSession?.() === true;
3542
3576
  const sessionMenu = (sessionId, path) => sessionMenuItems(t, {
3543
3577
  unread: unreadSessionIds.includes(sessionId),
3544
3578
  path,
@@ -3546,7 +3580,8 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3546
3580
  moveTargets: sessionMoveTargets(groups.items, sessionId).map((target) => ({
3547
3581
  ...target,
3548
3582
  id: moveSessionActionId(target.id)
3549
- }))
3583
+ })),
3584
+ canDelete
3550
3585
  });
3551
3586
  const requestSessionMove = (sessionId, targetWorkspaceId) => {
3552
3587
  const targetWorkspace = groups.items.find((workspace) => String(workspace.workspaceId) === targetWorkspaceId);
@@ -3594,6 +3629,8 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3594
3629
  const renderGroup = (workspace, zone) => {
3595
3630
  const expandKey = zone === "pinned" ? `pin:${workspace.workspaceId}` : String(workspace.workspaceId);
3596
3631
  const isExpanded = expanded[expandKey] ?? true;
3632
+ const currentSessionId = sessions.current === void 0 ? void 0 : String(sessions.current);
3633
+ const folder = projectFolderPresentation(isExpanded, workspace.visibleIds.some((id) => id === currentSessionId));
3597
3634
  const shownIds = workspace.visibleIds;
3598
3635
  const menuOpen = menu?.type === "workspace" && menu.id === workspace.workspaceId;
3599
3636
  const menuAt = menuOpen && menu.x !== void 0 && menu.y !== void 0 ? {
@@ -3735,7 +3772,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3735
3772
  },
3736
3773
  children: [
3737
3774
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3738
- className: "dcu-wb-folder",
3775
+ className: `dcu-wb-folder${folder.current ? " dcu-wb-folder-current" : ""}`,
3739
3776
  onClick: (event) => {
3740
3777
  event.stopPropagation();
3741
3778
  const box = hoverCardAnchor(event.currentTarget.getBoundingClientRect());
@@ -3755,7 +3792,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3755
3792
  top: box.top
3756
3793
  }, { immediate: true });
3757
3794
  },
3758
- children: isExpanded ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFolderOpenOutline16, { size: 16 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFolderClose16, { size: 16 })
3795
+ children: folder.open ? folder.current ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFolderOpen16, { size: 16 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFolderOpenOutline16, { size: 16 }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconFolderClose16, { size: 16 })
3759
3796
  }),
3760
3797
  /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
3761
3798
  className: "dcu-wb-project-title",
@@ -3826,6 +3863,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
3826
3863
  const dropsBeforeSession = sessionDropTarget?.workspaceId === workspaceId && sessionDropTarget.ontoProject !== true && sessionDropTarget.beforeId === id;
3827
3864
  const dropsAfterLastSession = sessionDropTarget?.workspaceId === workspaceId && sessionDropTarget.ontoProject !== true && sessionDropTarget.beforeId === void 0 && shownIds[shownIds.length - 1] === id;
3828
3865
  return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
3866
+ "data-dcu-session": id,
3829
3867
  className: `dcu-wb-session${selected ? " dcu-wb-selected" : ""}${sessionMenuOpen ? " dcu-wb-menu-open" : ""}${dropsBeforeSession ? " dcu-wb-drop" : ""}${dropsAfterLastSession ? " dcu-wb-drop dcu-wb-drop-after" : ""}`,
3830
3868
  role: "treeitem",
3831
3869
  "aria-selected": selected,
@@ -4372,6 +4410,37 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
4372
4410
  if (!wide || !sorting || treeRef.current === null) return;
4373
4411
  return mountWorkspaceDropIndicator(treeRef.current);
4374
4412
  }, [wide, sorting]);
4413
+ (0, react.useEffect)(() => {
4414
+ const current = sessions.current === void 0 ? void 0 : String(sessions.current);
4415
+ if (current === void 0 || lastRevealedSessionIdRef.current === current) return;
4416
+ const tree = {
4417
+ workspaces: workspaces.items.map((item) => ({
4418
+ workspaceId: String(item.workspaceId),
4419
+ sessionIds: item.sessionIds.map((id) => String(id))
4420
+ })),
4421
+ pinnedWorkspaceIds,
4422
+ groups: workspaceGroups.map((group) => ({
4423
+ id: group.id,
4424
+ workspaceIds: group.workspaceIds
4425
+ })),
4426
+ recentIds
4427
+ };
4428
+ if (!(tree.workspaces.some((item) => item.sessionIds.includes(current)) || tree.recentIds.includes(current))) return;
4429
+ lastRevealedSessionIdRef.current = current;
4430
+ pendingRevealScrollRef.current = true;
4431
+ setExpanded((currentExpanded) => expandedForCurrentSession(currentExpanded, current, tree));
4432
+ }, [
4433
+ pinnedWorkspaceIds,
4434
+ recentIds,
4435
+ sessions.current,
4436
+ workspaceGroups,
4437
+ workspaces.items
4438
+ ]);
4439
+ (0, react.useLayoutEffect)(() => {
4440
+ if (!pendingRevealScrollRef.current) return;
4441
+ pendingRevealScrollRef.current = false;
4442
+ treeRef.current?.querySelector(".dcu-wb-session.dcu-wb-selected")?.scrollIntoView?.({ block: "nearest" });
4443
+ }, [expanded]);
4375
4444
  if (!wide) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
4376
4445
  className: "dcu-wb dcu-wb-rail",
4377
4446
  children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("style", { children: stylesheet$4 })
@@ -4546,7 +4615,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
4546
4615
  setError(void 0);
4547
4616
  setCreateGroupOpen(true);
4548
4617
  },
4549
- children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconPlusOutline16, { size: 16 })
4618
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CreateGroupIcon, {})
4550
4619
  })
4551
4620
  })]
4552
4621
  }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
@@ -5308,7 +5377,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
5308
5377
  })
5309
5378
  });
5310
5379
  }
5311
- function ChannelBrowserTree({ openSession, archiveSession, deleteSession, forkSession, moveSession, renameSession, useSessions, useSessionPendingInteraction, useWorkspaces, t, menu, setMenu }) {
5380
+ function ChannelBrowserTree({ openSession, archiveSession, deleteSession, forkSession, moveSession, renameSession, useSessions, useSessionPendingInteraction, useWorkspaces, t, canDeleteSession, menu, setMenu }) {
5312
5381
  const sessions = useSessions((state) => state);
5313
5382
  const workspaces = useWorkspaces?.((state) => state);
5314
5383
  const pendingInteractions = (useSessionPendingInteraction ?? useEmptySessionPendingInteraction)((state) => state);
@@ -5420,6 +5489,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
5420
5489
  ...target,
5421
5490
  id: moveSessionActionId(target.id)
5422
5491
  }));
5492
+ const canDelete = canDeleteSession?.() === true;
5423
5493
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionRow, {
5424
5494
  id,
5425
5495
  title,
@@ -5431,7 +5501,8 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
5431
5501
  t,
5432
5502
  menuItems: sessionMenuItems(t, {
5433
5503
  unread,
5434
- moveTargets
5504
+ moveTargets,
5505
+ canDelete
5435
5506
  }),
5436
5507
  menuPoint: menu?.id === id && menu.x !== void 0 && menu.y !== void 0 ? {
5437
5508
  x: menu.x,
@@ -5580,7 +5651,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
5580
5651
  })]
5581
5652
  });
5582
5653
  }
5583
- function ScheduleBrowserTree({ openSession, archiveSession, deleteSession, forkSession, moveSession, renameSession, useSessions, useSessionPendingInteraction, useWorkspaces, t, openTaskSettings, menu, setMenu }) {
5654
+ function ScheduleBrowserTree({ openSession, archiveSession, deleteSession, forkSession, moveSession, renameSession, useSessions, useSessionPendingInteraction, useWorkspaces, t, canDeleteSession, openTaskSettings, menu, setMenu }) {
5584
5655
  const sessions = useSessions((state) => state);
5585
5656
  const pendingInteractions = (useSessionPendingInteraction ?? useEmptySessionPendingInteraction)((state) => state);
5586
5657
  const workspaces = useWorkspaces((state) => state);
@@ -5722,6 +5793,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
5722
5793
  ...target,
5723
5794
  id: moveSessionActionId(target.id)
5724
5795
  }));
5796
+ const canDelete = canDeleteSession?.() === true;
5725
5797
  return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionRow, {
5726
5798
  id,
5727
5799
  title,
@@ -5733,7 +5805,8 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
5733
5805
  t,
5734
5806
  menuItems: sessionMenuItems(t, {
5735
5807
  unread,
5736
- moveTargets
5808
+ moveTargets,
5809
+ canDelete
5737
5810
  }),
5738
5811
  menuPoint: menu?.id === id && menu.x !== void 0 && menu.y !== void 0 ? {
5739
5812
  x: menu.x,
@@ -6760,7 +6833,7 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
6760
6833
  });
6761
6834
  });
6762
6835
  /** Codex 风格的 DSH 侧栏,只替换导航外观,项目浏览和设置仍由 DSH 官方组件提供。 */
6763
- function CodexSidebar({ globalPanels, selectPanel, usePanelInfo = useLegacyPanelInfo, collapsed, width, openSession, startSession, toggleSidebar, archiveSession, deleteSession, forkSession, moveSession, renameSession, openPath, companionSlots, renderSlot, t, useSessions, useSessionPendingInteraction, useWorkspaces, prefillNewConversation, newConversationDraft }) {
6836
+ function CodexSidebar({ globalPanels, selectPanel, usePanelInfo = useLegacyPanelInfo, collapsed, width, openSession, startSession, toggleSidebar, archiveSession, canDeleteSession, deleteSession, forkSession, moveSession, renameSession, openPath, companionSlots, renderSlot, t, useSessions, useSessionPendingInteraction, useWorkspaces, prefillNewConversation, newConversationDraft }) {
6764
6837
  const panels = (0, react.useSyncExternalStore)(globalPanels?.subscribe ?? subscribeEmptyCompanionTabs, globalPanels?.getSnapshot ?? getEmptyPanels, globalPanels?.getSnapshot ?? getEmptyPanels);
6765
6838
  const activePanelId = usePanelInfo((info) => info.activePanelId);
6766
6839
  const panelButtons = (wide) => selectPanel === void 0 ? null : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(GlobalPanelButtons, {
@@ -7122,6 +7195,7 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
7122
7195
  openSession,
7123
7196
  archiveSession,
7124
7197
  deleteSession,
7198
+ canDeleteSession,
7125
7199
  forkSession,
7126
7200
  moveSession,
7127
7201
  renameSession,
@@ -7136,6 +7210,7 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
7136
7210
  openSession,
7137
7211
  archiveSession,
7138
7212
  deleteSession,
7213
+ canDeleteSession,
7139
7214
  forkSession,
7140
7215
  moveSession,
7141
7216
  renameSession,
@@ -8179,6 +8254,16 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
8179
8254
  "errors.workspaceInvalid": "项目标识无效。",
8180
8255
  "errors.groupMissing": "目标分组不存在。",
8181
8256
  "errors.orderAnchorMissing": "排序位置已失效,请重试。",
8257
+ "sessionTitle.system": "为编程助手会话生成标题。\n只输出一行,恰好两段:类型|主题\n类型必须是其中一个:{types}\n主题必须是具体事项,不能重复类型,不要写类型名或空主题。不要写日期或表情,不要引号、前缀、解释或 Markdown。\n主题使用用户消息的语言。",
8258
+ "sessionTitle.userFrame": "根据这条用户消息生成会话标题。只返回“类型|主题”一行,不要第三段,不要重复主题。",
8259
+ "sessionTitle.type.feature": "功能",
8260
+ "sessionTitle.type.design": "设计",
8261
+ "sessionTitle.type.fix": "修复",
8262
+ "sessionTitle.type.optimize": "优化",
8263
+ "sessionTitle.type.release": "发布",
8264
+ "sessionTitle.type.explore": "探索",
8265
+ "sessionTitle.type.docs": "文档",
8266
+ "sessionTitle.type.research": "研究",
8182
8267
  "meta.locale": "zh-CN"
8183
8268
  };
8184
8269
  const en = {
@@ -8453,6 +8538,16 @@ html[data-dcu-official-turn-navigator-supported=true] .dcu-turn-navigator,html:h
8453
8538
  "errors.workspaceInvalid": "The project identifier is invalid.",
8454
8539
  "errors.groupMissing": "The target group no longer exists.",
8455
8540
  "errors.orderAnchorMissing": "The target position is no longer available. Try again.",
8541
+ "sessionTitle.system": "Generate a title for a coding-assistant conversation.\nOutput exactly one line with two parts: Type|Theme\nType must be one of: {types}\nThe theme must be a concrete subject and must not repeat the type. Do not write dates, emoji, quotes, prefixes, explanations, or Markdown.\nWrite the theme in the language of the user message.",
8542
+ "sessionTitle.userFrame": "Generate a conversation title from this user message. Return only one Type|Theme line. Do not add a third part or repeat the theme.",
8543
+ "sessionTitle.type.feature": "Feature",
8544
+ "sessionTitle.type.design": "Design",
8545
+ "sessionTitle.type.fix": "Fix",
8546
+ "sessionTitle.type.optimize": "Optimize",
8547
+ "sessionTitle.type.release": "Release",
8548
+ "sessionTitle.type.explore": "Explore",
8549
+ "sessionTitle.type.docs": "Docs",
8550
+ "sessionTitle.type.research": "Research",
8456
8551
  "meta.locale": "en-US"
8457
8552
  };
8458
8553
  //#endregion
@@ -10127,6 +10222,12 @@ html[data-dsh-native-backdrop=mica] .dcu-settings-page,html[data-dsh-native-back
10127
10222
  return "ready";
10128
10223
  }
10129
10224
  //#endregion
10225
+ //#region src/client/archive-session-delete.ts
10226
+ /** 永久删除会话由归档管理插件通过 remote.workspaceRegistry.deleteSession 提供。 */
10227
+ function hasArchiveSessionDelete(value) {
10228
+ return value !== null && typeof value === "object" && typeof value.deleteSession === "function";
10229
+ }
10230
+ //#endregion
10130
10231
  //#region src/client/index.ts
10131
10232
  const inject = [
10132
10233
  "slots",
@@ -10139,7 +10240,7 @@ html[data-dsh-native-backdrop=mica] .dcu-settings-page,html[data-dsh-native-back
10139
10240
  "conversation"
10140
10241
  ];
10141
10242
  function hasDeleteSession(value) {
10142
- return value !== null && typeof value === "object" && "deleteSession" in value && typeof value.deleteSession === "function";
10243
+ return hasArchiveSessionDelete(value);
10143
10244
  }
10144
10245
  async function runHostAction(action, execute) {
10145
10246
  try {
@@ -10239,6 +10340,7 @@ html[data-dsh-native-backdrop=mica] .dcu-settings-page,html[data-dsh-native-back
10239
10340
  ctx.layout.toggleSidebar();
10240
10341
  },
10241
10342
  archiveSession,
10343
+ canDeleteSession: () => hasArchiveSessionDelete(ctx.get("remote.workspaceRegistry")),
10242
10344
  deleteSession,
10243
10345
  forkSession,
10244
10346
  moveSession,
@@ -10326,6 +10428,7 @@ html[data-dsh-native-backdrop=mica] .dcu-settings-page,html[data-dsh-native-back
10326
10428
  locale: NS,
10327
10429
  inject: () => ({
10328
10430
  archiveSession,
10431
+ canDeleteSession: () => hasArchiveSessionDelete(ctx.get("remote.workspaceRegistry")),
10329
10432
  deleteSession,
10330
10433
  deleteWorkspace: (workspaceId) => ctx.workspaces.delete(workspaceId),
10331
10434
  forkSession,