dsh-better-workspace 0.36.14 → 0.37.1

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
@@ -123,6 +123,7 @@ DSH 的侧边栏浏览区是一个公开插槽 `sidebar.workspaces`(single),官
123
123
 
124
124
  - **dsh 0.1.6-alpha.1**:图标集与浏览器注入面都变了,本插件 **0.10.2 起自动适配**——图标网格只列本宿主真正导出的字形(退役的 `IconSendOutline16` 自动落到等价的 `IconSendOutline14`,已保存的旧选择不会变成空图标位),会话拖拽排序在宿主不再注入 `insertSessionBefore` 时改用浏览器本地顺序,**功能不丢**。升级 dsh 与升级插件谁先谁后都收敛。
125
125
  - **dsh 0.1.6-alpha.2**:设置页重组——本插件 **0.12.0 起双座位**注册设置卡片(旧宿主的 设置→插件 卡片 + 新宿主 插件面板 bundle 页,按包名挂载);工作区树新增**磁盘目录嵌套层**(官方 workspace-tree 语义),添加工作区回归官方目录流(原生选择器 / 官方应用内浏览器)。
126
+ - **dsh 0.2.2-alpha.2**:自绘会话行渲染官方 `sidebar.session.row.trailing` 行尾座位(时间之后、置顶角标之前;空会话不渲染),官方实验性 worktree / PR 图标因此在插件接管侧栏后仍能出现;同时接受官方的空白会话复用语义(不传 `agentPreset` 时会复用同工作区任意 preset 的空白会话)。该座位按能力探测:老宿主没有它时行尾照常渲染,不会因此报错。兼容下限保持 `>=0.1.6-alpha.2`。
126
127
  - **跨端**:web 与桌面共用同一套客户端资产;外观 / 开关可经设置卡片手动跨端同步,**折叠状态与会话本地序每端本地**(设计如此)。
127
128
 
128
129
  ## 限制与路线图
