dsh-session-manager 0.7.3 → 0.7.5

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
@@ -2,6 +2,26 @@
2
2
 
3
3
  All notable changes to this project will be documented in this file.
4
4
 
5
+ ## 0.7.5 — 2026-10-22
6
+
7
+ - **fix(security)**: Enforce centralized API authentication on all `/session-manager/api/*` routes using DSH official `ctx.connection.admit(req)`. Enforce strict Owner-only authorization (`peer.principal.kind === "owner"`), reject untrusted, unauthenticated, empty, or non-owner requests before body reading and database queries, and fail closed with HTTP 503 (`auth-unavailable`) if connection service is missing or unready, preventing unauthorized access across public tunnels, reverse proxies, and local networks (#43).
8
+ - **fix(move)**: Synchronize the effective `workingDirectory` projection upon moving sessions across workspaces. For active sessions, call official `workingDirectory.set(agent, path)` when active or fall back to appending `working-directory/change` events to fold the projection in real time, and flush to disk via projection cache; for cold sessions, rewrite headers when un-diverged or append change events for sequential logs. For unmigrated packed rows with conflicting historical working-directory events, safely refuse moves with HTTP 409 (`working-directory-sync-unsafe`) before any file write to prevent destination directory drift upon restart (#42).
9
+ - **fix(ui)**: Align session header action buttons with native DSH session title bar style: unify height to 28px, remove idle border and background (transparent ghost buttons), add standard 6px border-radius, use official hover and active tokens, style danger buttons cleanly, and replace raw Unicode emojis with crisp 14×14 SVG vector icons (#44).
10
+ - **fix(ui)**: Optimize session header and manager panel layout: set header slot order to 0 to sit immediately after static session preset and team entries and before dynamic subagent and task status indicators; switch header action buttons to a fixed-width (flex-shrink: 0, 28px square) icon-only layout with corner priority badge; in session manager panel row actions, convert buttons matching header (archive, favorite, review, edit, move, delete) to clean icon-only buttons with hover tooltips while keeping non-header ("Open", "Migrate") and bulk action buttons with visible text labels (#46).
11
+ - **test**: Add comprehensive test suites for API authentication gating (`issue-43-api-auth.test.mjs`), cross-workspace working directory synchronization (`issue-42-working-directory-after-move.test.mjs`), header action button styling with SVG vector icons (`issue-44-header-styles.test.mjs`), and header/panel row layout optimization (`issue-46-header-layout.test.mjs`).
12
+ - **compat**: Compatible with DSH Desktop v0.2.1-rc.2 (and v0.2.0-rc.2).
13
+
14
+ ## 0.7.4 — 2026-10-20
15
+
16
+ - **fix(workspace)**: Repair workspace session membership on DSH 0.2.x. New and forked sessions are now attributed to the workspace owning their `cwd` as soon as the session is announced (runtime repair, no restart needed), and historical sessions whose `cwd` matches a registered workspace are re-registered on startup — all through the official DSH workspace entity API (#41).
17
+ - **fix(move)**: "Move to workspace" on a session whose `cwd` already equals the target workspace path now repairs the missing membership instead of returning a silent no-op. The response reports whether a membership was written (`attached`); the artifact's content, size and mtime are untouched and running sessions are never restarted (#41).
18
+ - **fix(compat)**: Resolve the DSH home through the official `$DSH_HOME` → `~/.dsh` order (tilde-expanded, absolute) when the `dshHomePath` service is not visible to the plugin scope, so session scans and stores work with a custom DSH home (#41).
19
+ - **fix(workspace)**: Read durable workspace membership from the registry record instead of the runtime-filtered projection when deleting sessions, so stale runtime indexes can no longer leave dead entries behind.
20
+ - **test**: Add regression coverage for runtime new/forked session attribution, boot repair, same-path move repair (including artifact byte/size/mtime invariants), idempotence, cross-workspace moves, cwd mismatch safety, incomplete-scan safety, restart stability, archived-session preservation, and custom DSH home resolution (#41).
21
+ - **compat**: Compatible with DSH Desktop v0.2.1-rc.2 (and v0.2.0-rc.2); workspace membership repair uses the official workspace registry entity API.
22
+ - **fix(safety)**: Workspace membership repair never migrates a session that is already accounted by another workspace: such a conflict is refused with `409 workspace-membership-conflict` and both records stay untouched, because an account removed from a different workspace cannot be restored through the official API. Completing a missing membership still goes through the official `attachSession()` after its validation conditions (header readability, cwd resolution, canonical path equality) are pre-checked, so a predictable rejection fails before any write (#41).
23
+ - **fix(api)**: "Move to workspace" no longer reports success when a repair cannot be completed: hosts without the official `attachSession` API answer `501 workspace-attach-unavailable`, an unconfirmable membership state is refused, a membership conflict answers `409 workspace-membership-conflict`, and unsafe or failed repairs answer `500` with `workspace-repair-unsafe` / `workspace-repair-failed`. Successful repairs report `membership` (`already-member` / `attached`) next to the existing `moved` / `attached` fields (#41).
24
+
5
25
  ## 0.7.3 — 2026-10-18
6
26
 
7
27
  - **fix(update)**: Fix built-in one-click update and resolve `cannot get property "remote" without inject` by routing update requests through the plugin's own Host API instead of client-side `remote.pluginManager`.
package/README.md CHANGED
@@ -20,7 +20,7 @@ Verified with the official DSH Desktop client; see [5 Compatibility](#5-compatib
20
20
 
21
21
  - **Delete** is irreversible and always asks for confirmation. Subagent sessions and transient blank placeholders (no persisted artifact) cannot be deleted.
22
22
  - **Archive / Unarchive** moves a session in and out of the active list without touching its disk content.
23
- - **Move to workspace** keeps history, title, archive state and derived-session relationships intact, rewrites the session's `cwd` to the target workspace, and updates the live writer's header in place so any pending tool calls keep landing on the new path.
23
+ - **Move to workspace** keeps history, title, archive state and derived-session relationships intact, rewrites the session's `cwd` to the target workspace, synchronizes the runtime `workingDirectory` projection for active agents, and updates the live writer's header in place so any pending tool calls keep landing on the new path. When the session's `cwd` already equals the target workspace path but its membership was never recorded, only the missing membership is repaired: no `cwd` rewrite, no artifact rewrite or move, and no session restart.
24
24
  - **Migrate Agent preset** rewrites the latest `agent-preset/selected` event (or the session header if no such event exists) so a session whose preset was renamed or removed can resume. Message history is never altered.
25
25
 
26
26
  ### 1.2 Session shortcuts
@@ -66,7 +66,7 @@ Verified with the official DSH Desktop client; see [5 Compatibility](#5-compatib
66
66
 
67
67
  ### 2.1 Title bar
68
68
 
69
- The right side of the title area exposes actions for the **current session**: **Archive / Unarchive**, **Tags / Notes**, **Move to workspace**, **Delete session**.
69
+ The right side of the title area exposes actions for the **current session**: **Archive / Unarchive**, **Favorites**, **Review-later**, **Tags / Notes**, **Move to workspace**, **Delete session**, and **More actions** (`⋯`), matching native DSH title-bar button sizing (28px height, transparent ghost style) and vector SVG icon design.
70
70
 
71
71
  ### 2.2 Sessions and workspaces management entry and interface
72
72
 
@@ -136,8 +136,9 @@ After changing plugin dependencies, `package.json`, bundle configuration, or oth
136
136
  - Cold rewrites preserve the artifact's stored format (V1 / V2 / V3 / V4 are all readable; the plugin never forces an upgrade). Moves and rewrites refuse corrupt / truncated Zstd logs or JSONL logs with incomplete final lines instead of publishing partial history.
137
137
  - Preset migration separates backup, publication and rollback. If rollback fails, recovery files are retained and their paths are included in the error; do not remove them.
138
138
  - **Workspace archiving rollback protection**: archiving is refused if active sessions are present, and batch session archiving automatically rolls back on partial failures to preserve state consistency.
139
- - Incomplete startup scans skip workspace reconciliation. Complete scans preserve live sessions and any membership added during the scan.
140
- - Plugin mutations are serialized per session and request bodies are limited to 64 KiB. This queue supplements, rather than replaces, DSH's own persistence coordination.
139
+ - On startup, sessions whose `cwd` names a registered workspace but whose membership record is missing are re-registered through the official DSH API (idempotent). Incomplete scans skip pruning only: existing membership is never dropped, and live sessions or memberships added during the scan are always preserved.
140
+ - Plugin mutations are serialized per session and request bodies are limited to 64 KiB. This queue supplements, rather than replaces, DSH's own persistence coordination.
141
+ - **Centralized API authentication**: All `/session-manager/api/*` routes are protected by DSH official `connection.admit()` and `requestRejection()` gates, strictly enforcing Owner-only privileges (`peer.principal.kind === "owner"`) and failing closed (HTTP 503) if connection services are absent, ensuring that exposed network tunnels or local proxies cannot bypass access control.
141
142
 
142
143
  ## 5 Compatibility
143
144
 
@@ -147,7 +148,7 @@ The table below lists verified version combinations between DeepSeek Harness (DS
147
148
 
148
149
  | DeepSeek Harness (DSH) | dsh-session-manager | Verified Environment |
149
150
  | :--- | :--- | :--- |
150
- | **v0.2.1-rc.2** | `0.7.3`, `0.7.2` | Desktop |
151
+ | **v0.2.1-rc.2** | `0.7.5`, `0.7.4`, `0.7.3`, `0.7.2` | Desktop |
151
152
  | **v0.2.0-rc.2** | `0.7.1`, `0.7.0`, `0.6.4`, `0.6.3`, `0.6.2`, `0.5.4` | Desktop |
152
153
  | **v0.1.7-rc.2** | `0.5.3` | Desktop / Web UI |
153
154
  | **v0.1.7-rc.1** | `0.5.2` | Desktop / Web UI |
package/README.zh.md CHANGED
@@ -20,7 +20,7 @@ DSH 会话与工作区管理——工作区:归档与显示。会话:跨工
20
20
 
21
21
  - **删除**:不可逆操作,UI 始终要求二次确认。subagent 会话和尚未落盘的空白会话占位不能删除。
22
22
  - **归档 / 移出归档**:把会话移出或移回主列表,不删除磁盘内容。
23
- - **移动至工作区**:跨工作区移动时保留历史、标题、归档状态和派生会话关系,同时把 `cwd` 重写为目标工作区,并就地更新 live writer 的 header,使挂起的工具调用继续落到新路径。
23
+ - **移动至工作区**:跨工作区移动时保留历史、标题、归档状态和派生会话关系,同时把 `cwd` 重写为目标工作区,实时同步活动 Agent 的运行时 `workingDirectory` 投影,并就地更新 live writer 的 header,使挂起的工具调用继续落到新路径。若会话的 `cwd` 本来就等于目标工作区、只是归属未登记,则只补全归属记录,不改写 `cwd`、不重写或移动工件、不重启会话。
24
24
  - **迁移 Agent 预设**:原预设被改名或删除导致会话无法恢复时,可修复该会话。迁移会就地重写最后一条 `agent-preset/selected` 事件(若从未记录则修改会话 header),不改动历史消息。
25
25
 
26
26
  ### 1.2 会话快捷管理
@@ -64,7 +64,7 @@ DSH 会话与工作区管理——工作区:归档与显示。会话:跨工
64
64
 
65
65
  ### 2.1 标题栏入口
66
66
 
67
- 标题栏右侧对**当前会话**提供:**归档 / 移出归档**、**标签 / 备注**、**移动至工作区**、**删除会话**。
67
+ 标题栏右侧对**当前会话**提供:**归档 / 移出归档**、**收藏**、**待回看**、**标签 / 备注**、**移动至工作区**、**删除会话**以及**更多操作**(`⋯`),与 DSH 原生顶栏按钮规范完全对齐(28px 高度、无边框幽灵透明样式、SVG 矢量描边图标)。
68
68
 
69
69
  ### 2.2 会话与工作区管理入口与界面
70
70
 
@@ -134,8 +134,9 @@ dsh plugin --profile web add <本仓库路径>
134
134
  - 冷会话重写保留原工件格式(V1 / V2 / V3 / V4 都可读,绝不强制升级)。损坏或截断的 Zstd 日志、缺少完整尾行的 JSONL 会拒绝移动 / 重写,不会把部分历史当作完整日志保存。
135
135
  - 迁移预设按"备份 → 发布 → 回滚"分阶段处理。如果回滚失败,会保留恢复文件并在错误中报告路径;不要删除这些文件。
136
136
  - **工作区归档事务保护**:若工作区内存在运行中会话则拒绝归档;批量归档会话若中途遇到异常会自动回滚已变更状态,避免部分成功导致状态不一致。
137
- - 启动扫描不完整时跳过工作区归属修复;完整扫描也不会清除仍在内存中或扫描期间新加入的会话。
137
+ - 启动时若发现 `cwd` 对应已注册工作区但归属记录遗漏的会话,会通过 DSH 官方接口补全登记(幂等);扫描不完整时只跳过清理,不会误删现有归属,也不会清除仍在内存中或扫描期间新加入的会话。
138
138
  - 同一会话的插件写操作按顺序执行;请求体限制为 64 KiB。该队列不替代 DSH 自身的持久化写入协调。
139
+ - **集中 API 鉴权与安全门禁**:所有 `/session-manager/api/*` 接口统一接入 DSH 官方 `connection.admit()` / `requestRejection()` 校验,严格限制仅 Owner 权限主体可调用,服务未就绪时默认拒绝(HTTP 503 Fail-Closed),有效阻断公网隧道或反向代理暴露下的未授权访问。
139
140
 
140
141
  ## 5 兼容性
141
142
 
@@ -145,7 +146,7 @@ dsh plugin --profile web add <本仓库路径>
145
146
 
146
147
  | DeepSeek Harness (DSH) | dsh-session-manager | 验证环境 |
147
148
  | :--- | :--- | :--- |
148
- | **v0.2.1-rc.2** | `0.7.3`, `0.7.2` | Desktop |
149
+ | **v0.2.1-rc.2** | `0.7.5`, `0.7.4`, `0.7.3`, `0.7.2` | Desktop |
149
150
  | **v0.2.0-rc.2** | `0.7.1`, `0.7.0`, `0.6.4`, `0.6.3`, `0.6.2`, `0.5.4` | Desktop |
150
151
  | **v0.1.7-rc.2** | `0.5.3` | Desktop / Web UI |
151
152
  | **v0.1.7-rc.1** | `0.5.2` | Desktop / Web UI |
package/lib/client.js CHANGED
@@ -289,6 +289,7 @@ function isTopmostDialog(z) {
289
289
  "confirm.move.current": "当前工作区:{name}",
290
290
  "confirm.move.same": "请选择与当前工作区不同的目标工作区",
291
291
  "confirm.move.confirm": "确认移动",
292
+ "move.restartRequired": "会话已成功移动至目标工作区,但当前工作目录需要在重启 DSH 后生效。",
292
293
  "confirm.cancel": "取消",
293
294
  "busy.processing": "处理中…",
294
295
  "error.operation": "操作失败:{message}",
@@ -640,6 +641,7 @@ function isTopmostDialog(z) {
640
641
  "confirm.move.current": "Current workspace: {name}",
641
642
  "confirm.move.same": "Choose a target workspace different from the current workspace",
642
643
  "confirm.move.confirm": "Move",
644
+ "move.restartRequired": "Session moved to target workspace successfully, but working directory will take effect after restarting DSH.",
643
645
  "confirm.cancel": "Cancel",
644
646
  "busy.processing": "Working…",
645
647
  "error.operation": "Operation failed: {message}",
@@ -693,11 +695,18 @@ function isTopmostDialog(z) {
693
695
  };
694
696
 
695
697
  const css = [
696
- ".sm-header{display:flex;align-items:center;gap:6px}",
697
- ".sm-headerBtn{box-sizing:border-box;min-height:28px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:1px solid var(--dsw-alias-border-l2);border-radius:999px;align-items:center;gap:4px;padding:3px 10px;font-size:12px;line-height:18px;display:inline-flex;white-space:nowrap}",
698
- ".sm-headerBtn:hover:not(:disabled),.sm-headerBtn:focus-visible{background:var(--dsw-alias-interactive-bg-hover)}",
698
+ ".sm-header{display:inline-flex;align-items:center;gap:6px;flex-wrap:nowrap}",
699
+ ".sm-header{flex-shrink:0}",
700
+ ".sm-headerBtn{display:inline-flex;align-items:center;justify-content:center;gap:4px;min-height:28px;height:28px;box-sizing:border-box;color:var(--dsw-alias-label-secondary);background:transparent;border:0;border-radius:6px;cursor:pointer;padding:0 6px;font-size:12px;line-height:18px;white-space:nowrap;transition:background .12s,color .12s;flex-shrink:0}",
701
+ ".sm-header .sm-headerBtn{width:28px;min-width:28px;padding:0;justify-content:center;position:relative}",
702
+ ".sm-header .sm-headerBtnLabel{display:none}",
703
+ ".sm-header .sm-priorityBadge{position:absolute;top:0;right:0;font-size:8px;line-height:9px;padding:0 2px;border-radius:3px;pointer-events:none}",
704
+ ".sm-headerBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}",
705
+ ".sm-headerBtn:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}",
699
706
  ".sm-headerBtn:disabled{opacity:.5;cursor:not-allowed}",
700
- ".sm-headerBtn svg{flex:none}",
707
+ ".sm-headerBtn.sm-headerBtnActive{background:var(--dsw-alias-button-ghost-active-fill,rgba(0,0,0,.06));color:var(--dsw-alias-label-primary)}",
708
+ ".sm-headerBtn svg{width:14px;height:14px;display:block;margin:auto;flex-shrink:0}",
709
+ ".sm-headerBtn:hover{background:var(--dsw-alias-interactive-bg-hover)}",
701
710
  ".sm-busy{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:28px;margin-left:4px}",
702
711
  ".sm-footer{display:flex}",
703
712
  ".sm-footerBtn{min-height:28px;color:var(--dsw-alias-label-tertiary);cursor:pointer;background:0 0;border:0;border-radius:6px;align-items:center;gap:6px;padding:3px 8px;font-size:12px;line-height:18px;display:inline-flex}",
@@ -745,8 +754,8 @@ function isTopmostDialog(z) {
745
754
  ".sm-moveItem:hover{background:var(--dsw-alias-interactive-bg-hover)}",
746
755
  ".sm-moveItemSelected{border-color:var(--dsw-alias-state-business-primary);background:var(--dsw-alias-state-business-tertiary)}",
747
756
  ".sm-moveItemName{color:var(--dsw-alias-label-primary);font-size:13px;line-height:18px}",
748
- ".sm-moveItemMeta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.sm-panelModal{width:760px;max-width:92vw}.sm-panelModal .sm-rowActions{flex-wrap:wrap;justify-content:flex-end}.sm-headerMenu{position:absolute;right:0;top:100%;margin-top:4px;z-index:100005;display:flex;flex-direction:column;min-width:140px;padding:4px;background:var(--dsw-alias-bg-layer-2,#fff);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;box-shadow:0 4px 16px rgba(0,0,0,.15)}.sm-headerMenuItem{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:0 0;border:0;border-radius:6px;color:var(--dsw-alias-label-primary,#111);cursor:pointer;padding:6px 10px;font-size:13px;line-height:18px;white-space:nowrap}.sm-headerMenuItem:hover{background:var(--dsw-alias-interactive-bg-hover)}.sm-headerMenuItem:disabled{opacity:.5;cursor:not-allowed}.sm-headerMenuItem .sm-headerBtnIcon{width:20px;min-width:20px;text-align:center;flex-shrink:0}.sm-headerMenuItemDanger{color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-headerMenuItemDanger:hover{background:var(--dsw-alias-interactive-bg-hover-danger)}.sm-headerMenuUltraOnly{display:none!important}.sm-headerBtn{display:inline-flex;align-items:center;justify-content:center;gap:6px;min-height:32px;height:32px;box-sizing:border-box;color:var(--dsw-alias-label-secondary);background:var(--dsw-alias-button-floating-fill,#fff);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;padding:0 10px;font-size:13px;line-height:1;white-space:nowrap;transition:background .15s,color .15s,border-color .15s;flex-shrink:0}.sm-headerBtn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);border-color:var(--dsw-alias-border-l1)}.sm-headerBtn:focus-visible{outline:2px solid var(--dsw-alias-state-business-primary);outline-offset:1px}.sm-headerBtn svg{width:16px;height:16px;display:block;margin:auto;flex-shrink:0}.sm-migratePanel{display:flex;flex-direction:column;gap:14px;min-width:480px}.sm-migrateRow{display:flex;flex-direction:column;gap:8px}.sm-migrateRow>label{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:16px;font-weight:500}.sm-migrateChips{display:flex;flex-wrap:wrap;gap:6px}.sm-migrateChip{padding:6px 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);background:transparent;cursor:pointer;font-size:13px;line-height:18px;color:var(--dsw-alias-label-primary);white-space:nowrap}.sm-migrateChip:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-migrateChip:disabled{opacity:.5;cursor:not-allowed}.sm-migrateChipOn{background:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary)}.sm-migrateEmpty{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.sm-migratePreview{padding:10px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-size:13px;line-height:18px}.sm-migrateWarn{padding:10px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary,#f59e0b) 30%,transparent);border-radius:8px;background:var(--dsw-alias-state-warn-tertiary,#fef5e7);color:var(--dsw-alias-label-secondary);font-size:13px;line-height:18px}.sm-migrateList{max-height:200px;overflow:auto;border:1px solid var(--dsw-alias-border-l2);border-radius:8px}.sm-headerBtnDanger{background:var(--dsw-alias-button-floating-fill,#fff);color:var(--dsw-alias-state-error-primary,#d92d20);border-color:var(--dsw-alias-state-error-primary,#d92d20);font-weight:500}.sm-headerBtnDanger:hover:not(:disabled){background:var(--dsw-alias-state-error-primary,#d92d20);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-header{display:inline-flex;align-items:center;gap:6px;flex-wrap:nowrap}.sm-headerSecondaryActions{display:inline-flex;align-items:center;gap:6px;flex-wrap:nowrap}.sm-headerCompactMenu{display:none;position:relative}.sm-headerCompactMenu.sm-headerCompactMenuOpen{position:relative;z-index:100004}.sm-headerCompactMenuBtn{width:32px;min-width:32px;height:32px;padding:0;justify-content:center;font-size:16px;line-height:1}.sm-headerBtnIcon{display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:14px;line-height:1;vertical-align:middle;flex-shrink:0}.sm-headerBtn.sm-markIcon{width:32px;min-width:32px;height:32px;padding:0;justify-content:center}.sm-headerBtn.sm-markIcon .sm-headerBtnIcon{width:16px;height:16px;font-size:15px;line-height:1}.sm-headerCompactMenuBtn .sm-headerBtnIcon{width:16px;height:16px;font-size:16px;line-height:1}.sm-annotationToggleOpen{position:relative;z-index:100004}.sm-headerBtnActive{background:var(--dsw-alias-button-ghost-active-fill);color:var(--dsw-alias-label-primary)}@container (max-width:1000px){.sm-headerBtn{width:32px;min-width:32px;height:32px;padding:0;justify-content:center}.sm-headerBtnLabel,.sm-priorityText,.sm-priorityBadge{display:none}.sm-headerBtn.sm-headerBtn-withBadge{width:auto;min-width:32px;padding:0 6px}}@container (max-width:520px){.sm-headerSecondaryActions,.sm-headerSecondaryAction{display:none!important}.sm-headerCompactMenu{display:inline-flex}}@container (max-width:420px){.sm-header>:not(.sm-headerCompactMenu){display:none!important}.sm-header .sm-headerBtn:not(.sm-headerCompactMenuBtn){display:none!important}.sm-headerCompactMenu{display:inline-flex!important}.sm-headerMenu{right:auto!important;left:0!important}.sm-headerMenuUltraOnly{display:flex!important}}",
749
- ".sm-panelDialog{position:fixed;inset:0;margin:auto;transform:none;width:680px;max-width:calc(100vw - 32px);height:560px;max-height:calc(100vh - 32px);box-sizing:border-box;display:flex;flex-direction:column;gap:0;background:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);overflow:hidden;z-index:1020}.sm-panelDialog .sm-nativeDialogHeader{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;position:relative;min-height:46px;box-sizing:border-box}.sm-panelDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;min-width:0;max-width:calc(100% - 140px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center;pointer-events:auto;z-index:0}.sm-panelDialog .sm-nativeDialogHeaderActions{display:flex;align-items:center;gap:6px;flex:none;position:relative;z-index:1;margin-left:auto}.sm-nativeDialogFooter,.sm-bulkDialog .sm-nativeDialogFooter,.sm-confirmDialog .sm-nativeDialogFooter,.sm-migrateDialog .sm-nativeDialogFooter{display:flex;padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-panelDialog .sm-panel{display:flex;flex-direction:column;gap:6px;min-height:0;flex:1 1 auto;overflow:auto;padding:8px 12px}.sm-panelDialog .sm-list{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-height:0;overflow:auto;scrollbar-gutter:stable}.sm-panelDialog .sm-row{display:flex;align-items:center;gap:8px;padding:6px 10px;min-height:36px;border:1px solid transparent;border-radius:8px;background:transparent;flex-shrink:0;transition:background .12s ease,border-color .12s ease}.sm-panelDialog .sm-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.sm-panelDialog .sm-rowCurrent{background:var(--dsw-alias-bg-module-platform);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-panelDialog .sm-rowMain{display:flex;align-items:stretch!important;gap:8px;min-width:0;flex:1 1 auto;overflow:visible;text-align:left!important}.sm-panelDialog .sm-rowTitle{min-width:0;flex:1 1 0%;width:100%;align-self:stretch;display:flex;align-items:center;justify-content:flex-start;gap:6px;font-size:12px;line-height:16px;overflow:hidden;text-align:left!important;direction:ltr!important;unicode-bidi:plaintext}.sm-confirmDialog{z-index:10000}.sm-confirmDialog.sm-nativeDialogLayer{position:fixed;left:calc(50vw + 184px);top:calc(50vh - 90px);width:360px;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:calc(50vh - 90px) auto auto calc(50vw + 308px)}.sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:auto;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);display:flex;flex-direction:column;box-sizing:border-box;background:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);padding:0;overflow:hidden;animation:sm-confirmPop .14s ease-out}.sm-confirmDialog .sm-nativeDialogHeader{position:relative;padding:12px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);display:flex;align-items:center;justify-content:center;min-height:44px;box-sizing:border-box}.sm-confirmDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;text-align:center;width:auto;max-width:calc(100% - 32px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-confirmDialog .sm-nativeDialogBody{padding:10px 16px;display:flex;flex-direction:column;gap:8px;min-height:0;max-height:calc(100vh - 120px);overflow-y:auto}.sm-confirmDialog .sm-nativeDialogDescription{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary);white-space:pre-wrap}.sm-confirmDialog .sm-warn{display:flex;align-items:flex-start;gap:8px;color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px;background:color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 8%,transparent);border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 25%,transparent);border-radius:8px;padding:8px 10px;margin-top:0}.sm-confirmDialog .sm-nativeDialogFooter{padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-confirmDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer;background:transparent;color:var(--dsw-alias-label-primary);text-align:center}.sm-confirmDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-migrateDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-updateDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-bulkDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-panelDialog .sm-nativeDialogCancel:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-confirmDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-confirmDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}@keyframes sm-confirmPop{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.sm-confirmDialog.sm-nativeDialog{padding:0;width:auto;max-width:none}.sm-panelDialog .sm-rowTitle>span:first-child{display:block;min-width:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;flex:1 1 auto;width:auto;text-align:left!important;direction:ltr!important;unicode-bidi:plaintext}.sm-panelDialog .sm-rowMeta{display:none}.sm-panelDialog .sm-rowActions{display:flex;gap:2px;flex:none;justify-content:flex-end}.sm-panelDialog .sm-rowActions .sm-rowBtn{min-height:22px;padding:0 7px;font-size:11px;line-height:18px;border-radius:6px;border:1px solid transparent;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap}.sm-rowBtn.sm-markIcon{padding:0 6px;font-size:13px;line-height:18px}.sm-panelDialog .sm-rowActions .sm-rowBtn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.sm-panelDialog .sm-rowActions .sm-rowBtnDanger{color:var(--dsw-alias-state-error-primary)}.sm-panelDialog .sm-rowActions .sm-rowBtnDanger:hover{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary)}.sm-panelDialog .sm-filter{flex:none;padding:6px 12px 4px;gap:4px;display:flex;flex-wrap:wrap}.sm-panelDialog .sm-filterBtn{height:28px;min-height:28px;padding:3px 10px;font-size:12px;line-height:18px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;box-sizing:border-box;white-space:nowrap;flex-shrink:0;transition:all .15s ease}.sm-panelDialog .sm-filterBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-panelDialog .sm-filterBtn:disabled{opacity:.4;cursor:not-allowed}.sm-panelDialog .sm-filterBtn.sm-on{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-primary)}.sm-panelDialog .sm-badge{font-size:10px;line-height:14px;padding:0 5px;border-radius:6px;flex:none}.sm-panelDialog .sm-error{padding:6px 10px;margin:0;font-size:12px;line-height:16px}.sm-panelDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:transparent;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:center}.sm-panelDialog .sm-nativeDialogCancel{background:transparent}.sm-panelDialog .sm-nativeDialogConfirm,.sm-annotationDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-panelDialog .sm-nativeDialogConfirm:hover:not(:disabled),.sm-annotationDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}.sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-confirmDialog .sm-nativeDialogDanger,.sm-migrateDialog .sm-nativeDialogDanger,.sm-bulkDialog .sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-confirmDialog .sm-nativeDialogDanger:hover:not(:disabled),.sm-migrateDialog .sm-nativeDialogDanger:hover:not(:disabled),.sm-bulkDialog .sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-panelDialog .sm-empty{padding:18px 0;font-size:12px;color:var(--dsw-alias-label-tertiary);text-align:center}.sm-panelDialog .sm-footError{font-size:11px;color:var(--dsw-alias-state-error-primary);margin-right:auto;line-height:20px}.sm-panelDialog .sm-moveLabel{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}.sm-migrateDialog .sm-nativeDialogFooter{flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-migrateDialog .sm-migrateChip{cursor:pointer;pointer-events:auto;position:relative;z-index:1}.sm-migrateDialog .sm-migrateChip[disabled]{opacity:.5;cursor:not-allowed}.sm-migrateDialog.sm-nativeDialogLayer{position:fixed;left:50vw;top:auto;bottom:48px;transform:translateX(-50%);width:min(560px,calc(100vw - 32px));max-height:none;display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:auto;z-index:10001}.sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:360px;max-width:calc(100vw - 32px);max-height:min(70vh,520px);box-sizing:border-box;background-color:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.45);overflow:hidden;padding:0;display:flex;flex-direction:column;gap:0}.sm-migrateDialog{position:fixed;left:50vw;top:auto;bottom:48px;transform:translateX(-50%);width:min(560px,calc(100vw - 32px));max-height:min(70vh,520px);box-sizing:border-box;display:flex;flex-direction:column;gap:0;background-color:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.45);overflow:hidden;z-index:10001}.sm-migrateDialog .sm-nativeDialogHeader{padding:12px 18px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;position:relative;display:flex;align-items:center;justify-content:center;min-height:44px;box-sizing:border-box}.sm-migrateDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;color:var(--dsw-alias-label-primary,#111);text-align:center;width:auto;max-width:calc(100% - 36px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-migrateDialog .sm-migratePanel{padding:12px 18px;display:flex;flex-direction:column;gap:14px}.sm-migrateDialog .sm-nativeDialogBody{padding:0}.sm-migrateDialog .sm-nativeDialogFooter{padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0;gap:8px}.sm-migrateDialog .sm-migrateRow>label{color:var(--dsw-alias-label-secondary,#444)}.sm-migrateDialog .sm-migrateChip{padding:6px 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2,#ddd);background-color:var(--dsw-alias-markdown-tag,#f1f3f5);color:var(--dsw-alias-label-primary,#111);font-size:13px;line-height:18px;cursor:pointer;pointer-events:auto;position:relative;z-index:1;white-space:nowrap}.sm-migrateDialog .sm-migrateChip:hover:not(:disabled){background-color:var(--dsw-alias-interactive-bg-hover,#e8e8e8)}.sm-migrateDialog .sm-migrateChipOn{background-color:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-migrateDialog .sm-migrateChip.sm-migrateChipOn:hover:not(:disabled){background-color:var(--dsw-alias-button-info-hover,#4576f0);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-button-info-hover,#4576f0);filter:none}.sm-migrateDialog .sm-migrateChipOn:hover:not(:disabled){filter:brightness(.92)}.sm-migrateDialog .sm-migrateChip[disabled]{opacity:.5;cursor:not-allowed}.sm-migrateDialog .sm-migrateEmpty{color:var(--dsw-alias-label-tertiary,#888)}.sm-migrateDialog .sm-migratePreview{padding:10px 12px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;background-color:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#111);font-size:13px;line-height:18px}.sm-migrateDialog .sm-migrateWarn{padding:10px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary,#f59e0b) 30%,transparent);border-radius:8px;background-color:var(--dsw-alias-state-warn-tertiary,#fef5e7);color:var(--dsw-alias-label-secondary,#444);font-size:13px;line-height:18px}.sm-migrateDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;background-color:transparent;color:var(--dsw-alias-label-primary,#111);text-align:center}.sm-migrateDialog .sm-nativeDialogButton:hover:not(:disabled){background-color:var(--dsw-alias-interactive-bg-hover,#e8e8e8)}.sm-migrateDialog .sm-nativeDialogConfirm{background-color:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-migrateDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}",
757
+ ".sm-moveItemMeta{color:var(--dsw-alias-label-tertiary);font-size:11px;line-height:16px}.sm-panelModal{width:760px;max-width:92vw}.sm-panelModal .sm-rowActions{flex-wrap:wrap;justify-content:flex-end}.sm-headerMenu{position:absolute;right:0;top:100%;margin-top:4px;z-index:100005;display:flex;flex-direction:column;min-width:140px;padding:4px;background:var(--dsw-alias-bg-layer-2,#fff);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;box-shadow:0 4px 16px rgba(0,0,0,.15)}.sm-headerMenuItem{display:flex;align-items:center;gap:8px;width:100%;text-align:left;background:0 0;border:0;border-radius:6px;color:var(--dsw-alias-label-primary,#111);cursor:pointer;padding:6px 10px;font-size:13px;line-height:18px;white-space:nowrap}.sm-headerMenuItem:hover{background:var(--dsw-alias-interactive-bg-hover)}.sm-headerMenuItem:disabled{opacity:.5;cursor:not-allowed}.sm-headerMenuItem .sm-headerBtnIcon{width:14px;min-width:14px;text-align:center;flex-shrink:0}.sm-headerMenuItemDanger{color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-headerMenuItemDanger:hover{background:var(--dsw-alias-interactive-bg-hover-danger)}.sm-headerMenuUltraOnly{display:none!important}.sm-migratePanel{display:flex;flex-direction:column;gap:14px;min-width:480px}.sm-migrateRow{display:flex;flex-direction:column;gap:8px}.sm-migrateRow>label{color:var(--dsw-alias-label-secondary);font-size:12px;line-height:16px;font-weight:500}.sm-migrateChips{display:flex;flex-wrap:wrap;gap:6px}.sm-migrateChip{padding:6px 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);background:transparent;cursor:pointer;font-size:13px;line-height:18px;color:var(--dsw-alias-label-primary);white-space:nowrap}.sm-migrateChip:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-migrateChip:disabled{opacity:.5;cursor:not-allowed}.sm-migrateChipOn{background:var(--dsw-alias-state-business-primary);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary)}.sm-migrateEmpty{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:18px}.sm-migratePreview{padding:10px 12px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-primary);font-size:13px;line-height:18px}.sm-migrateWarn{padding:10px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary,#f59e0b) 30%,transparent);border-radius:8px;background:var(--dsw-alias-state-warn-tertiary,#fef5e7);color:var(--dsw-alias-label-secondary);font-size:13px;line-height:18px}.sm-migrateList{max-height:200px;overflow:auto;border:1px solid var(--dsw-alias-border-l2);border-radius:8px}.sm-headerBtnDanger{background:transparent;color:var(--dsw-alias-state-error-primary,#d92d20);border:0;font-weight:500}.sm-headerBtnDanger:hover:not(:disabled){background:var(--dsw-alias-state-error-primary,#d92d20);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-headerSecondaryActions{display:inline-flex;align-items:center;gap:6px;flex-wrap:nowrap}.sm-headerCompactMenu{display:none;position:relative}.sm-headerCompactMenu.sm-headerCompactMenuOpen{position:relative;z-index:100004}.sm-headerCompactMenuBtn{width:28px;min-width:28px;height:28px;padding:0;justify-content:center;font-size:14px;line-height:1}.sm-headerBtnIcon{display:inline-flex;align-items:center;justify-content:center;width:14px;height:14px;font-size:14px;line-height:1;vertical-align:middle;flex-shrink:0}.sm-headerBtn.sm-markIcon{width:28px;min-width:28px;height:28px;padding:0;justify-content:center}.sm-headerBtn.sm-markIcon .sm-headerBtnIcon{width:14px;height:14px;font-size:14px;line-height:1}.sm-headerCompactMenuBtn .sm-headerBtnIcon{width:14px;height:14px;font-size:14px;line-height:1}.sm-annotationToggleOpen{position:relative;z-index:100004}@container (max-width:1000px){.sm-headerBtn{width:28px;min-width:28px;height:28px;padding:0;justify-content:center}.sm-headerBtnLabel,.sm-priorityText,.sm-priorityBadge{display:none}.sm-headerBtn.sm-headerBtn-withBadge{width:auto;min-width:28px;padding:0 6px}}@container (max-width:520px){.sm-headerSecondaryActions,.sm-headerSecondaryAction{display:none!important}.sm-headerCompactMenu{display:inline-flex}}@container (max-width:420px){.sm-header>:not(.sm-headerCompactMenu){display:none!important}.sm-header .sm-headerBtn:not(.sm-headerCompactMenuBtn){display:none!important}.sm-headerCompactMenu{display:inline-flex!important}.sm-headerMenu{right:auto!important;left:0!important}.sm-headerMenuUltraOnly{display:flex!important}}",
758
+ ".sm-panelDialog{position:fixed;inset:0;margin:auto;transform:none;width:680px;max-width:calc(100vw - 32px);height:560px;max-height:calc(100vh - 32px);box-sizing:border-box;display:flex;flex-direction:column;gap:0;background:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);overflow:hidden;z-index:1020}.sm-panelDialog .sm-nativeDialogHeader{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:10px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;position:relative;min-height:46px;box-sizing:border-box}.sm-panelDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;min-width:0;max-width:calc(100% - 140px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;text-align:center;pointer-events:auto;z-index:0}.sm-panelDialog .sm-nativeDialogHeaderActions{display:flex;align-items:center;gap:6px;flex:none;position:relative;z-index:1;margin-left:auto}.sm-nativeDialogFooter,.sm-bulkDialog .sm-nativeDialogFooter,.sm-confirmDialog .sm-nativeDialogFooter,.sm-migrateDialog .sm-nativeDialogFooter{display:flex;padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-panelDialog .sm-panel{display:flex;flex-direction:column;gap:6px;min-height:0;flex:1 1 auto;overflow:auto;padding:8px 12px}.sm-panelDialog .sm-list{display:flex;flex-direction:column;gap:2px;flex:1 1 auto;min-height:0;overflow:auto;scrollbar-gutter:stable}.sm-panelDialog .sm-row{display:flex;align-items:center;gap:8px;padding:6px 10px;min-height:36px;border:1px solid transparent;border-radius:8px;background:transparent;flex-shrink:0;transition:background .12s ease,border-color .12s ease}.sm-panelDialog .sm-row:hover{background:var(--dsw-alias-interactive-bg-hover)}.sm-panelDialog .sm-rowCurrent{background:var(--dsw-alias-bg-module-platform);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-panelDialog .sm-rowMain{display:flex;align-items:stretch!important;gap:8px;min-width:0;flex:1 1 auto;overflow:visible;text-align:left!important}.sm-panelDialog .sm-rowTitle{min-width:0;flex:1 1 0%;width:100%;align-self:stretch;display:flex;align-items:center;justify-content:flex-start;gap:6px;font-size:12px;line-height:16px;overflow:hidden;text-align:left!important;direction:ltr!important;unicode-bidi:plaintext}.sm-confirmDialog{z-index:10000}.sm-confirmDialog.sm-nativeDialogLayer{position:fixed;left:calc(50vw + 184px);top:calc(50vh - 90px);width:360px;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:calc(50vh - 90px) auto auto calc(50vw + 308px)}.sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-confirmDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:auto;max-width:calc(100vw - 32px);max-height:calc(100vh - 32px);display:flex;flex-direction:column;box-sizing:border-box;background:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.25);padding:0;overflow:hidden;animation:sm-confirmPop .14s ease-out}.sm-confirmDialog .sm-nativeDialogHeader{position:relative;padding:12px 16px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);display:flex;align-items:center;justify-content:center;min-height:44px;box-sizing:border-box}.sm-confirmDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;text-align:center;width:auto;max-width:calc(100% - 32px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-confirmDialog .sm-nativeDialogBody{padding:10px 16px;display:flex;flex-direction:column;gap:8px;min-height:0;max-height:calc(100vh - 120px);overflow-y:auto}.sm-confirmDialog .sm-nativeDialogDescription{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary);white-space:pre-wrap}.sm-confirmDialog .sm-warn{display:flex;align-items:flex-start;gap:8px;color:var(--dsw-alias-state-error-primary);font-size:12px;line-height:18px;background:color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 8%,transparent);border:1px solid color-mix(in srgb,var(--dsw-alias-state-error-primary,#ec1313) 25%,transparent);border-radius:8px;padding:8px 10px;margin-top:0}.sm-confirmDialog .sm-nativeDialogFooter{padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-confirmDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;cursor:pointer;background:transparent;color:var(--dsw-alias-label-primary);text-align:center}.sm-confirmDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-migrateDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-updateDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-bulkDialog .sm-nativeDialogCancel:hover:not(:disabled),.sm-panelDialog .sm-nativeDialogCancel:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-confirmDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-confirmDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}@keyframes sm-confirmPop{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}.sm-confirmDialog.sm-nativeDialog{padding:0;width:auto;max-width:none}.sm-panelDialog .sm-rowTitle>span:first-child{display:block;min-width:0;text-overflow:ellipsis;white-space:nowrap;overflow:hidden;flex:1 1 auto;width:auto;text-align:left!important;direction:ltr!important;unicode-bidi:plaintext}.sm-panelDialog .sm-rowMeta{display:none}.sm-panelDialog .sm-rowActions{display:flex;gap:4px;flex:none;align-items:center;justify-content:flex-end}.sm-panelDialog .sm-rowActions .sm-rowBtn{display:inline-flex;align-items:center;justify-content:center;min-height:22px;height:22px;box-sizing:border-box;padding:0 7px;font-size:11px;line-height:18px;border-radius:6px;border:1px solid transparent;background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;white-space:nowrap;transition:background .12s,color .12s}.sm-panelDialog .sm-rowActions .sm-rowBtn.sm-rowBtnIcon,.sm-panelDialog .sm-rowActions .sm-rowBtn.sm-markIcon{width:22px;min-width:22px;padding:0;justify-content:center}.sm-panelDialog .sm-rowActions .sm-rowBtn.sm-markIcon .sm-headerBtnIcon,.sm-panelDialog .sm-rowActions .sm-rowBtn.sm-rowBtnIcon .sm-headerBtnIcon{width:14px;height:14px;font-size:14px;line-height:1}.sm-panelDialog .sm-rowActions .sm-rowBtn.sm-rowBtnIcon svg,.sm-panelDialog .sm-rowActions .sm-rowBtn.sm-markIcon svg{width:14px;height:14px;display:block;margin:auto;flex-shrink:0}.sm-rowActions .sm-rowBtnLabel{display:none}.sm-rowBtn.sm-markIcon{padding:0 6px;font-size:13px;line-height:18px}.sm-panelDialog .sm-rowActions .sm-rowBtn:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.sm-panelDialog .sm-rowActions .sm-rowBtnActive{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary)}.sm-panelDialog .sm-rowActions .sm-rowBtnDanger{color:var(--dsw-alias-state-error-primary)}.sm-panelDialog .sm-rowActions .sm-rowBtnDanger:hover{background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary)}.sm-panelDialog .sm-filter{flex:none;padding:6px 12px 4px;gap:4px;display:flex;flex-wrap:wrap}.sm-panelDialog .sm-filterBtn{height:28px;min-height:28px;padding:3px 10px;font-size:12px;line-height:18px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2);background:transparent;color:var(--dsw-alias-label-secondary);cursor:pointer;box-sizing:border-box;white-space:nowrap;flex-shrink:0;transition:all .15s ease}.sm-panelDialog .sm-filterBtn:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.sm-panelDialog .sm-filterBtn:disabled{opacity:.4;cursor:not-allowed}.sm-panelDialog .sm-filterBtn.sm-on{background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-primary)}.sm-panelDialog .sm-badge{font-size:10px;line-height:14px;padding:0 5px;border-radius:6px;flex:none}.sm-panelDialog .sm-error{padding:6px 10px;margin:0;font-size:12px;line-height:16px}.sm-panelDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2);border-radius:8px;background:transparent;color:var(--dsw-alias-label-primary);cursor:pointer;text-align:center}.sm-panelDialog .sm-nativeDialogCancel{background:transparent}.sm-panelDialog .sm-nativeDialogConfirm,.sm-annotationDialog .sm-nativeDialogConfirm{background:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-panelDialog .sm-nativeDialogConfirm:hover:not(:disabled),.sm-annotationDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}.sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-confirmDialog .sm-nativeDialogDanger,.sm-migrateDialog .sm-nativeDialogDanger,.sm-bulkDialog .sm-nativeDialogDanger{background:var(--dsw-alias-state-error-primary,#d92d20);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-error-primary,#d92d20)}.sm-confirmDialog .sm-nativeDialogDanger:hover:not(:disabled),.sm-migrateDialog .sm-nativeDialogDanger:hover:not(:disabled),.sm-bulkDialog .sm-nativeDialogDanger:hover:not(:disabled){filter:brightness(.92)}.sm-panelDialog .sm-empty{padding:18px 0;font-size:12px;color:var(--dsw-alias-label-tertiary);text-align:center}.sm-panelDialog .sm-footError{font-size:11px;color:var(--dsw-alias-state-error-primary);margin-right:auto;line-height:20px}.sm-panelDialog .sm-moveLabel{font-size:12px;line-height:18px;color:var(--dsw-alias-label-secondary)}.sm-migrateDialog .sm-nativeDialogFooter{flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0}.sm-migrateDialog .sm-migrateChip{cursor:pointer;pointer-events:auto;position:relative;z-index:1}.sm-migrateDialog .sm-migrateChip[disabled]{opacity:.5;cursor:not-allowed}.sm-migrateDialog.sm-nativeDialogLayer{position:fixed;left:50vw;top:auto;bottom:48px;transform:translateX(-50%);width:min(560px,calc(100vw - 32px));max-height:none;display:block;align-items:initial;justify-content:initial;box-sizing:border-box;background:transparent;border:0;box-shadow:none;padding:0;inset:auto;z-index:10001}.sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialogBackdrop{display:none}.sm-migrateDialog.sm-nativeDialogLayer .sm-nativeDialog{position:relative;left:auto;top:auto;transform:none;width:360px;max-width:calc(100vw - 32px);max-height:min(70vh,520px);box-sizing:border-box;background-color:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.45);overflow:hidden;padding:0;display:flex;flex-direction:column;gap:0}.sm-migrateDialog{position:fixed;left:50vw;top:auto;bottom:48px;transform:translateX(-50%);width:min(560px,calc(100vw - 32px));max-height:min(70vh,520px);box-sizing:border-box;display:flex;flex-direction:column;gap:0;background-color:var(--sm-dialog-fill);color:var(--dsw-alias-label-primary,#111);border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:12px;box-shadow:0 16px 48px rgba(0,0,0,.45);overflow:hidden;z-index:10001}.sm-migrateDialog .sm-nativeDialogHeader{padding:12px 18px;border-bottom:1px solid var(--dsw-alias-border-l2,#eee);flex:none;position:relative;display:flex;align-items:center;justify-content:center;min-height:44px;box-sizing:border-box}.sm-migrateDialog .sm-nativeDialogTitle{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);margin:0;font-size:14px;line-height:20px;font-weight:600;color:var(--dsw-alias-label-primary,#111);text-align:center;width:auto;max-width:calc(100% - 36px);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.sm-migrateDialog .sm-migratePanel{padding:12px 18px;display:flex;flex-direction:column;gap:14px}.sm-migrateDialog .sm-nativeDialogBody{padding:0}.sm-migrateDialog .sm-nativeDialogFooter{padding:10px 16px;border-top:1px solid var(--dsw-alias-border-l2,#eee);flex:none;flex-wrap:wrap;justify-content:space-between;gap:6px;margin-top:0;gap:8px}.sm-migrateDialog .sm-migrateRow>label{color:var(--dsw-alias-label-secondary,#444)}.sm-migrateDialog .sm-migrateChip{padding:6px 12px;border-radius:999px;border:1px solid var(--dsw-alias-border-l2,#ddd);background-color:var(--dsw-alias-markdown-tag,#f1f3f5);color:var(--dsw-alias-label-primary,#111);font-size:13px;line-height:18px;cursor:pointer;pointer-events:auto;position:relative;z-index:1;white-space:nowrap}.sm-migrateDialog .sm-migrateChip:hover:not(:disabled){background-color:var(--dsw-alias-interactive-bg-hover,#e8e8e8)}.sm-migrateDialog .sm-migrateChipOn{background-color:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-migrateDialog .sm-migrateChip.sm-migrateChipOn:hover:not(:disabled){background-color:var(--dsw-alias-button-info-hover,#4576f0);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-button-info-hover,#4576f0);filter:none}.sm-migrateDialog .sm-migrateChipOn:hover:not(:disabled){filter:brightness(.92)}.sm-migrateDialog .sm-migrateChip[disabled]{opacity:.5;cursor:not-allowed}.sm-migrateDialog .sm-migrateEmpty{color:var(--dsw-alias-label-tertiary,#888)}.sm-migrateDialog .sm-migratePreview{padding:10px 12px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;background-color:var(--dsw-alias-bg-layer-2,#fff);color:var(--dsw-alias-label-primary,#111);font-size:13px;line-height:18px}.sm-migrateDialog .sm-migrateWarn{padding:10px 12px;border:1px solid color-mix(in srgb,var(--dsw-alias-state-warn-primary,#f59e0b) 30%,transparent);border-radius:8px;background-color:var(--dsw-alias-state-warn-tertiary,#fef5e7);color:var(--dsw-alias-label-secondary,#444);font-size:13px;line-height:18px}.sm-migrateDialog .sm-nativeDialogButton{min-height:28px;padding:3px 14px;font-size:12px;line-height:20px;border:1px solid var(--dsw-alias-border-l2,#ddd);border-radius:8px;cursor:pointer;background-color:transparent;color:var(--dsw-alias-label-primary,#111);text-align:center}.sm-migrateDialog .sm-nativeDialogButton:hover:not(:disabled){background-color:var(--dsw-alias-interactive-bg-hover,#e8e8e8)}.sm-migrateDialog .sm-nativeDialogConfirm{background-color:var(--dsw-alias-state-business-primary,#356ae6);color:var(--dsw-alias-label-primary-foreground,#fff);border-color:var(--dsw-alias-state-business-primary,#356ae6)}.sm-migrateDialog .sm-nativeDialogConfirm:hover:not(:disabled){filter:brightness(.94)}",
750
759
  // The .sm-tooltip rule below deliberately keeps !important: it targets
751
760
  // DSH's Tooltip primitive (used through renderTip), which ships its own
752
761
  // inline styles, so a plugin rule cannot win on specificity alone
@@ -2449,6 +2458,150 @@ function isTopmostDialog(z) {
2449
2458
  useEffect(() => { void annotationStore.load(refreshOnMount); }, [refreshOnMount]);
2450
2459
  return state;
2451
2460
  };
2461
+
2462
+ function HeaderStarIcon(props = {}) {
2463
+ const size = props.size || 14;
2464
+ const filled = !!props.filled;
2465
+ return h("svg", {
2466
+ viewBox: "0 0 24 24",
2467
+ width: size,
2468
+ height: size,
2469
+ fill: filled ? "var(--dsw-alias-state-warn-primary, #eac54f)" : "none",
2470
+ stroke: filled ? "var(--dsw-alias-state-warn-primary, #eac54f)" : "currentColor",
2471
+ strokeWidth: "1.5",
2472
+ strokeLinecap: "round",
2473
+ strokeLinejoin: "round",
2474
+ "aria-hidden": "true",
2475
+ style: { display: "block" }
2476
+ },
2477
+ h("polygon", { points: "12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2" })
2478
+ );
2479
+ }
2480
+
2481
+ function HeaderClockIcon(props = {}) {
2482
+ const size = props.size || 14;
2483
+ return h("svg", {
2484
+ viewBox: "0 0 24 24",
2485
+ width: size,
2486
+ height: size,
2487
+ fill: "none",
2488
+ stroke: "currentColor",
2489
+ strokeWidth: "1.5",
2490
+ strokeLinecap: "round",
2491
+ strokeLinejoin: "round",
2492
+ "aria-hidden": "true",
2493
+ style: { display: "block" }
2494
+ },
2495
+ h("circle", { cx: 12, cy: 12, r: 9 }),
2496
+ h("polyline", { points: "12 7 12 12 15 14" })
2497
+ );
2498
+ }
2499
+
2500
+ function HeaderTagIcon(props = {}) {
2501
+ const size = props.size || 14;
2502
+ return h("svg", {
2503
+ viewBox: "0 0 24 24",
2504
+ width: size,
2505
+ height: size,
2506
+ fill: "none",
2507
+ stroke: "currentColor",
2508
+ strokeWidth: "1.5",
2509
+ strokeLinecap: "round",
2510
+ strokeLinejoin: "round",
2511
+ "aria-hidden": "true",
2512
+ style: { display: "block" }
2513
+ },
2514
+ h("path", { d: "M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z" }),
2515
+ h("line", { x1: 7, y1: 7, x2: 7.01, y2: 7 })
2516
+ );
2517
+ }
2518
+
2519
+ function HeaderArchiveIcon(props = {}) {
2520
+ const size = props.size || 14;
2521
+ const isUnarchive = !!props.unarchive;
2522
+ return h("svg", {
2523
+ viewBox: "0 0 24 24",
2524
+ width: size,
2525
+ height: size,
2526
+ fill: "none",
2527
+ stroke: "currentColor",
2528
+ strokeWidth: "1.5",
2529
+ strokeLinecap: "round",
2530
+ strokeLinejoin: "round",
2531
+ "aria-hidden": "true",
2532
+ style: { display: "block" }
2533
+ },
2534
+ h("polyline", { points: "21 8 21 21 3 21 3 8" }),
2535
+ h("rect", { x: 1, y: 3, width: 22, height: 5, rx: 1 }),
2536
+ isUnarchive
2537
+ ? h(React.Fragment, null,
2538
+ h("polyline", { points: "10 12 12 10 14 12" }),
2539
+ h("line", { x1: 12, y1: 10, x2: 12, y2: 16 })
2540
+ )
2541
+ : h(React.Fragment, null,
2542
+ h("polyline", { points: "10 14 12 16 14 14" }),
2543
+ h("line", { x1: 12, y1: 16, x2: 12, y2: 10 })
2544
+ )
2545
+ );
2546
+ }
2547
+
2548
+ function HeaderMoveIcon(props = {}) {
2549
+ const size = props.size || 14;
2550
+ return h("svg", {
2551
+ viewBox: "0 0 24 24",
2552
+ width: size,
2553
+ height: size,
2554
+ fill: "none",
2555
+ stroke: "currentColor",
2556
+ strokeWidth: "1.5",
2557
+ strokeLinecap: "round",
2558
+ strokeLinejoin: "round",
2559
+ "aria-hidden": "true",
2560
+ style: { display: "block" }
2561
+ },
2562
+ h("polyline", { points: "17 4 21 8 17 12" }),
2563
+ h("line", { x1: 3, y1: 8, x2: 21, y2: 8 }),
2564
+ h("polyline", { points: "7 20 3 16 7 12" }),
2565
+ h("line", { x1: 21, y1: 16, x2: 3, y2: 16 })
2566
+ );
2567
+ }
2568
+
2569
+ function HeaderTrashIcon(props = {}) {
2570
+ const size = props.size || 14;
2571
+ return h("svg", {
2572
+ viewBox: "0 0 24 24",
2573
+ width: size,
2574
+ height: size,
2575
+ fill: "none",
2576
+ stroke: "currentColor",
2577
+ strokeWidth: "1.5",
2578
+ strokeLinecap: "round",
2579
+ strokeLinejoin: "round",
2580
+ "aria-hidden": "true",
2581
+ style: { display: "block" }
2582
+ },
2583
+ h("polyline", { points: "3 6 5 6 21 6" }),
2584
+ h("path", { d: "M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2" })
2585
+ );
2586
+ }
2587
+
2588
+ function HeaderEllipsisIcon(props = {}) {
2589
+ const size = props.size || 14;
2590
+ return h("svg", {
2591
+ viewBox: "0 0 24 24",
2592
+ width: size,
2593
+ height: size,
2594
+ fill: "currentColor",
2595
+ stroke: "none",
2596
+ "aria-hidden": "true",
2597
+ style: { display: "block" }
2598
+ },
2599
+ h("circle", { cx: 12, cy: 12, r: 2 }),
2600
+ h("circle", { cx: 19, cy: 12, r: 2 }),
2601
+ h("circle", { cx: 5, cy: 12, r: 2 })
2602
+ );
2603
+ }
2604
+
2452
2605
  const annotationButtons = (id, title, t, state, className, onToggle, onEdit, disabled = false, editorOpen = false) => {
2453
2606
  const value = annotationOf(state, id);
2454
2607
  const busy = disabled || !state.loaded || !!state.error || state.pending.has(id);
@@ -2457,23 +2610,24 @@ function isTopmostDialog(z) {
2457
2610
  const favoriteLabel = favoriteDesc + ": " + title;
2458
2611
  const reviewLabel = reviewDesc + ": " + title;
2459
2612
  const isHeader = className === "sm-headerBtn";
2613
+ const priorityInfo = value.priority ? ` (P${value.priority})` : "";
2460
2614
  return h(React.Fragment, null,
2461
2615
  renderTip(favoriteDesc, h("button", { type: "button", className: className + " sm-markIcon" + (value.favorite ? " sm-markOn" : ""), disabled: busy, "aria-label": favoriteLabel, "aria-pressed": value.favorite, onClick: () => onToggle({ favorite: !value.favorite }) },
2462
- h("span", { className: "sm-headerBtnIcon" }, value.favorite ? "★" : "☆")
2616
+ h("span", { className: "sm-headerBtnIcon" }, HeaderStarIcon({ filled: value.favorite }))
2463
2617
  )),
2464
2618
  renderTip(reviewDesc, h("button", { type: "button", className: className + " sm-markIcon" + (value.reviewLater ? " sm-markOn" : ""), disabled: busy, "aria-label": reviewLabel, "aria-pressed": value.reviewLater, onClick: () => onToggle({ reviewLater: !value.reviewLater }) },
2465
- h("span", { className: "sm-headerBtnIcon" }, "◷")
2619
+ h("span", { className: "sm-headerBtnIcon" }, HeaderClockIcon())
2466
2620
  )),
2467
- renderTip(t("marks.edit.aria"), h("button", {
2621
+ renderTip(t("marks.edit.aria") + priorityInfo, h("button", {
2468
2622
  type: "button",
2469
- className: className + (isHeader ? " sm-headerSecondaryAction" : "") + (editorOpen ? " sm-annotationToggleOpen sm-headerBtnActive" : ""),
2623
+ className: className + (isHeader ? " sm-headerSecondaryAction" : " sm-rowBtnIcon") + (editorOpen ? " sm-annotationToggleOpen sm-headerBtnActive sm-rowBtnActive" : ""),
2470
2624
  disabled: busy,
2471
2625
  "aria-label": t("marks.edit.aria") + ": " + title,
2472
2626
  ...(isHeader ? { "aria-expanded": editorOpen } : {}),
2473
2627
  onClick: e => onEdit(e)
2474
2628
  },
2475
- isHeader ? h("span", { className: "sm-headerBtnIcon" }, "🏷") : null,
2476
- isHeader ? h("span", { className: "sm-headerBtnLabel" }, t("marks.header.edit")) : t("marks.edit"),
2629
+ h("span", { className: "sm-headerBtnIcon" }, HeaderTagIcon()),
2630
+ h("span", { className: isHeader ? "sm-headerBtnLabel" : "sm-rowBtnLabel" }, isHeader ? t("marks.header.edit") : t("marks.edit")),
2477
2631
  isHeader ? h("span", { className: "sm-priorityBadge sm-priority-" + (value.priority ?? 3) }, "P" + (value.priority ?? 3)) : null
2478
2632
  ))
2479
2633
  );
@@ -3773,7 +3927,7 @@ function isTopmostDialog(z) {
3773
3927
  ));
3774
3928
  }
3775
3929
 
3776
- const CURRENT_VERSION = "0.7.3";
3930
+ const CURRENT_VERSION = "0.7.5";
3777
3931
 
3778
3932
  function compareSemver(v1, v2) {
3779
3933
  if (typeof v1 !== "string" || typeof v2 !== "string") return 0;
@@ -5006,11 +5160,49 @@ function isTopmostDialog(z) {
5006
5160
  h("div", { className: "sm-rowMeta" }, shortPath(s.cwd) + (s.cwd ? " · " : "") + formatRelative(s.updatedAt, now)),
5007
5161
  h("div", { className: "sm-rowActions" },
5008
5162
  h("button", { type: "button", className: "sm-rowBtn", disabled: busy, onClick: () => { if (isArchived) { if (isWsArchived) { if (typeof window !== "undefined" && typeof window.alert === "function") { window.alert(t("error.workspaceArchived")); } return; } /* DSH refuses to surface an archived session as the current view: clicking "Open" on an archived row flashes an empty chat panel and bounces back to "no session selected". Unarchive first, then open. (issue #17.4) */ runRow(s.id, async () => { await onUnarchive(s.id); await onOpen(s.id); }); } else { onOpen(s.id); } } }, t("row.open")),
5009
- h("button", { type: "button", className: "sm-rowBtn", disabled: busy, onClick: () => runRow(s.id, () => { if (isArchived) { if (isWsArchived) { if (typeof window !== "undefined" && typeof window.alert === "function") { window.alert(t("error.workspaceArchived")); } return; } return onUnarchive(s.id); } return onArchive(s.id); }) }, t(isArchived ? "row.unarchive" : "row.archive")),
5163
+ renderTip(t(isArchived ? "row.unarchive" : "row.archive"), h("button", {
5164
+ type: "button",
5165
+ className: "sm-rowBtn sm-rowBtnIcon" + (isArchived ? " sm-rowBtnActive" : ""),
5166
+ disabled: busy,
5167
+ "aria-label": t(isArchived ? "row.unarchive" : "row.archive") + ": " + (s.displayTitle || s.id),
5168
+ onClick: () => runRow(s.id, () => {
5169
+ if (isArchived) {
5170
+ if (isWsArchived) {
5171
+ if (typeof window !== "undefined" && typeof window.alert === "function") {
5172
+ window.alert(t("error.workspaceArchived"));
5173
+ }
5174
+ return;
5175
+ }
5176
+ return onUnarchive(s.id);
5177
+ }
5178
+ return onArchive(s.id);
5179
+ })
5180
+ },
5181
+ h("span", { className: "sm-headerBtnIcon" }, HeaderArchiveIcon({ unarchive: isArchived })),
5182
+ h("span", { className: "sm-rowBtnLabel" }, t(isArchived ? "row.unarchive" : "row.archive"))
5183
+ )),
5010
5184
  annotationButtons(s.id, s.displayTitle || s.id, t, annotations, "sm-rowBtn", patch => runRow(s.id, () => annotationStore.save(s.id, patch)), () => { setAnnotationAnchor(null); setAnnotationFor(current => current?.id === s.id ? null : s); }, busy),
5011
- h("button", { type: "button", className: "sm-rowBtn", disabled: busy, onClick: () => { if (moveFor && moveFor.id === s.id) setMoveFor(null); else setMoveFor(s); } }, t("row.move")),
5185
+ renderTip(t("row.move"), h("button", {
5186
+ type: "button",
5187
+ className: "sm-rowBtn sm-rowBtnIcon" + (moveFor && moveFor.id === s.id ? " sm-rowBtnActive" : ""),
5188
+ disabled: busy,
5189
+ "aria-label": t("row.move") + ": " + (s.displayTitle || s.id),
5190
+ onClick: () => { if (moveFor && moveFor.id === s.id) setMoveFor(null); else setMoveFor(s); }
5191
+ },
5192
+ h("span", { className: "sm-headerBtnIcon" }, HeaderMoveIcon()),
5193
+ h("span", { className: "sm-rowBtnLabel" }, t("row.move"))
5194
+ )),
5012
5195
  h("button", { type: "button", className: "sm-rowBtn", disabled: busy, onClick: () => { if (migrateFor && migrateFor.id === s.id) setMigrateFor(null); else setMigrateFor(s); } }, t("row.migrate")),
5013
- h("button", { type: "button", className: "sm-rowBtn sm-rowBtnDanger", disabled: busy, onClick: () => { if (confirmFor && confirmFor.id === s.id) setConfirmFor(null); else setConfirmFor(s); } }, t("row.delete"))
5196
+ renderTip(t("row.delete"), h("button", {
5197
+ type: "button",
5198
+ className: "sm-rowBtn sm-rowBtnDanger sm-rowBtnIcon" + (confirmFor && confirmFor.id === s.id ? " sm-rowBtnActive" : ""),
5199
+ disabled: busy,
5200
+ "aria-label": t("row.delete") + ": " + (s.displayTitle || s.id),
5201
+ onClick: () => { if (confirmFor && confirmFor.id === s.id) setConfirmFor(null); else setConfirmFor(s); }
5202
+ },
5203
+ h("span", { className: "sm-headerBtnIcon" }, HeaderTrashIcon()),
5204
+ h("span", { className: "sm-rowBtnLabel" }, t("row.delete"))
5205
+ ))
5014
5206
  )
5015
5207
  )
5016
5208
  )
@@ -6096,7 +6288,7 @@ function isTopmostDialog(z) {
6096
6288
  isArchived ? onUnarchive(sessionId) : onArchive(sessionId)
6097
6289
  )
6098
6290
  },
6099
- h("span", { className: "sm-headerBtnIcon" }, isArchived ? "📤" : "📥"),
6291
+ h("span", { className: "sm-headerBtnIcon" }, HeaderArchiveIcon({ unarchive: isArchived })),
6100
6292
  h("span", { className: "sm-headerBtnLabel" }, isArchived ? (t ? t("row.unarchive") : "移出归档") : (t ? t("row.archive") : "归档"))
6101
6293
  )) : null,
6102
6294
  annotationButtons(sessionId, props.displayTitle || sessionId, t, annotations, "sm-headerBtn", patch => runWithAlert("annotations", () => annotationStore.save(sessionId, patch)), (e) => {
@@ -6132,7 +6324,7 @@ function isTopmostDialog(z) {
6132
6324
  }
6133
6325
  }
6134
6326
  },
6135
- h("span", { className: "sm-headerBtnIcon" }, "↔"),
6327
+ h("span", { className: "sm-headerBtnIcon" }, HeaderMoveIcon()),
6136
6328
  h("span", { className: "sm-headerBtnLabel" }, t ? t("row.move") : "移动至工作区")
6137
6329
  )),
6138
6330
  renderTip(t ? t("row.delete") : "删除会话", h("button", {
@@ -6154,7 +6346,7 @@ function isTopmostDialog(z) {
6154
6346
  }
6155
6347
  }
6156
6348
  },
6157
- h("span", { className: "sm-headerBtnIcon" }, "🗑"),
6349
+ h("span", { className: "sm-headerBtnIcon" }, HeaderTrashIcon()),
6158
6350
  h("span", { className: "sm-headerBtnLabel" }, t ? t("row.delete") : "删除会话")
6159
6351
  ))
6160
6352
  ),
@@ -6171,7 +6363,7 @@ function isTopmostDialog(z) {
6171
6363
  setMoreOpen(v => !v);
6172
6364
  }
6173
6365
  },
6174
- h("span", { className: "sm-headerBtnIcon" }, "⋯")
6366
+ h("span", { className: "sm-headerBtnIcon" }, HeaderEllipsisIcon())
6175
6367
  )),
6176
6368
  moreOpen ? h("div", { className: "sm-headerMenu", role: "menu", style: menuStyle },
6177
6369
  (onArchive || onUnarchive) ? h("button", {
@@ -6183,7 +6375,7 @@ function isTopmostDialog(z) {
6183
6375
  runWithAlert("archive", () => isArchived ? onUnarchive(sessionId) : onArchive(sessionId));
6184
6376
  }
6185
6377
  },
6186
- h("span", { className: "sm-headerBtnIcon" }, isArchived ? "📤" : "📥"),
6378
+ h("span", { className: "sm-headerBtnIcon" }, HeaderArchiveIcon({ unarchive: isArchived })),
6187
6379
  h("span", null, isArchived ? (t ? t("row.unarchive") : "移出归档") : (t ? t("row.archive") : "归档"))
6188
6380
  ) : null,
6189
6381
  h("button", {
@@ -6196,7 +6388,7 @@ function isTopmostDialog(z) {
6196
6388
  runWithAlert("annotations", () => annotationStore.save(sessionId, { favorite: !currentAnnotation.favorite }));
6197
6389
  }
6198
6390
  },
6199
- h("span", { className: "sm-headerBtnIcon" }, currentAnnotation.favorite ? "★" : "☆"),
6391
+ h("span", { className: "sm-headerBtnIcon" }, HeaderStarIcon({ filled: currentAnnotation.favorite })),
6200
6392
  h("span", null, t ? t(currentAnnotation.favorite ? "marks.favorite.remove" : "marks.favorite.add") : (currentAnnotation.favorite ? "取消收藏" : "收藏会话"))
6201
6393
  ),
6202
6394
  h("button", {
@@ -6209,7 +6401,7 @@ function isTopmostDialog(z) {
6209
6401
  runWithAlert("annotations", () => annotationStore.save(sessionId, { reviewLater: !currentAnnotation.reviewLater }));
6210
6402
  }
6211
6403
  },
6212
- h("span", { className: "sm-headerBtnIcon" }, "◷"),
6404
+ h("span", { className: "sm-headerBtnIcon" }, HeaderClockIcon()),
6213
6405
  h("span", null, t ? t(currentAnnotation.reviewLater ? "marks.review.remove" : "marks.review.add") : (currentAnnotation.reviewLater ? "取消稍后回看" : "稍后回看"))
6214
6406
  ),
6215
6407
  h("button", {
@@ -6226,7 +6418,7 @@ function isTopmostDialog(z) {
6226
6418
  setAnnotationFor(curr => (curr?.id === sessionId ? null : { id: sessionId, displayTitle }));
6227
6419
  }
6228
6420
  },
6229
- h("span", { className: "sm-headerBtnIcon" }, "🏷"),
6421
+ h("span", { className: "sm-headerBtnIcon" }, HeaderTagIcon()),
6230
6422
  h("span", null, t ? t("marks.header.edit") : "标签/备注")
6231
6423
  ),
6232
6424
  h("button", {
@@ -6245,7 +6437,7 @@ function isTopmostDialog(z) {
6245
6437
  }
6246
6438
  }
6247
6439
  },
6248
- h("span", { className: "sm-headerBtnIcon" }, "↔"),
6440
+ h("span", { className: "sm-headerBtnIcon" }, HeaderMoveIcon()),
6249
6441
  h("span", null, t ? t("row.move") : "移动至工作区")
6250
6442
  ),
6251
6443
  h("button", {
@@ -6264,7 +6456,7 @@ function isTopmostDialog(z) {
6264
6456
  }
6265
6457
  }
6266
6458
  },
6267
- h("span", { className: "sm-headerBtnIcon" }, "🗑"),
6459
+ h("span", { className: "sm-headerBtnIcon" }, HeaderTrashIcon()),
6268
6460
  h("span", null, t ? t("row.delete") : "删除会话")
6269
6461
  )
6270
6462
  ) : null
@@ -6976,6 +7168,12 @@ function isTopmostDialog(z) {
6976
7168
  const wasCurrent = ctx.sessions.list.getSnapshot().current === sessionId;
6977
7169
  const response = await callApi("/move", { sessionId, targetWorkspaceId });
6978
7170
  if (!response.ok) throw new Error(response.error || "move failed");
7171
+ if (response.result?.restartRequired) {
7172
+ try {
7173
+ const msg = (typeof t === "function" ? t("move.restartRequired") : null) || "会话已成功移动至目标工作区,但当前工作目录需要在重启 DSH 后生效。";
7174
+ window.alert(msg);
7175
+ } catch (_) {}
7176
+ }
6979
7177
  const refreshMovedSession = async () => {
6980
7178
  await Promise.allSettled([
6981
7179
  typeof ctx.workspaces?.refresh === "function" ? ctx.workspaces.refresh() : Promise.resolve(),
@@ -7050,7 +7248,7 @@ function isTopmostDialog(z) {
7050
7248
  ctx.slots.inject("conversation.session.header.actions", () => ctx.slots.register({
7051
7249
  name: "conversation.session.header.actions",
7052
7250
  id: "session-manager-header",
7053
- order: 40,
7251
+ order: 0,
7054
7252
  locale: NS,
7055
7253
  inject: () => actions()
7056
7254
  }, HeaderAction));