dsh-better-workspace 0.39.2 → 0.40.0

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/README.md CHANGED
@@ -55,7 +55,7 @@
55
55
  <table>
56
56
  <tr>
57
57
  <td align="center" width="58%"><img src="docs/screenshots/5-context-menu.png" alt="右键菜单"/></td>
58
- <td valign="top"><b>右键菜单</b><br/>操作都收进右键:工作区行——重命名 / 删除 / 分叉 / 归档 / 自定义外观 / <b>修改工作区默认预设</b>(v0.32.0 起,改写该工作区常驻新会话所用的 agent 预设,走官方同一通道;内置预设显示官方本地化名——标准模式 / PTC 模式 / 极简模式 / 创造模式,v0.33.0 起;工作区暂无待命新会话时,确认后会预备一个带所选预设的新会话作为该工作区默认);工作区分组行——重命名分组(同步更新组内所有工作区名称)/ 自定义外观;会话与会话分组行——重命名 / 分叉 / 归档 / 自定义外观;会话行另有<b>复制 Session ID</b>(v0.30.0 起,对齐 dsh 0.2.1-alpha.5 官方会话菜单第五项——写剪贴板走宿主原语,复制成功与否均有提示)。<br/><b>v0.38.0 起接入官方统一右键菜单</b>:会话/工作区行由宿主共享菜单渲染,官方条目与插件补充项(移动到分组 / 移出分组 / 自定义外观 / 修改默认预设,排在分隔线之后)同席,官方新增条目会自动出现;分组行仍用插件菜单。</td>
58
+ <td valign="top"><b>右键菜单</b><br/>操作都收进右键:工作区行——重命名 / 在文件夹显示 / 删除工作区 / <b>筛选会话</b>(归档显示四态,v0.40.0 起) / 自定义外观 / <b>修改工作区默认预设</b>(v0.32.0 起,改写该工作区常驻新会话所用的 agent 预设,走官方同一通道;内置预设显示官方本地化名——标准模式 / PTC 模式 / 极简模式 / 创造模式,v0.33.0 起;工作区暂无待命新会话时,确认后会预备一个带所选预设的新会话作为该工作区默认);工作区分组行——重命名分组(同步更新组内所有工作区名称)/ 自定义外观;会话与会话分组行——重命名 / 分叉 / 归档 / 自定义外观;会话行另有<b>复制 Session ID</b>(v0.30.0 起,对齐 dsh 0.2.1-alpha.5 官方会话菜单第五项——写剪贴板走宿主原语,复制成功与否均有提示)。<br/><b>v0.38.0 起接入官方统一右键菜单</b>:会话/工作区行由宿主共享菜单渲染,官方条目与插件补充项(移动到分组 / 移出分组 / 自定义外观 / 修改默认预设,排在分隔线之后)同席,官方新增条目会自动出现;分组行仍用插件菜单。<br/><b>v0.40.0 起工作区右键新增「筛选会话」子菜单</b>:四个显示状态——跟随全局(默认)/ 隐藏已归档 / 全部对话(显示已归档)/ 仅显示已归档;选择只改该工作区,不写全局筛选,其他工作区照旧。</td>
59
59
  </tr>
60
60
  </table>
61
61
 
@@ -72,7 +72,7 @@
72
72
  - **拖拽还原原版能力**:工作区行可拖拽——拖到另一工作区行上/下半即调整顺序(写回宿主 registry 序),拖到分组行中带则移动进该分组(改写名称前缀);**工作区分组行同样可拖拽(v0.36.0 起,三带悬停)**——拖到分组行时行分三个落区:上下 **30% 边带**=与该组**排序**(拖完立即重排、刷新后保留),**中带**=整组移入(组成员逐个改写名称前缀,与「重命名分组」同一语义;拖到自身/自己的子孙组上会被拒绝);**组行与工作区行同处一条混合序列(v0.36.5 起)**:一个层级里的行顺序只有一份(组行与裸工作区行交错),工作区可以拖到分组行的边带插到该组前面/后面,分组也可以拖到工作区行前面/后面——不再有「组永远排在裸工作区之前」的限制;拖到**另一层**的边带是**放置**(v0.36.6):工作区离开原组(或进入目标层)并插到落点,「插到第一个」画哪落哪(跨磁盘层不放行——磁盘层是文件系统事实);**拖入黑框统一(v0.36.7)**:工作区行拖到分组行中带 = 改名前缀进组(黑框反馈);组行拖到**它所属的磁盘层工作区行 / 直接父级分组行**中带 = 整组「放入」该容器、排到该层末尾(标题与磁盘位置都不动,同一套黑框视觉)——排序走边带、放入走中带,两类操作视觉上彻底分开;**容器防环(v0.36.9)**:磁盘层的容器工作区不能被拖进它自己的名称组或子工作区——那会把容器改名成自己的子孙(如「工作/用户目录」甚至「<id>/用户目录」),现在整行拒绝、不留任何落点反馈,排序与放入父容器(v0.36.7)不受影响;**平级组嵌套与提升(v0.36.10)**:组行拖到平级组行的**中带**=变成它的**子组**(成员标题落到新组之下,`工作/平行帮` → `工作/Fis管理后台/平行帮`,天然不撞名——旧的并入语义会在双方都有同名子工作区时报 name-conflict、整树不动);组行拖到**另一层工作区行的边带**(同磁盘、不在自己子树内)=**整组提升**到那行所在层并锚定在落点旁(「把平行帮拖到和用户目录、工作平级」);已打开的排序槽不再锁死判定——指针推回行**中带**即可翻成放入黑框,嵌套与排序随时互切;**静止松手兜底**:Chromium 把指针静止约一秒后的松手吞成 dragend 时,按最后悬停的落点补提交(Esc 取消不受影响),不再「松手没反应」;**撑开让位(v0.36.4)**:进入排序边带立刻把目标行撑开一行(工作区行与分组行同一套视觉),判定按**行未撑开时的原始位置**算——指针停在槽空出的新区里保持当前方向不闪烁;槽已打开的行只按原始中线二选一(上半=插在前,下半=插在后,**不会翻成「移入」**),三带里的中带 INTO 只在首次进入时决定,随时可改主意;会话行可拖拽——同组内拖到另一会话上/下即调整顺序,拖到**别组的会话行**会把名字前缀改写到那个组(拖到根层的行 = 移出分组),拖到会话子分组行即移动进该分组,拖到**自己的工作区行**或**树里任何组外的地方**(含空白区域)同样移出分组 —— 拖拽期间工作区行整行高亮、树底部有一条淡虚线提示这个出口;带分组前缀的会话行右键还多一项「移出分组」。显示顺序 = 宿主手动序(分组行 = 父容器下的持久化组序),拖拽结果立即生效。**磁盘层是文件系统事实,不随拖拽改变**:跨磁盘层不放行(边带不接管光标、不画落点线),同磁盘层内按落点锚定。拖拽期间树形保持不变(v0.36.4):单链合并行不再临时展开、归组成功也不自动展开目标组——指针下的行不会突然换人,展开状态只在点击时改变。