package/README_EN.md CHANGED
@@ -100,6 +100,7 @@ Same `dsh-better-*` family, zero overlap: [dsh-better-sidebar](https://github.co
100
100
 
101
101
  - **dsh 0.1.6-alpha.1**: both the primitives icon set and the browser injection face changed; this plugin **adapts automatically since 0.10.2**. The icon grid only lists glyphs this host actually exports (the retired `IconSendOutline16` resolves to the equivalent `IconSendOutline14`, so a previously saved choice never turns into an empty icon slot), and session drag-to-reorder falls back to a browser-local order when the host no longer injects `insertSessionBefore` — **no feature is lost**. Either upgrade order (plugin first or dsh first) converges.
102
102
  - **dsh 0.1.6-alpha.2**: the settings pages were reworked — since **0.12.0** this plugin registers its settings card on **both seats** (the pre-alpha.2 Settings → Plugins card and the alpha.2+ Plugins panel's bundle page, keyed by package name); the tree gains the **disk-nesting layer** (official workspace-tree semantics) and add-workspace rides the official directory flow (native chooser / official in-app browser).
103
+ - **dsh 0.2.2-alpha.2**: the hand-drawn session rows now render the shipped `sidebar.session.row.trailing` seat (after the time, before the pin badge; blank rows skip it), so the official experimental worktree / PR icons still appear after this plugin takes over the sidebar. The plugin also accepts the host's blank-session reuse semantics (without `agentPreset`, a blank from any preset in the same workspace may be reused). The seat is capability-probed: hosts without it keep rendering the row tail and never error. The compatibility floor stays `>=0.1.6-alpha.2`.
103
104
  - **Across surfaces**: web and desktop share one set of client assets; appearance / switches sync manually through the settings card, while **collapse state and the local session order stay per-browser** by design.
104
105
 
105
106
  ## Limitations / roadmap
package/dsh.plugin.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "id": "dsh-external/dsh-better-workspace",
3
- "version": "0.36.14",
3
+ "version": "0.37.1",
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.36.14",
3
+ "version": "0.37.1",
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
@@ -4878,9 +4878,10 @@ window.__ModuleLoader__.load({
4878
4878
  // it is supposed to support.
4879
4879
  '.bw-row-count,.bw-row-time{-webkit-text-stroke-width:0}',
4880
4880
  '.bw-schedule-badge{flex:none;display:inline-flex;align-items:center;color:var(--dsw-alias-label-tertiary,#9a9a9a);margin:0 6px}',
4881
+ '.bw-row-trailing{flex:none;display:inline-flex;align-items:center;gap:6px;color:var(--dsw-alias-label-tertiary,#9a9a9a)}',
4881
4882
  '.bw-row-actions{flex:none;display:none;align-items:center;gap:15px}',
4882
4883
  '.bw-row:hover .bw-row-actions,.bw-row.menu-open .bw-row-actions{display:flex}',
4883
- '.bw-row:hover .bw-row-time,.bw-row:hover .bw-row-count,.bw-row:hover .bw-schedule-badge,.bw-row:hover .bw-pin-indicator,.bw-row.menu-open .bw-row-time,.bw-row.menu-open .bw-row-count,.bw-row.menu-open .bw-schedule-badge,.bw-row.menu-open .bw-pin-indicator{display:none}',
4884
+ '.bw-row:hover .bw-row-time,.bw-row:hover .bw-row-count,.bw-row:hover .bw-schedule-badge,.bw-row:hover .bw-row-trailing,.bw-row:hover .bw-pin-indicator,.bw-row.menu-open .bw-row-time,.bw-row.menu-open .bw-row-count,.bw-row.menu-open .bw-schedule-badge,.bw-row.menu-open .bw-row-trailing,.bw-row.menu-open .bw-pin-indicator{display:none}',
4884
4885
  '.bw-row-archived .bw-row-label{color:var(--dsw-alias-label-caption,#8a8a8a)}',
4885
4886
  '.bw-pin-indicator{flex:none;display:inline-flex;align-items:center;justify-content:center;width:16px;height:20px;color:var(--dsw-alias-label-caption,#adb2b8);margin:0 0 0 6px}',
4886
4887
  '.bw-overflow-row{display:block;width:100%;text-align:left;border:0;background:transparent;color:var(--dsw-alias-label-tertiary,#9a9a9a);font-size:12px;cursor:pointer;padding:4px 6px;font-family:inherit}',
@@ -6306,6 +6307,22 @@ window.__ModuleLoader__.load({
6306
6307
  t: scheduleSeat.t,
6307
6308
  }))
6308
6309
  : null
6310
+ // Official alpha.2 row-trailing strip: a list seat nested INSIDE the
6311
+ // row, between the time cell and the pin marker, hidden while the hover
6312
+ // actions show. Officially populated by the experimental worktree/PR
6313
+ // icon; rendering it here keeps that surface visible in our sidebar.
6314
+ const trailingSeats = sessionActions && Array.isArray(sessionActions.trailingSeat)
6315
+ ? sessionActions.trailingSeat
6316
+ : []
6317
+ const trailingNode = !node.blank && trailingSeats.length > 0
6318
+ ? E('span', { className: 'bw-row-trailing' }, trailingSeats.map((seat, index) => E(QuietBoundary, {
6319
+ key: 'trailing-seat-' + index,
6320
+ }, E(ShippedSeatOccupant, {
6321
+ seat,
6322
+ ownerProps: { sessionId: node.id },
6323
+ t: seat.t,
6324
+ }))))
6325
+ : null
6309
6326
  // Official mirror surface (dsh 0.1.7 Rows.tsx): pinned rows carry the
6310
6327
  // pin marker; archived rows render grayed and never open; the hover
6311
6328
  // strip hosts the "..." trigger and the pin/archive quick buttons.
@@ -6410,6 +6427,7 @@ window.__ModuleLoader__.load({
6410
6427
  // Official blank rows carry no time, no pin, no actions (a standing
6411
6428
  // "new session" placeholder, not a session).
6412
6429
  !node.blank ? E('span', { className: 'bw-row-time' }, timeLabel(node.updatedAt, now, t)) : null,
6430
+ trailingNode,
6413
6431
  !node.blank && node.pinned ? E('span', { className: 'bw-pin-indicator', role: 'img', 'aria-label': pinnedTitle || undefined, title: pinnedTitle || undefined }, icon('IconPinFillRegular', 13)) : null,
6414
6432
  strip,
6415
6433
  )
@@ -7863,6 +7881,7 @@ window.__ModuleLoader__.load({
7863
7881
  // off the ledger like the schedule mark.
7864
7882
  const seatEntriesOf = typeof seatEntriesReader === 'function' ? seatEntriesReader : null
7865
7883
  const rowActionSeat = seatEntriesOf ? seatEntriesOf('sidebar.workspaces.session.row.action') : []
7884
+ const trailingSeat = seatEntriesOf ? seatEntriesOf('sidebar.session.row.trailing') : []
7866
7885
  const hoverSeat = seatEntriesOf ? seatEntriesOf('sidebar.session.row.hover') : []
7867
7886
  /** Effective catalog row of one shipped command (current keybinding, label). */
7868
7887
  const shortcutRowOf = (id) => {
@@ -8565,6 +8584,7 @@ window.__ModuleLoader__.load({
8565
8584
  // reproduction cannot supply); the context menu keeps every entry
8566
8585
  // through sessionMenuEntriesFor + handleCtxPick.
8567
8586
  rowActionSeat,
8587
+ trailingSeat,
8568
8588
  rename: (node) => setDialog({ kind: 'sess-rename', session: node }),
8569
8589
  hoverBody: (node, status) => sessionHoverBody(node, status),
8570
8590
  explainArchived: () => {
@@ -10617,29 +10637,6 @@ window.__ModuleLoader__.load({
10617
10637
 
10618
10638
  /* ---------------------------- render --------------------------- */
10619
10639
 
10620
- if (!wide) {
10621
- return E('div', { className: 'bw-rail' },
10622
- StyleNode(),
10623
- E('button', {
10624
- type: 'button',
10625
- className: 'bw-rail-btn',
10626
- 'aria-label': shortcutLabel(t('rail.search'), 'session.search'),
10627
- 'aria-keyshortcuts': shortcutAria('session.search'),
10628
- title: shortcutLabel(t('rail.search'), 'session.search'),
10629
- onClick: () => { expandSidebar(); setSearchOpen(true); setFocusPending(true) },
10630
- }, icon('IconSearchOutline16', 18)),
10631
- flowAvailable ? E('button', {
10632
- type: 'button',
10633
- className: 'bw-rail-btn',
10634
- 'aria-label': shortcutLabel(t('rail.add'), 'workspace.add'),
10635
- 'aria-keyshortcuts': shortcutAria('workspace.add'),
10636
- title: shortcutLabel(t('rail.add'), 'workspace.add'),
10637
- onClick: () => { expandSidebar(); startAddFlow() },
10638
- disabled: flowBusy,
10639
- }, icon('IconProjectAddOutline16', 18)) : null,
10640
- )
10641
- }
10642
-
10643
10640
  const dialogElement = (() => {
10644
10641
  if (dialog === null) return null
10645
10642
  if (dialog.kind === 'ws-rename') return E(TextDialog, {
@@ -10860,6 +10857,29 @@ window.__ModuleLoader__.load({
10860
10857
  // definition: the ref is the one stable handle it can call.
10861
10858
  startAddFlowRef.current = startAddFlow
10862
10859
 
10860
+ if (!wide) {
10861
+ return E('div', { className: 'bw-rail' },
10862
+ StyleNode(),
10863
+ E('button', {
10864
+ type: 'button',
10865
+ className: 'bw-rail-btn',
10866
+ 'aria-label': shortcutLabel(t('rail.search'), 'session.search'),
10867
+ 'aria-keyshortcuts': shortcutAria('session.search'),
10868
+ title: shortcutLabel(t('rail.search'), 'session.search'),
10869
+ onClick: () => { expandSidebar(); setSearchOpen(true); setFocusPending(true) },
10870
+ }, icon('IconSearchOutline16', 18)),
10871
+ flowAvailable ? E('button', {
10872
+ type: 'button',
10873
+ className: 'bw-rail-btn',
10874
+ 'aria-label': shortcutLabel(t('rail.add'), 'workspace.add'),
10875
+ 'aria-keyshortcuts': shortcutAria('workspace.add'),
10876
+ title: shortcutLabel(t('rail.add'), 'workspace.add'),
10877
+ onClick: () => { expandSidebar(); startAddFlow() },
10878
+ disabled: flowBusy,
10879
+ }, icon('IconProjectAddOutline16', 18)) : null,
10880
+ )
10881
+ }
10882
+
10863
10883
  // v0.18.0 — "drag it OUT" must never land on nothing. The row level
10864
10884
  // already covers the workspace row and the root-level session rows; this
10865
10885
  // catches everything else (the empty space below the tree, the header