73
73
  - **不丢原生能力**:会话行(打开/重命名/分叉/归档;**双击标题**重命名,v0.34.0 起;**右键是唯一菜单入口**——行内「⋯」已退役,悬停只留快捷钮,工作区行同样只留新会话钮,v0.35.1 起)、**官方行样式逐项对齐**(v0.34.0 起:恒定 16px 状态槽——运行转圈不再挤动标题、悬停 800ms 弹官方 HoverCard(标题/路径/时间/状态,可复制)、超长标题悬停匀速滚动、活动链工作区文件夹图标着蓝、拖放指示用官方斜纹图案)、每工作区「新会话」(点 + 总是先展开该工作区,让新会话立刻可见)、当前会话高亮、官方状态灯(蓝色运行环 / 琥珀待交互 / 绿色完成提醒)、**状态呼吸灯**(折叠藏起的状态灯向外冒泡:工作区/分组行图标按状态色呼吸发光——琥珀待交互/绿完成,自定义过发光的标题一起呼吸;运行中只在会话行本层蓝色呼吸,不外渗;可在设置关闭)、**活跃定时任务角标**(有活动 Schedule 的会话显示闹钟图标;v0.23.0 起直接渲染官方 `sidebar.session.row.leading` 座位的占用者,与官方行同源)、未分组会话兜底、界面文案跟随 DSH 的语言设置(内置 21 种语言,含简繁中文)。
74
74
  - **新增项自动配色 + 图标(v0.25.0,默认关闭)**:设置卡里一个开关,打开后**新创建的会话**自动分到一个内置色、**新工作区**再额外分到一个图标,懒得逐个设置的人直接开箱即用。颜色来自**定死的 13 个槽位**,每个槽位配**两色**——浅色主题用深色系、深色主题用亮色系——按「洗牌袋 + 近期回避窗口」抽取:一轮之内绝不重复,跨轮也不会立刻撞上刚出过的 3 个,连续新建几项肉眼可辨。**可读性是真达标**:每个色在**对应主题**背景下的对比度都 **≥4.5**,即 WCAG **正文级 AA**(对比度是脚本真算的,测试逐色断言;浅色主题按比纯白更暗的悬停面、深色主题按最亮的面这种保守取值)。行里存的是**槽位 id(`auto:3`)而不是色值**,所以**切换深浅主题时颜色自动换成同色系的另一套**,既不用重新设置,也不会失配。**只影响打开开关之后新建的项**:你手动设置过外观的行(存的是 hex)永不被覆盖,关闭开关也不回收已分配的样式,同一项不会被二次随机。图标从既有图标候选集里取、按宿主实际导出过滤;**图标只给工作区**——会话行的那个位置是官方状态灯与日程角标,没有图标位。
75
- - **官方新语义与快捷键都接上(v0.23.0,对齐 dsh 0.1.7-rc.2)**:① 归档筛选是官方新版三态直选(**隐藏已归档** / **全部对话(显示已归档)** / **仅显示已归档**);选「仅显示已归档」时**没有归档会话的工作区整行隐藏**,空列表显示「暂无已归档会话」+「查看其他会话」一键回退;② 官方快捷键 **⌥⌘K 搜索 / ⌥⌘O 添加工作区 / ⌥⌘N 新会话**(桌面端为 ⌘K / ⌘O / ⌘N)在本插件的自绘侧栏里**真的生效**——搜索键打开并聚焦本插件的搜索框、添加键走同一个官方目录流(原生宿主弹系统选择器,browse 宿主直接弹出官方应用内目录浏览器),按钮文案还会带上宿主当前的键位;③ 首次使用的工作区显示为本地化的「默认工作区」,不再露出磁盘目录名。
75
+ - **官方新语义与快捷键都接上(v0.23.0,对齐 dsh 0.1.7-rc.2)**:① 归档筛选是官方新版三态直选(**隐藏已归档** / **全部对话(显示已归档)** / **仅显示已归档**);选「仅显示已归档」时**没有归档会话的工作区整行隐藏**,空列表显示「暂无已归档会话」+「查看其他会话」一键回退;② 官方快捷键 **⌥⌘K 搜索 / ⌥⌘O 添加工作区 / ⌥⌘N 新会话**(桌面端为 ⌘K / ⌘O / ⌘N)在本插件的自绘侧栏里**真的生效**——搜索键打开并聚焦本插件的搜索框、添加键走同一个官方目录流(原生宿主弹系统选择器,browse 宿主直接弹出官方应用内目录浏览器),按钮文案还会带上宿主当前的键位;③ 首次使用的工作区显示为本地化的「默认工作区」,不再露出磁盘目录名。④ **v0.40.0 起工作区右键「筛选会话」可单独覆盖这三态**(跟随全局 / 隐藏已归档 / 全部对话 / 仅显示已归档):默认跟随全局,覆盖只影响该工作区,全局筛选和其他工作区都不动;「仅显示已归档」下没有归档会话的工作区若自己选了该态,仍保留空行,方便从同一个右键菜单改回。
76
76
  - **自动标题永不拆层,用户分组才拆(v0.39.2,issue #19)**:宿主为每个标题记录了来源(`session/title` 的 `source.kind`)。本插件把来源经摘要投影 `betterWorkspace/titleSource` 带到侧栏:**`fallback` / `provider` 的自动标题整条平铺,标题里有多少 `/` 都不建组**(不再自动包 `“”`,也不等 20 秒改名);只有你**显式重命名、拖入分组或改写分组前缀**(来源变为 `user`)之后,`/` 才作为层级。这样新会话一生成就是一行,不会因为回显首条消息或路径被拆成伪目录。来源缺失时(旧冷缓存、投影未注册)仍保留显示层兜底:引用绝对路径或 `~` / `./` / `../` 路径的标题整条平铺;成对引号保护其中的 `/`;没有斜杠的引号段只是普通文字。旧会话不会丢,也不需要迁移数据。会话分组仍默认开启,不需要的话可在视图菜单关掉。
77
77
  - **新会话页的工作区选择器 = 侧栏那棵树(v0.22.0)**:会话空态页「工作区」按钮的弹层原本是官方的一层平铺标题列表(连磁盘目录嵌套都没有);本插件接管该座位后,弹层绘制与侧栏**同一棵**树——磁盘目录嵌套、「/」名称分组三态、单链合并全部读同一个视图 store,所以侧栏的视图选项一改,**这边立刻跟着变**;当前工作区带勾选标记,分组行可开合(选择器内本地记忆,默认全展开),标题按侧栏的层级叶子显示。底部「添加工作区」仍由**官方目录拾取占用者**承载(原生选择器 / 官方应用内浏览器),不是仿制品。
78
78
 
package/README_EN.md CHANGED
@@ -55,7 +55,7 @@ Session titles nest on `/` too (e.g. `test1/plugin maintenance`). Session groups
55
55
  <table>
56
56
  <tr>
57
57
  <td align="center" width="58%"><img src="docs/screenshots/5-context-menu.png" alt="Context menu"/></td>
58
- <td valign="top"><b>Context menu everywhere</b><br/>Actions live in the right-click menu: workspace rows — rename / delete / fork / archive / customize; folder rows — rename group (updates all descendant workspaces) / customize; session &amp; session-group rows — rename / fork / archive / customize; session rows also get <b>Copy Session ID</b> (v0.30.0, mirroring dsh 0.2.1-alpha.5's fifth official menu entry — the clipboard write rides the host primitive, with a notice either way).<br/><b>Since v0.38.0 the shared host context menu owns session/workspace rows</b>: official entries and this plugin's extras (move to group / move out / customize / default preset, after a separator) share one popup, and future official entries appear automatically; group rows keep the plugin menu.</td>
58
+ <td valign="top"><b>Context menu everywhere</b><br/>Actions live in the right-click menu: workspace rows — rename / show in folder / delete workspace / <b>filter sessions</b> (archived visibility, since v0.40.0) / customize; folder rows — rename group (updates all descendant workspaces) / customize; session &amp; session-group rows — rename / fork / archive / customize; session rows also get <b>Copy Session ID</b> (v0.30.0, mirroring dsh 0.2.1-alpha.5's fifth official menu entry — the clipboard write rides the host primitive, with a notice either way).<br/><b>Since v0.38.0 the shared host context menu owns session/workspace rows</b>: official entries and this plugin's extras (move to group / move out / customize / default preset, after a separator) share one popup, and future official entries appear automatically; group rows keep the plugin menu.<br/><b>Since v0.40.0 workspace rows add a “Filter sessions” submenu</b>: Follow global (default) / Hide archived / All conversations (show archived) / Archived only. The pick changes only that workspace, never the global filter, and every other workspace stays as it is.</td>
59
59
  </tr>
60
60
  </table>
61
61
 
@@ -72,7 +72,7 @@ Session titles nest on `/` too (e.g. `test1/plugin maintenance`). Session groups
72
72
  - **Native drag restored**: drag a workspace row above/below another to reorder (writes back the host registry order) or onto a folder row to move it into that group (rewrites the title prefix); drag session rows to reorder inside their group, onto a row of ANOTHER group to move into that group (onto a root-level row to leave the group), onto a session-group row to move into it, or onto their OWN workspace row / anywhere outside a group (empty space included) to leave it — the workspace row highlights and the tree shows a faint dashed hint while such a drag is in flight; a grouped session row also offers "Move out of group" in its context menu. Display order = host manual order, drag results are visible immediately. **The disk layer is a filesystem fact and never changes through dragging**: a cross-level drop only re-groups the name prefix (the workspace lands at the end of its own disk level), same-level drops take the anchor order. While dragging a workspace, merged single-chain rows (e.g. work/A) temporarily re-expand into folder rows — every level of the path becomes a drop target, and chains merge back when the drag ends.
73
73
  - **Native capabilities kept**: open/rename/fork/archive sessions, per-workspace new-session (the + button always expands the workspace first so the new session is immediately visible), current-session highlight, official status dots (blue running ring / amber pending / green done), **status breathing lights** (dots hidden by collapse bubble outward: workspace/folder rows breathe on their icon in the status color — amber pending / green done, custom-glow labels breathe along; running breathes blue only on the session row itself and never relays; off-able in settings), **active-schedule badge** (alarm clock icon for sessions with active Schedule records; since v0.23.0 it renders the occupant of the shipped `sidebar.session.row.leading` seat, so it is the same mark the official row would show), ungrouped-session fallback, UI copy in 21 languages following the DSH language preference (Simplified and Traditional Chinese included).
74
74
  - **Auto color + icon for new items (v0.25.0, off by default)**: one switch in the plugin settings card. Turn it on and every newly created session gets a built-in color while every new workspace additionally gets an icon — for anyone who would rather not style rows one by one. Colors come from **13 fixed slots**, each shipping **two colors** — a darker one for the light theme, a lighter one for the dark theme — drawn with a shuffle bag plus a recent-draw window: nothing repeats inside a cycle, a refill never starts with the last three colors, and items added in a row look clearly different. **The readability claim is real**: every entry keeps contrast **≥ 4.5** on its own theme's background, i.e. WCAG **normal-text AA** (computed by script and asserted per color in the test suite, measured against conservative surfaces: a hovered row darker than pure white in the light theme, the brightest surface in the dark theme). A row stores the **slot id (`auto:3`), not a hex**, so **switching between light and dark repaints it with the matching sibling color** — nothing to reconfigure and no mismatch. **Only items created after you turn it on are touched**: rows you styled by hand (stored as hex) are never overwritten, turning it off does not undo assignments, and an item is never randomized twice. Icons come from the existing icon candidate set, filtered by what the host actually exports — and **workspaces only**: the session row's cell belongs to the official status dot and schedule mark, so it has no icon slot.
75
- - **Official semantics and shortcuts wired up (v0.23.0, aligned with dsh 0.1.7-rc.2)**: ① the archived filter is the shipped three-way pick (**Hide archived** / **All conversations (show archived)** / **Archived only**); under "Archived only" a workspace without archived sessions disappears entirely, and an empty list offers "No archived sessions yet" + **View other sessions** as the way back. ② The shipped shortcuts **⌥⌘K search / ⌥⌘O add workspace / ⌥⌘N new session** (⌘K / ⌘O / ⌘N on desktop) really work in this plugin's own sidebar — the search key opens and focuses this sidebar's filter field, the add key runs the very same official directory flow (native chooser on a native host, the in-app pointer on a browse host), and the buttons show the host's current keybindings. ③ A first-use workspace reads as the localized "Default workspace" instead of the on-disk directory name.
75
+ - **Official semantics and shortcuts wired up (v0.23.0, aligned with dsh 0.1.7-rc.2)**: ① the archived filter is the shipped three-way pick (**Hide archived** / **All conversations (show archived)** / **Archived only**); under "Archived only" a workspace without archived sessions disappears entirely, and an empty list offers "No archived sessions yet" + **View other sessions** as the way back. ② The shipped shortcuts **⌥⌘K search / ⌥⌘O add workspace / ⌥⌘N new session** (⌘K / ⌘O / ⌘N on desktop) really work in this plugin's own sidebar — the search key opens and focuses this sidebar's filter field, the add key runs the very same official directory flow (native chooser on a native host, the in-app pointer on a browse host), and the buttons show the host's current keybindings. ③ A first-use workspace reads as the localized "Default workspace" instead of the on-disk directory name. ④ **Since v0.40.0 a workspace's right-click “Filter sessions” submenu can override those three states per workspace** (Follow global / Hide archived / All conversations / Archived only): the default follows the global filter, the override touches only that workspace (neither the global pick nor other workspaces move), and a workspace that chose “Archived only” while holding no archived sessions keeps its empty row so the same menu can switch it back.
76
76
  - **Automatic titles never nest; only your explicit grouping does (v0.39.2, issue #19)**: the host records where each title came from (`source.kind` on `session/title`). This plugin carries that provenance to the sidebar through the `betterWorkspace/titleSource` summary projection: a **`fallback` / `provider` auto-title is always ONE row, no matter how many `/` it contains** (no synthetic `“”` wrap and no 20-second rename). A `/` becomes a hierarchy only after you **rename the session, drag it into a group, or rewrite its group prefix** — the source then becomes `user`. A fresh session therefore stays a single row from birth, even when its echoed first message or a path used to shred it into fake folders. When the projection is missing (old cold cache, registration unavailable) the display keeps its text fallback: titles quoting an absolute path or a `~` / `./` / `../` path stay flat; paired quotes protect a `/` inside them; a quoted span with no slash is ordinary text. No session data is migrated or lost. Session grouping stays on by default; turn it off in the view menu if you don't want it.
77
77
  - **The New Session workspace picker IS the sidebar tree (v0.22.0)**: the empty-state "Workspace" chip used to open the shipped one-level list of flat titles (no disk nesting at all). This plugin shadows that seat (lowest priority renders) and draws the **same** tree the sidebar draws — disk nesting, the tri-state "/" name layer, chain compression — all from the one view store, so changing a view option on the sidebar moves this popover immediately. The current workspace carries a check, folder rows fold (picker-local, fully expanded by default), and the pinned "Add workspace" action still renders the **shipped directory-picking occupant** (native chooser / official in-app browser) instead of a copy.
78
78
 
package/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-external/dsh-better-workspace",
3
- "version": "0.39.2",
3
+ "version": "0.40.0",
4
4
  "main": "./src/index.js",
5
5
  "description": "侧边栏工作区树:按官方磁盘目录嵌套(官方 workspace-tree 语义),可选按名称中的 / 分组(默认关闭,设置里开启);新会话页的工作区选择器同树。Workspace tree for the DSH sidebar workspace list, nested by official disk folders with optional \"/\"-name grouping; the New Session workspace picker shows the same tree.",
6
6
  "engines": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-better-workspace",
3
- "version": "0.39.2",
3
+ "version": "0.40.0",
4
4
  "description": "侧边栏工作区树:按官方磁盘目录嵌套(官方 workspace-tree 语义),可选按名称中的 / 分组(默认关闭,设置里开启);新会话页的工作区选择器同树(同一份视图选项即时同步);添加工作区走官方目录流。Workspace tree for the DSH sidebar: disk-path nesting (official workspace-tree semantics), with optional \"/\"-name grouping (off by default), and the same tree in the New Session workspace picker; add-workspace rides the official directory flow.",
5
5
  "type": "module",
6
6
  "repository": {
package/src/client.js CHANGED
@@ -1109,7 +1109,7 @@ window.__ModuleLoader__.load({
1109
1109
  // LITERAL, not a spread of DEFAULT_APPEARANCE: init() is eval-harness
1110
1110
  // friendly (no cross-section reference), and the smoke suite asserts the
1111
1111
  // two stay in lockstep field by field.
1112
- init: () => ({ expanded: {}, sessionsExpanded: {}, sessionGroups: {}, sessionOrder: {}, prefs: { compactChains: true, sessionLimit: 0, appearance: { color: '', glow: 0, weight: 0, shadow: false, stroke: false, strokeWidth: 1, strokeColor: '#808080' } }, styling: {}, groupBy: 'workspace-tree', orderBy: 'manual', archivedFilter: 'default', workspaceGroupMode: 'disk', sessionTitleSlash: true, workspaceTitleSlash: false, ungroupedOpen: true, folders: { ws: {}, sess: {} }, folderOrder: {} }),
1112
+ init: () => ({ expanded: {}, sessionsExpanded: {}, sessionGroups: {}, sessionOrder: {}, prefs: { compactChains: true, sessionLimit: 0, appearance: { color: '', glow: 0, weight: 0, shadow: false, stroke: false, strokeWidth: 1, strokeColor: '#808080' } }, styling: {}, groupBy: 'workspace-tree', orderBy: 'manual', archivedFilter: 'default', workspaceArchivedFilters: {}, workspaceGroupMode: 'disk', sessionTitleSlash: true, workspaceTitleSlash: false, ungroupedOpen: true, folders: { ws: {}, sess: {} }, folderOrder: {} }),
1113
1113
  // NOTE: hydration REPLACES the state with the persisted whole value —
1114
1114
  // init defaults never merge. Every action must tolerate a missing key
1115
1115
  // (states persisted by older plugin versions lack sessionGroups), and
@@ -1137,6 +1137,15 @@ window.__ModuleLoader__.load({
1137
1137
  setGroupBy: (d, value) => { d.groupBy = value },
1138
1138
  setOrderBy: (d, value) => { d.orderBy = value },
1139
1139
  setArchivedFilter: (d, value) => { d.archivedFilter = value === 'show' || value === 'only' ? value : 'default' },
1140
+ // Per-workspace override of the archived visibility filter (v0.40.0).
1141
+ // Absent means "follow the global archivedFilter"; a stored value is
1142
+ // one of the same three literals, so sessionsOf needs no translation
1143
+ // layer. null deletes the override and restores the follow state.
1144
+ setWorkspaceArchivedFilter: (d, workspaceId, value) => {
1145
+ if (!d.workspaceArchivedFilters || typeof d.workspaceArchivedFilters !== 'object') d.workspaceArchivedFilters = {}
1146
+ if (value === 'default' || value === 'show' || value === 'only') d.workspaceArchivedFilters[workspaceId] = value
1147
+ else delete d.workspaceArchivedFilters[workspaceId]
1148
+ },
1140
1149
  setSessionTitleSlash: (d, value) => { d.sessionTitleSlash = value !== false },
1141
1150
  setWorkspaceTitleSlash: (d, value) => { d.workspaceTitleSlash = value !== false },
1142
1151
  // v0.21.0 tri-state grouping (issue #7). The legacy boolean rides
@@ -3724,6 +3733,19 @@ window.__ModuleLoader__.load({
3724
3733
  // Archived-row visibility (v0.20.0, official ArchivedFilter mirror);
3725
3734
  // persisted snapshots from older plugin versions lack the key.
3726
3735
  const archivedFilter = useStore ? (useStore(s => s.archivedFilter) || 'default') : 'default'
3736
+ // Per-workspace archived-visibility overrides (v0.40.0): hydrated
3737
+ // snapshots predate the key, so every read takes the empty-object
3738
+ // fallback and an unknown value means "follow the global filter".
3739
+ const workspaceArchivedFilters = useStore ? (useStore(s => s.workspaceArchivedFilters) || {}) : {}
3740
+ const workspaceArchivedFilterOf = (workspaceId) => {
3741
+ if (!workspaceArchivedFilters || typeof workspaceArchivedFilters !== 'object') return null
3742
+ const value = workspaceArchivedFilters[workspaceId]
3743
+ return value === 'default' || value === 'show' || value === 'only' ? value : null
3744
+ }
3745
+ const effectiveArchivedFilterOf = (workspace) => {
3746
+ const override = workspace ? workspaceArchivedFilterOf(workspace.workspaceId) : null
3747
+ return override || archivedFilter
3748
+ }
3727
3749
  const archivedSet = React.useMemo(() => new Set(archivedSessionIds), [archivedSessionIds])
3728
3750
  const pinnedSet = React.useMemo(() => new Set(pinnedSessionIds), [pinnedSessionIds])
3729
3751
  const subCounts = React.useMemo(
@@ -4225,9 +4247,10 @@ window.__ModuleLoader__.load({
4225
4247
 
4226
4248
  const sessionsOf = (workspace) => {
4227
4249
  const rows = []
4250
+ const filter = effectiveArchivedFilterOf(workspace)
4228
4251
  for (const id of workspace.sessionIds || []) {
4229
4252
  const summary = list && list.byId ? list.byId[id] : undefined
4230
- if (!sessionVisible(summary, currentId, archivedSet, archivedFilter)) continue
4253
+ if (!sessionVisible(summary, currentId, archivedSet, filter)) continue
4231
4254
  const st = statusOf(id)
4232
4255
  rows.push({
4233
4256
  id,
@@ -6091,8 +6114,17 @@ window.__ModuleLoader__.load({
6091
6114
  * with, so this can never disagree with the session list below the row.
6092
6115
  */
6093
6116
  const archivedOnly = archivedFilter === 'only'
6094
- const workspaceVisible = (workspace) => !archivedOnly
6095
- || !!(workspace && Array.isArray(workspace.sessionIds) && sessionsOf(workspace).length > 0)
6117
+ const workspaceVisible = (workspace) => {
6118
+ if (!workspace) return false
6119
+ if (effectiveArchivedFilterOf(workspace) !== 'only') return true
6120
+ if (Array.isArray(workspace.sessionIds) && sessionsOf(workspace).length > 0) return true
6121
+ // Keep an EMPTY workspace that carries its own "only archived"
6122
+ // override: its row is the sole surface holding the menu that can
6123
+ // switch it back to "follow global". Hiding it would trap the user
6124
+ // in an empty view with no visible way out (the global empty-state
6125
+ // action edits the global filter, not this workspace's override).
6126
+ return workspaceArchivedFilterOf(workspace.workspaceId) === 'only'
6127
+ }
6096
6128
  const countVisibleAt = (level) => {
6097
6129
  let total = 0
6098
6130
  for (const folder of level.folders) {
@@ -6487,6 +6519,39 @@ window.__ModuleLoader__.load({
6487
6519
  current: projection && typeof projection.agentPreset === 'string' ? projection.agentPreset : undefined,
6488
6520
  })
6489
6521
  }
6522
+ // Per-workspace archived visibility (v0.40.0). The four entries share
6523
+ // one id set across the primitives submenu, the flat no-Menu fallback
6524
+ // and the official shared menu, so dispatch is identical everywhere.
6525
+ // A leading check marks the stored value; `follow` is the absent key.
6526
+ const archiveFilterOptions = (workspaceId) => {
6527
+ const selected = workspaceArchivedFilterOf(workspaceId)
6528
+ const option = (value, id, label) => ({
6529
+ value,
6530
+ id,
6531
+ label: (selected === value ? '✓ ' : '') + label,
6532
+ })
6533
+ return [
6534
+ option(null, 'bw-archive-follow', t('menu.archiveFollow')),
6535
+ option('default', 'bw-archive-hide', t('menu.archiveHide')),
6536
+ option('show', 'bw-archive-show', t('menu.archiveShow')),
6537
+ option('only', 'bw-archive-only', t('menu.archiveOnly')),
6538
+ ]
6539
+ }
6540
+ const archiveFilterEntries = (workspaceId) => {
6541
+ const options = archiveFilterOptions(workspaceId)
6542
+ // The plugin's no-primitives fallback menu is a flat button list, so
6543
+ // a submenu would be unreachable there. Flatten into the parent menu
6544
+ // instead; ids stay the same, dispatch stays shared.
6545
+ if (typeof ui.Menu !== 'function') {
6546
+ return options.map((option) => ({ id: option.id, label: option.label }))
6547
+ }
6548
+ return [{
6549
+ id: 'bw-archive-filter',
6550
+ label: t('menu.archiveFilter'),
6551
+ icon: icon('IconArchiveOutlineRegular', 16),
6552
+ submenu: options.map((option) => ({ id: option.id, label: option.label })),
6553
+ }]
6554
+ }
6490
6555
  const menuEntries = () => {
6491
6556
  if (ctx === null) return []
6492
6557
  const customizeEntry = { id: 'customize', label: t('custom.title'), icon: icon('IconPersonalizationOutline16', 16) }
@@ -6520,6 +6585,7 @@ window.__ModuleLoader__.load({
6520
6585
  { id: 'delete', label: ot ? ot('delete.workspace') : t('menu.delete'), icon: icon('IconTrashOutline16', 16), danger: true },
6521
6586
  { type: 'separator', id: 'bw-sep' },
6522
6587
  ...wsGroupItems,
6588
+ ...archiveFilterEntries(ctx.payload.workspaceId),
6523
6589
  customizeEntry,
6524
6590
  // v0.32.0: the workspace default preset. Rides the official
6525
6591
  // agent-preset roster + blank-composition channels (the hero
@@ -6554,6 +6620,17 @@ window.__ModuleLoader__.load({
6554
6620
  }
6555
6621
  const { kind, payload } = current
6556
6622
  setCtx(null)
6623
+ const archiveValue = id === 'bw-archive-follow' ? null
6624
+ : id === 'bw-archive-hide' ? 'default'
6625
+ : id === 'bw-archive-show' ? 'show'
6626
+ : id === 'bw-archive-only' ? 'only'
6627
+ : undefined
6628
+ if (kind === 'workspace' && archiveValue !== undefined) {
6629
+ if (actions && typeof actions.setWorkspaceArchivedFilter === 'function') {
6630
+ actions.setWorkspaceArchivedFilter(payload.workspaceId, archiveValue)
6631
+ }
6632
+ return
6633
+ }
6557
6634
  if (id === 'move-group') {
6558
6635
  // Lock the clicked row as the dialog target; the group name starts
6559
6636
  // at its CURRENT prefix so "retype to move elsewhere" is one edit.
@@ -6592,6 +6669,12 @@ window.__ModuleLoader__.load({
6592
6669
  return !summary || groupsAllowedFor(summary)
6593
6670
  },
6594
6671
  label: (key) => t(key),
6672
+ archiveOptions: (workspaceId) => archiveFilterOptions(workspaceId),
6673
+ setArchiveFilter: (workspaceId, value) => {
6674
+ if (actions && typeof actions.setWorkspaceArchivedFilter === 'function') {
6675
+ actions.setWorkspaceArchivedFilter(workspaceId, value)
6676
+ }
6677
+ },
6595
6678
  customize: (kind, payload) => {
6596
6679
  const name = kind === 'workspace' ? (payload.title || payload.leaf) : payload.title
6597
6680
  setCustomize({ kind, entryKey: keyOf(kind, payload), name })
@@ -7282,6 +7365,23 @@ window.__ModuleLoader__.load({
7282
7365
  run: () => bridge.moveGroup('workspace', payload),
7283
7366
  })
7284
7367
  }
7368
+ // A submenu, not four top-level rows: the official shared menu
7369
+ // only sees this plugin's contribution, so the workspace verb
7370
+ // block stays short while the four archive modes are one level
7371
+ // deeper. The check mark lives in the label because a shared
7372
+ // contextMenus action has no selectedIds channel.
7373
+ const archive = bridge.archiveOptions && bridge.archiveOptions(target.workspaceId)
7374
+ if (archive && archive.length > 0) {
7375
+ actions.push({
7376
+ id: 'bw-archive-filter',
7377
+ label: bridge.label('menu.archiveFilter'),
7378
+ children: archive.map((option) => ({
7379
+ id: option.id,
7380
+ label: option.label,
7381
+ run: () => bridge.setArchiveFilter(target.workspaceId, option.value),
7382
+ })),
7383
+ })
7384
+ }
7285
7385
  actions.push({
7286
7386
  id: 'bw-customize',
7287
7387
  label: bridge.label('custom.title'),
@@ -64,6 +64,11 @@ window.__ModuleLoader__.load({
64
64
  'menu.moveOutGroup': '移出分组',
65
65
  'menu.sessionId': '复制 Session ID',
66
66
  'menu.workspacePreset': '修改工作区默认预设…',
67
+ 'menu.archiveFilter': '筛选会话',
68
+ 'menu.archiveFollow': '跟随全局',
69
+ 'menu.archiveHide': '隐藏已归档',
70
+ 'menu.archiveShow': '全部对话(显示已归档)',
71
+ 'menu.archiveOnly': '仅显示已归档',
67
72
  'wsPreset.title': '修改工作区默认预设',
68
73
  'wsPreset.current': '当前默认预设',
69
74
  'wsPreset.currentUnknown': '当前预设未知',
@@ -227,6 +232,11 @@ window.__ModuleLoader__.load({
227
232
  'menu.moveOutGroup': 'Move out of group',
228
233
  'menu.sessionId': 'Copy Session ID',
229
234
  'menu.workspacePreset': 'Workspace default preset…',
235
+ 'menu.archiveFilter': 'Filter sessions',
236
+ 'menu.archiveFollow': 'Follow global',
237
+ 'menu.archiveHide': 'Hide archived',
238
+ 'menu.archiveShow': 'All conversations (show archived)',
239
+ 'menu.archiveOnly': 'Archived only',
230
240
  'wsPreset.title': 'Change workspace default preset',
231
241
  'wsPreset.current': 'Current default preset',
232
242
  'wsPreset.currentUnknown': 'Current preset unknown',
@@ -398,6 +408,11 @@ window.__ModuleLoader__.load({
398
408
  'menu.moveOutGroup': 'إخراج من المجموعة',
399
409
  'menu.sessionId': 'نسخ معرّف الجلسة',
400
410
  'menu.workspacePreset': 'الإعداد المسبق الافتراضي لمساحة العمل…',
411
+ 'menu.archiveFilter': 'تصفية الجلسات',
412
+ 'menu.archiveFollow': 'اتباع العام',
413
+ 'menu.archiveHide': 'إخفاء المؤرشفة',
414
+ 'menu.archiveShow': 'كل المحادثات (إظهار المؤرشفة)',
415
+ 'menu.archiveOnly': 'المؤرشفة فقط',
401
416
  'wsPreset.title': 'تغيير الإعداد المسبق الافتراضي لمساحة العمل',
402
417
  'wsPreset.current': 'الإعداد المسبق الافتراضي الحالي',
403
418
  'wsPreset.currentUnknown': 'الإعداد المسبق الحالي غير معروف',
@@ -561,6 +576,11 @@ window.__ModuleLoader__.load({
561
576
  'menu.moveOutGroup': 'Aus der Gruppe entfernen',
562
577
  'menu.sessionId': 'Session-ID kopieren',
563
578
  'menu.workspacePreset': 'Workspace-Standardpreset…',
579
+ 'menu.archiveFilter': 'Sitzungen filtern',
580
+ 'menu.archiveFollow': 'Global folgen',
581
+ 'menu.archiveHide': 'Archivierte ausblenden',
582
+ 'menu.archiveShow': 'Alle Unterhaltungen (archivierte anzeigen)',
583
+ 'menu.archiveOnly': 'Nur archivierte',
564
584
  'wsPreset.title': 'Workspace-Standardpreset ändern',
565
585
  'wsPreset.current': 'Aktueller Standardpreset',
566
586
  'wsPreset.currentUnknown': 'Aktueller Preset unbekannt',
@@ -724,6 +744,11 @@ window.__ModuleLoader__.load({
724
744
  'menu.moveOutGroup': 'Retirer du groupe',
725
745
  'menu.sessionId': 'Copier l’ID de session',
726
746
  'menu.workspacePreset': 'Préréglage par défaut du workspace…',
747
+ 'menu.archiveFilter': 'Filtrer les sessions',
748
+ 'menu.archiveFollow': 'Suivre le global',
749
+ 'menu.archiveHide': 'Masquer les archivées',
750
+ 'menu.archiveShow': 'Toutes les conversations (afficher les archivées)',
751
+ 'menu.archiveOnly': 'Archivées uniquement',
727
752
  'wsPreset.title': 'Modifier le préréglage par défaut du workspace',
728
753
  'wsPreset.current': 'Préréglage par défaut actuel',
729
754
  'wsPreset.currentUnknown': 'Préréglage actuel inconnu',
@@ -887,6 +912,11 @@ window.__ModuleLoader__.load({
887
912
  'menu.moveOutGroup': 'समूह से बाहर निकालें',
888
913
  'menu.sessionId': 'सेशन आईडी कॉपी करें',
889
914
  'menu.workspacePreset': 'वर्कस्पेस डिफ़ॉल्ट प्रीसेट…',
915
+ 'menu.archiveFilter': 'सत्र फ़िल्टर करें',
916
+ 'menu.archiveFollow': 'ग्लोबल का पालन करें',
917
+ 'menu.archiveHide': 'संग्रहीत छिपाएँ',
918
+ 'menu.archiveShow': 'सभी बातचीत (संग्रहीत दिखाएँ)',
919
+ 'menu.archiveOnly': 'केवल संग्रहीत',
890
920
  'wsPreset.title': 'वर्कस्पेस डिफ़ॉल्ट प्रीसेट बदलें',
891
921
  'wsPreset.current': 'वर्तमान डिफ़ॉल्ट प्रीसेट',
892
922
  'wsPreset.currentUnknown': 'वर्तमान प्रीसेट अज्ञात',
@@ -1050,6 +1080,11 @@ window.__ModuleLoader__.load({
1050
1080
  'menu.moveOutGroup': 'Keluarkan dari grup',
1051
1081
  'menu.sessionId': 'Salin ID Sesi',
1052
1082
  'menu.workspacePreset': 'Preset bawaan ruang kerja…',
1083
+ 'menu.archiveFilter': 'Filter sesi',
1084
+ 'menu.archiveFollow': 'Ikuti global',
1085
+ 'menu.archiveHide': 'Sembunyikan arsip',
1086
+ 'menu.archiveShow': 'Semua percakapan (tampilkan arsip)',
1087
+ 'menu.archiveOnly': 'Hanya arsip',
1053
1088
  'wsPreset.title': 'Ubah preset bawaan ruang kerja',
1054
1089
  'wsPreset.current': 'Preset bawaan saat ini',
1055
1090
  'wsPreset.currentUnknown': 'Preset saat ini tidak diketahui',
@@ -1213,6 +1248,11 @@ window.__ModuleLoader__.load({
1213
1248
  'menu.moveOutGroup': 'Rimuovi dal gruppo',
1214
1249
  'menu.sessionId': 'Copia ID sessione',
1215
1250
  'menu.workspacePreset': 'Preset predefinito dello workspace…',
1251
+ 'menu.archiveFilter': 'Filtra sessioni',
1252
+ 'menu.archiveFollow': 'Segui globale',
1253
+ 'menu.archiveHide': 'Nascondi archiviate',
1254
+ 'menu.archiveShow': 'Tutte le conversazioni (mostra archiviate)',
1255
+ 'menu.archiveOnly': 'Solo archiviate',
1216
1256
  'wsPreset.title': 'Modifica il preset predefinito dello workspace',
1217
1257
  'wsPreset.current': 'Preset predefinito attuale',
1218
1258
  'wsPreset.currentUnknown': 'Preset attuale sconosciuto',
@@ -1376,6 +1416,11 @@ window.__ModuleLoader__.load({
1376
1416
  'menu.moveOutGroup': 'グループから出す',
1377
1417
  'menu.sessionId': 'セッション ID をコピー',
1378
1418
  'menu.workspacePreset': 'ワークスペース既定プリセット…',
1419
+ 'menu.archiveFilter': 'セッションを絞り込む',
1420
+ 'menu.archiveFollow': 'グローバルに従う',
1421
+ 'menu.archiveHide': 'アーカイブを非表示',
1422
+ 'menu.archiveShow': 'すべての会話(アーカイブを表示)',
1423
+ 'menu.archiveOnly': 'アーカイブのみ',
1379
1424
  'wsPreset.title': 'ワークスペース既定プリセットを変更',
1380
1425
  'wsPreset.current': '現在の既定プリセット',
1381
1426
  'wsPreset.currentUnknown': '現在のプリセットは不明',
@@ -1539,6 +1584,11 @@ window.__ModuleLoader__.load({
1539
1584
  'menu.moveOutGroup': '그룹에서 제거',
1540
1585
  'menu.sessionId': '세션 ID 복사',
1541
1586
  'menu.workspacePreset': '작업 공간 기본 프리셋…',
1587
+ 'menu.archiveFilter': '세션 필터',
1588
+ 'menu.archiveFollow': '전역 설정 따르기',
1589
+ 'menu.archiveHide': '보관된 항목 숨기기',
1590
+ 'menu.archiveShow': '모든 대화(보관된 항목 표시)',
1591
+ 'menu.archiveOnly': '보관된 항목만',
1542
1592
  'wsPreset.title': '작업 공간 기본 프리셋 변경',
1543
1593
  'wsPreset.current': '현재 기본 프리셋',
1544
1594
  'wsPreset.currentUnknown': '현재 프리셋을 알 수 없음',
@@ -1702,6 +1752,11 @@ window.__ModuleLoader__.load({
1702
1752
  'menu.moveOutGroup': 'Uit groep halen',
1703
1753
  'menu.sessionId': 'Sessie-ID kopiëren',
1704
1754
  'menu.workspacePreset': 'Standaardpreset van workspace…',
1755
+ 'menu.archiveFilter': 'Sessies filteren',
1756
+ 'menu.archiveFollow': 'Globaal volgen',
1757
+ 'menu.archiveHide': 'Gearchiveerde verbergen',
1758
+ 'menu.archiveShow': 'Alle gesprekken (gearchiveerde tonen)',
1759
+ 'menu.archiveOnly': 'Alleen gearchiveerd',
1705
1760
  'wsPreset.title': 'Standaardpreset van workspace wijzigen',
1706
1761
  'wsPreset.current': 'Huidige standaardpreset',
1707
1762
  'wsPreset.currentUnknown': 'Huidige preset onbekend',
@@ -1865,6 +1920,11 @@ window.__ModuleLoader__.load({
1865
1920
  'menu.moveOutGroup': 'Przenieś poza grupę',
1866
1921
  'menu.sessionId': 'Kopiuj ID sesji',
1867
1922
  'menu.workspacePreset': 'Domyślny preset obszaru roboczego…',
1923
+ 'menu.archiveFilter': 'Filtruj sesje',
1924
+ 'menu.archiveFollow': 'Zgodnie z globalnymi',
1925
+ 'menu.archiveHide': 'Ukryj zarchiwizowane',
1926
+ 'menu.archiveShow': 'Wszystkie rozmowy (pokaż zarchiwizowane)',
1927
+ 'menu.archiveOnly': 'Tylko zarchiwizowane',
1868
1928
  'wsPreset.title': 'Zmień domyślny preset obszaru roboczego',
1869
1929
  'wsPreset.current': 'Aktualny domyślny preset',
1870
1930
  'wsPreset.currentUnknown': 'Aktualny preset nieznany',
@@ -2028,6 +2088,11 @@ window.__ModuleLoader__.load({
2028
2088
  'menu.moveOutGroup': 'Remover do grupo',
2029
2089
  'menu.sessionId': 'Copiar ID da sessão',
2030
2090
  'menu.workspacePreset': 'Preset padrão do workspace…',
2091
+ 'menu.archiveFilter': 'Filtrar sessões',
2092
+ 'menu.archiveFollow': 'Seguir o global',
2093
+ 'menu.archiveHide': 'Ocultar arquivadas',
2094
+ 'menu.archiveShow': 'Todas as conversas (mostrar arquivadas)',
2095
+ 'menu.archiveOnly': 'Somente arquivadas',
2031
2096
  'wsPreset.title': 'Alterar o preset padrão do workspace',
2032
2097
  'wsPreset.current': 'Preset padrão atual',
2033
2098
  'wsPreset.currentUnknown': 'Preset atual desconhecido',
@@ -2191,6 +2256,11 @@ window.__ModuleLoader__.load({
2191
2256
  'menu.moveOutGroup': 'Убрать из группы',
2192
2257
  'menu.sessionId': 'Копировать ID сессии',
2193
2258
  'menu.workspacePreset': 'Пресет воркспейса по умолчанию…',
2259
+ 'menu.archiveFilter': 'Фильтровать сеансы',
2260
+ 'menu.archiveFollow': 'Как в общем',
2261
+ 'menu.archiveHide': 'Скрыть архивные',
2262
+ 'menu.archiveShow': 'Все разговоры (показать архивные)',
2263
+ 'menu.archiveOnly': 'Только архивные',
2194
2264
  'wsPreset.title': 'Изменить пресет воркспейса по умолчанию',
2195
2265
  'wsPreset.current': 'Текущий пресет по умолчанию',
2196
2266
  'wsPreset.currentUnknown': 'Текущий пресет неизвестен',
@@ -2354,6 +2424,11 @@ window.__ModuleLoader__.load({
2354
2424
  'menu.moveOutGroup': 'Flytta ut ur gruppen',
2355
2425
  'menu.sessionId': 'Kopiera sessions-ID',
2356
2426
  'menu.workspacePreset': 'Standardförinställning för arbetsyta…',
2427
+ 'menu.archiveFilter': 'Filtrera sessioner',
2428
+ 'menu.archiveFollow': 'Följ globalt',
2429
+ 'menu.archiveHide': 'Dölj arkiverade',
2430
+ 'menu.archiveShow': 'Alla konversationer (visa arkiverade)',
2431
+ 'menu.archiveOnly': 'Endast arkiverade',
2357
2432
  'wsPreset.title': 'Ändra standardförinställning för arbetsyta',
2358
2433
  'wsPreset.current': 'Aktuell standardförinställning',
2359
2434
  'wsPreset.currentUnknown': 'Aktuell förinställning okänd',
@@ -2517,6 +2592,11 @@ window.__ModuleLoader__.load({
2517
2592
  'menu.moveOutGroup': 'ย้ายออกจากกลุ่ม',
2518
2593
  'menu.sessionId': 'คัดลอก ID เซสชัน',
2519
2594
  'menu.workspacePreset': 'พรีเซ็ตเริ่มต้นของพื้นที่ทำงาน…',
2595
+ 'menu.archiveFilter': 'กรองเซสชัน',
2596
+ 'menu.archiveFollow': 'ตามการตั้งค่าทั่วไป',
2597
+ 'menu.archiveHide': 'ซ่อนที่เก็บถาวร',
2598
+ 'menu.archiveShow': 'บทสนทนาทั้งหมด (แสดงที่เก็บถาวร)',
2599
+ 'menu.archiveOnly': 'เฉพาะที่เก็บถาวร',
2520
2600
  'wsPreset.title': 'เปลี่ยนพรีเซ็ตเริ่มต้นของพื้นที่ทำงาน',
2521
2601
  'wsPreset.current': 'พรีเซ็ตเริ่มต้นปัจจุบัน',
2522
2602
  'wsPreset.currentUnknown': 'ไม่ทราบพรีเซ็ตปัจจุบัน',
@@ -2680,6 +2760,11 @@ window.__ModuleLoader__.load({
2680
2760
  'menu.moveOutGroup': 'Gruptan çıkar',
2681
2761
  'menu.sessionId': 'Oturum kimliğini kopyala',
2682
2762
  'menu.workspacePreset': 'Çalışma alanı varsayılan ön ayarı…',
2763
+ 'menu.archiveFilter': 'Oturumları filtrele',
2764
+ 'menu.archiveFollow': 'Geneli takip et',
2765
+ 'menu.archiveHide': 'Arşivlenenleri gizle',
2766
+ 'menu.archiveShow': 'Tüm konuşmalar (arşivlenenleri göster)',
2767
+ 'menu.archiveOnly': 'Yalnızca arşivlenenler',
2683
2768
  'wsPreset.title': 'Çalışma alanı varsayılan ön ayarını değiştir',
2684
2769
  'wsPreset.current': 'Geçerli varsayılan ön ayar',
2685
2770
  'wsPreset.currentUnknown': 'Geçerli ön ayar bilinmiyor',
@@ -2843,6 +2928,11 @@ window.__ModuleLoader__.load({
2843
2928
  'menu.moveOutGroup': 'Đưa ra khỏi nhóm',
2844
2929
  'menu.sessionId': 'Sao chép ID phiên',
2845
2930
  'menu.workspacePreset': 'Preset mặc định của không gian làm việc…',
2931
+ 'menu.archiveFilter': 'Lọc phiên',
2932
+ 'menu.archiveFollow': 'Theo toàn cục',
2933
+ 'menu.archiveHide': 'Ẩn đã lưu trữ',
2934
+ 'menu.archiveShow': 'Tất cả cuộc trò chuyện (hiện đã lưu trữ)',
2935
+ 'menu.archiveOnly': 'Chỉ đã lưu trữ',
2846
2936
  'wsPreset.title': 'Thay đổi preset mặc định của không gian làm việc',
2847
2937
  'wsPreset.current': 'Preset mặc định hiện tại',
2848
2938
  'wsPreset.currentUnknown': 'Không rõ preset hiện tại',
@@ -3006,6 +3096,11 @@ window.__ModuleLoader__.load({
3006
3096
  'menu.moveOutGroup': '移出分組',
3007
3097
  'menu.sessionId': '複製 Session ID',
3008
3098
  'menu.workspacePreset': '修改工作區預設…',
3099
+ 'menu.archiveFilter': '篩選會話',
3100
+ 'menu.archiveFollow': '跟隨全域',
3101
+ 'menu.archiveHide': '隱藏已封存',
3102
+ 'menu.archiveShow': '全部對話(顯示已封存)',
3103
+ 'menu.archiveOnly': '僅顯示已封存',
3009
3104
  'wsPreset.title': '修改工作區預設',
3010
3105
  'wsPreset.current': '目前預設',
3011
3106
  'wsPreset.currentUnknown': '目前預設未知',
@@ -3169,6 +3264,11 @@ window.__ModuleLoader__.load({
3169
3264
  'menu.moveOutGroup': '移出分組',
3170
3265
  'menu.sessionId': '複製 Session ID',
3171
3266
  'menu.workspacePreset': '修改工作區預設…',
3267
+ 'menu.archiveFilter': '篩選會話',
3268
+ 'menu.archiveFollow': '跟隨全域',
3269
+ 'menu.archiveHide': '隱藏已封存',
3270
+ 'menu.archiveShow': '全部對話(顯示已封存)',
3271
+ 'menu.archiveOnly': '僅顯示已封存',
3172
3272
  'wsPreset.title': '修改工作區預設',
3173
3273
  'wsPreset.current': '目前預設',
3174
3274
  'wsPreset.currentUnknown': '目前預設未知',
@@ -3332,6 +3432,11 @@ window.__ModuleLoader__.load({
3332
3432
  'menu.moveOutGroup': '移出分組',
3333
3433
  'menu.sessionId': '複製 Session ID',
3334
3434
  'menu.workspacePreset': '修改工作區預設…',
3435
+ 'menu.archiveFilter': '篩選工作階段',
3436
+ 'menu.archiveFollow': '跟隨全域',
3437
+ 'menu.archiveHide': '隱藏已封存',
3438
+ 'menu.archiveShow': '全部對話(顯示已封存)',
3439
+ 'menu.archiveOnly': '僅顯示已封存',
3335
3440
  'wsPreset.title': '修改工作區預設',
3336
3441
  'wsPreset.current': '目前預設',
3337
3442
  'wsPreset.currentUnknown': '目前預設未知',