dsh-plugin-core-demo 0.6.1 → 0.7.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.
Files changed (2) hide show
  1. package/dist/client.js +347 -138
  2. package/package.json +1 -1
package/dist/client.js CHANGED
@@ -211,7 +211,7 @@ var CHIP_CSS = "\n/* \u4E09\u6761\u5C40\u90E8\u53D8\u91CF\u627F\u8F7D\u914D\u827
211
211
  var CODE_VIEWER_CSS = "/* CodeViewer\uFF08\u53EA\u8BFB CodeMirror \u67E5\u770B\u5668\uFF09\u6837\u5F0F\u3002\u7C7B\u540D\u56FA\u5B9A dshpc-cv*\uFF1B\u989C\u8272\u5403 --dshpc-* token\uFF0C\n \u6DF1\u8272\u7531 design \u7684 token \u6DF1\u8272\u6BB5\u81EA\u52A8\u751F\u6548\uFF08\u4E0D\u5199\u6B7B\u989C\u8272\u503C\uFF09\u3002 */\n.dshpc-cv{position:relative;display:flex;flex-direction:column;height:100%;min-height:0;}\n.dshpc-cv__copy{position:absolute;top:6px;right:6px;z-index:5;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;appearance:none;border:1px solid var(--dshpc-border,rgba(128,128,128,.35));border-radius:var(--dshpc-radius-sm,6px);background:var(--dshpc-surface-1,#fff);color:var(--dshpc-fg-2,rgba(128,128,128,.95));cursor:pointer;opacity:0;transition:opacity .12s var(--dshpc-ease,ease),background .12s,color .12s;}\n.dshpc-cv:hover .dshpc-cv__copy,.dshpc-cv__copy:focus-visible{opacity:1;}\n.dshpc-cv__copy:hover{background:var(--dshpc-hover,rgba(38,49,72,.06));color:var(--dshpc-fg,#1f2328);}\n.dshpc-cv__copy svg{width:16px;height:16px;}\n.dshpc-cv__editor{flex:1 1 auto;min-height:0;overflow:hidden;}\n.dshpc-cv__editor .cm-editor{height:100%;}\n.dshpc-cv__editor .cm-scroller{overflow:auto;}\n";
212
212
 
213
213
  // dist/ui/panel-dock-css.generated.js
214
- var PANEL_DOCK_CSS = "\n/* \u505C\u9760\u680F = **\u5E03\u5C40\u6210\u5458**\uFF0C\u4E0D\u662F\u6D6E\u5C42\uFF1A\u5B83\u5360\u5BBD\u5EA6\u3001\u628A\u4E3B\u533A\u771F\u6B63\u6324\u7A84\uFF08\u5144\u5F1F\u9879\u76EE 2026-09-28\uFF1A\n \u300C\u5206\u680F\u538B\u8FC7\u6765\uFF0C\u4E0D\u662F\u76D6\u4E0A\u53BB\u300D\uFF09\u3002\u6240\u4EE5\u8C03\u7528\u65B9\u5FC5\u987B\u628A\u5B83\u653E\u8FDB\u81EA\u5DF1\u7684 flex \u6839\u91CC\u3002 */\n.dshpc-dock{display:flex;flex:0 0 auto;align-self:stretch;min-width:0}\n\n/* \u5355\u680F\uFF1Asticky + 100vh \u8BA9\u5B83\u5728\u9875\u9762\u6EDA\u52A8\u65F6\u4FDD\u6301\u53EF\u89C1\uFF0C\u540C\u65F6\u4ECD\u7136\u5360\u5BBD\u5EA6\u3002\n \u26A0\uFE0F **\u672C\u6761\u523B\u610F\u4E0D\u8BBE z-index**\uFF1A\u5E03\u5C40\u6210\u5458\u4E00\u65E6\u5E26\u6B63 z-index\uFF0C\u5C31\u4F1A\u65E0\u6761\u4EF6\u538B\u8FC7\u5BBF\u4E3B portal \u5230 body \u7684\n \u5F39\u7A97\uFF08\u5144\u5F1F\u9879\u76EE 2026-10-05 \u771F\u673A\u4E8B\u6545\u300C\u4FA7\u8FB9\u680F\u76D6\u4F4F\u5BBF\u4E3B\u8BBE\u7F6E\u5F39\u7A97\u300D\uFF09\u3002\u5C42\u5E8F\u4EA4\u7ED9 DOM \u987A\u5E8F\u88C1\u51B3\u3002 */\n.dshpc-dock__panel{\n box-sizing:border-box;position:sticky;top:0;align-self:stretch;\n display:flex;flex-direction:column;flex:0 0 auto;\n /* \u9AD8\u5EA6\u9ED8\u8BA4\u89C6\u53E3\u9AD8\uFF08\u6574\u9875\u573A\u666F\uFF09\uFF1B\u5D4C\u5728\u5B9A\u9AD8\u5BB9\u5668\u91CC\u65F6\u7531\u8C03\u7528\u65B9\u7ED9 --dshpc-dock-h\uFF08\u5982 420px / 100%\uFF09\u3002 */\n height:var(--dshpc-dock-h,100vh);max-height:var(--dshpc-dock-h,100vh);min-width:0;\n background:var(--dshpc-surface-base);color:var(--dshpc-fg);\n border-left:1px solid var(--dshpc-border);\n box-shadow:var(--dshpc-shadow-2);\n}\n\n.dshpc-dock__head{\n flex:none;display:flex;align-items:center;gap:8px;\n /* \u53F3\u4FA7 34px = 8(\u8FB9\u8DDD) + 20(\u5173\u94AE) + 6(\u547C\u5438)\uFF1A\u7ED9\u7EDD\u5BF9\u5B9A\u4F4D\u7684\u5173\u94AE\u7559\u4F4D\uFF0C\u6807\u9898/extra \u4E0D\u4ECE\u5B83\u5E95\u4E0B\u94BB */\n padding:10px 34px 10px 14px;\n border-bottom:1px solid var(--dshpc-border-faint);\n}\n/* \u56FE\u6807\u4F4D / \u6807\u9898\u53F3\u4FA7\u7684\u5185\u5BB9\u4F4D\uFF1A\u6D88\u8D39\u65B9\u4F20 ReactNode\uFF0C\u53EF\u585E\u591A\u4E2A\uFF1B\u5E93\u53EA\u8D1F\u8D23\u6392\u5E03\uFF0C\u4E0D\u62A2\u5BBD\u5EA6\u3002 */\n.dshpc-dock__lead{display:inline-flex;align-items:center;gap:6px;flex:none;color:var(--dshpc-fg-2)}\n.dshpc-dock__extra{display:inline-flex;align-items:center;gap:6px;flex:none;margin-left:auto}\n/* \u81EA\u5B9A\u4E49\u5934\u90E8\uFF1A\u6574\u884C\u5F52\u8C03\u7528\u65B9 \u2014\u2014 \u4E0D\u52A0\u5185\u8FB9\u8DDD/\u8FB9\u6846/\u80CC\u666F\uFF0C\u4E5F\u4E0D\u7ED9\u5173\u94AE\u7559\u5185\u8054\u7A7A\u95F4\uFF08\u5173\u94AE\u662F\u7EDD\u5BF9\u5B9A\u4F4D\u7684\uFF09\u3002 */\n.dshpc-dock__head--custom{display:block;padding:0;border-bottom:none}\n.dshpc-dock__title{\n flex:1 1 auto;min-width:0;\n overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\n font-size:var(--dshpc-font-md);font-weight:600;\n}\n/* \u5173\u95ED\u94AE\uFF1A20\xD720 \u65B9\u89D2\u56FE\u6807\u4F4D\uFF08\u4E0E Modal \u7684\u5173\u95ED\u94AE\u540C\u89C4\u683C\uFF0C\u4E0D\u501F Picker \u89E6\u53D1\u5668\u76AE\u80A4\uFF09\u3002 */\n.dshpc-dock__close{\n display:inline-flex;align-items:center;justify-content:center;flex:none;\n width:20px;height:20px;padding:0;border:none;border-radius:var(--dshpc-radius-sm);\n background:transparent;color:var(--dshpc-fg-3);\n font-family:inherit;font-size:13px;line-height:1;cursor:pointer;\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-dock__close:hover{background:var(--dshpc-hover);color:var(--dshpc-fg)}\n.dshpc-dock__close:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n/* \u5934\u90E8\u5173\u94AE\uFF1A\u7EDD\u5BF9\u5B9A\u4F4D\uFF0C\u4F4D\u7F6E\u4E0E\u5185\u7F6E\u5934\u5B8C\u5168\u4E00\u81F4\uFF08top 10 / right 8\uFF09\uFF1B\u81EA\u5B9A\u4E49\u5934\u4E5F\u7528\u8FD9\u4E00\u4E2A\u4F4D\u7F6E\u3002\n \u951A\u70B9\u662F\u9762\u677F\u672C\u8EAB\uFF08position:sticky \u5373\u5B9A\u4F4D\u4E0A\u4E0B\u6587\uFF09\uFF0C\u4E0D\u5728\u6EDA\u52A8\u5185\u5BB9\u91CC\uFF0C\u6240\u4EE5\u6B63\u6587\u6EDA\u52A8\u5B83\u4E0D\u8DDF\u6EDA\u3002 */\n.dshpc-dock__close--abs{position:absolute;top:10px;right:8px;z-index:8}\n/* \u6D6E\u52A8\u5173\u94AE\uFF1A\u65E0\u5934\u90E8\u9762\u677F\u7528\uFF0C\u7565\u6536\u4E00\u70B9\u8FB9\u8DDD\u3002 */\n.dshpc-dock__close--floating{\n position:absolute;top:6px;right:6px;z-index:8;\n background:var(--dshpc-surface-menu);border:1px solid var(--dshpc-border-faint);\n}\n\n/* \u5185\u5BB9\u533A\u81EA\u5DF1\u6EDA\uFF1A\u9762\u677F\u9AD8\u5EA6\u9501 100vh\uFF0C\u5185\u5BB9\u4E0D\u8BBE\u5185\u90E8\u6EDA\u52A8\u5C31\u4F1A\u628A\u6574\u9875\u6491\u9AD8\u3002 */\n.dshpc-dock__body{flex:1 1 auto;min-height:0;overflow:auto}\n\n/* \u62D6\u62FD\u6761\uFF1A\u5DE6\u7F18 6px \u547D\u4E2D\u533A\uFF0C**\u4E0D\u753B\u7EBF**\uFF0Chover/\u6309\u4F4F\u65F6\u624D\u6D6E\u51FA\u4E00\u6761\u6D45\u8272\u5E26\u3002\n z-index 7 \u5FC5\u987B\u9AD8\u4E8E\u9762\u677F\u5185\u5BB9\u91CC\u7684\u6D6E\u5C42\uFF08\u590D\u5236\u94AE\u4E00\u7C7B\uFF09\uFF0C\u5426\u5219\u547D\u4E2D\u533A\u4F1A\u88AB\u5185\u5BB9\u76D6\u4F4F\u3002 */\n.dshpc-dock__resizer{\n position:absolute;left:0;top:0;bottom:0;width:6px;\n z-index:7;cursor:col-resize;background:transparent;\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n/* hover/\u6309\u4F4F\uFF1A\u4E0D\u586B\u7070\u5E26\uFF0C\u6539\u4E3A\u5B98\u65B9 work \u533A\u6307\u793A\u6761\u6837\u5F0F \u2014\u2014 \u5DE6\u7F18 2px \u84DD\u7AD6\u6761\u3001\u4E0A\u4E0B\u6E10\u9690\n \uFF08\u989C\u8272\u8D70 business \u84DD\u7684\u5B98\u65B9 alias\uFF0C\u660E\u6697\u81EA\u52A8\u8DDF\u968F\u5BBF\u4E3B\uFF1B\u547D\u4E2D\u533A\u4ECD\u662F 6px \u4E0D\u53D8\uFF09\u3002 */\n.dshpc-dock__resizer:hover,.dshpc-dock__resizer:active{\n background:linear-gradient(180deg,transparent,var(--dshpc-business) 30%,var(--dshpc-business) 70%,transparent) left center / 1px 100% no-repeat;\n}\n\n/* \u62D6\u52A8\u671F\uFF1A\u2460 <iframe>\uFF08PDF / HTML \u9884\u89C8\uFF09\u662F\u72EC\u7ACB\u6587\u6863\uFF0C\u4F1A\u541E\u6389\u7236\u6587\u6863\u7684 pointermove\uFF0C\n \u5411\u53F3\u62D6\u8FDB iframe \u5C31\u5361\u6B7B \u2014\u2014 \u6574\u7247\u8BA9\u51FA\u6307\u9488\u4E8B\u4EF6\uFF1B\u2461 contain \u628A\u91CD\u6392\u9694\u79BB\u5728\u680F\u5185\uFF0C\n \u5426\u5219\u6BCF\u5E27\u6539\u5BBD\u5EA6\u90FD\u4F1A\u7275\u52A8\u6574\u9875\u91CD\u6392\uFF08\u5144\u5F1F\u9879\u76EE 2026-10-04 \u771F\u673A\u300C\u632A\u5F88\u4E45\u624D\u52A8\u4E00\u4E0B\u300D\uFF09\u3002 */\n.dshpc-dock.dshpc-dock--resizing iframe{pointer-events:none}\n.dshpc-dock.dshpc-dock--resizing .dshpc-dock__panel{contain:layout paint;will-change:width}\n";
214
+ var PANEL_DOCK_CSS = "\n/* \u505C\u9760\u680F = **\u5E03\u5C40\u6210\u5458**\uFF0C\u4E0D\u662F\u6D6E\u5C42\uFF1A\u5B83\u5360\u5BBD\u5EA6\u3001\u628A\u4E3B\u533A\u771F\u6B63\u6324\u7A84\uFF08\u5144\u5F1F\u9879\u76EE 2026-09-28\uFF1A\n \u300C\u5206\u680F\u538B\u8FC7\u6765\uFF0C\u4E0D\u662F\u76D6\u4E0A\u53BB\u300D\uFF09\u3002\u6240\u4EE5\u8C03\u7528\u65B9\u5FC5\u987B\u628A\u5B83\u653E\u8FDB\u81EA\u5DF1\u7684 flex \u6839\u91CC\u3002 */\n.dshpc-dock{display:flex;flex:0 0 auto;align-self:stretch;min-width:0}\n/* \u5F00\u7740\u65F6\u7ED9\u4E3B\u533A\u6EDA\u52A8\u6761\u8BA9\u51FA\u4E00\u6761\u7F1D\uFF1A\u6EDA\u52A8\u6761\u8D34\u6B7B\u5206\u9694\u7EBF\u5F88\u96BE\u770B\uFF08\u7528\u6237 2026-10-28\uFF0C\u5BF9\u9F50\n dsh-better-sidebar \u7684\u7559\u767D\uFF09\u3002\u5168\u5173\u65F6\u6574\u6761 dock \u9000\u51FA\uFF0C\u7F1D\u9699\u4E00\u8D77\u6D88\u5931\u3001\u4E0D\u7559\u767D\u8FB9\u3002\n \u7F1D\u5BBD\u53EF\u7531\u8C03\u7528\u65B9\u76D6 --dshpc-dock-gap\uFF1BTS \u4FA7\u7684\u8BA9\u4F4D\u91CF\uFF08DOCK_GAP\uFF09\u8981\u4E0E\u5B83\u4E00\u81F4\u3002 */\n.dshpc-dock--open{margin-left:var(--dshpc-dock-gap,1px)}\n\n/* \u81EA\u52A8\u52A0\u7684\u5BBF\u4E3B\u884C\uFF08openFilePreview \u52A0 / \u5173\u95ED\u5373\u6458\uFF09\uFF1A\u6D88\u8D39\u65B9\u90A3\u884C\u4E0D\u5FC5\u81EA\u5DF1\u5199 flex\u3002\n \u53EA\u8BA9\u300C\u7B2C\u4E00\u4E2A\u975E\u9884\u89C8\u5B50\u9879\u300D\u5F53\u4E3B\u533A\u4F38\u5C55\uFF0C\u5176\u4F59\u76F4\u63A5\u5B50\u9879\u4E0D\u52A8\uFF08\u9875\u811A\u6761\u3001\u5DE5\u5177\u6761\u4E0D\u8BEF\u4F24\uFF09\uFF1B\n display \u4E0D\u5728\u8FD9\u91CC\u5199\u6B7B \u2014\u2014 \u672C\u6765\u5C31\u662F grid \u7B49\u5E03\u5C40\u7684\u5143\u7D20\u4FDD\u6301\u539F\u6837\uFF0C\u7531 TS \u4FA7\u6309\u8BA1\u7B97\u503C\u8865 flex\u3002 */\n.dshpc-dock-host{min-width:0;min-height:0}\n.dshpc-dock-host>:not([data-dshpc-file-preview]){min-width:0}\n.dshpc-dock-host>:first-child:not([data-dshpc-file-preview]){flex:1 1 auto}\n\n/* \u5355\u680F\uFF1Asticky + 100vh \u8BA9\u5B83\u5728\u9875\u9762\u6EDA\u52A8\u65F6\u4FDD\u6301\u53EF\u89C1\uFF0C\u540C\u65F6\u4ECD\u7136\u5360\u5BBD\u5EA6\u3002\n \u26A0\uFE0F **\u672C\u6761\u523B\u610F\u4E0D\u8BBE z-index**\uFF1A\u5E03\u5C40\u6210\u5458\u4E00\u65E6\u5E26\u6B63 z-index\uFF0C\u5C31\u4F1A\u65E0\u6761\u4EF6\u538B\u8FC7\u5BBF\u4E3B portal \u5230 body \u7684\n \u5F39\u7A97\uFF08\u5144\u5F1F\u9879\u76EE 2026-10-05 \u771F\u673A\u4E8B\u6545\u300C\u4FA7\u8FB9\u680F\u76D6\u4F4F\u5BBF\u4E3B\u8BBE\u7F6E\u5F39\u7A97\u300D\uFF09\u3002\u5C42\u5E8F\u4EA4\u7ED9 DOM \u987A\u5E8F\u88C1\u51B3\u3002 */\n.dshpc-dock__panel{\n box-sizing:border-box;position:sticky;top:0;align-self:stretch;\n display:flex;flex-direction:column;flex:0 0 auto;\n /* \u9AD8\u5EA6\u9ED8\u8BA4\u89C6\u53E3\u9AD8\uFF08\u6574\u9875\u573A\u666F\uFF09\uFF1B\u5D4C\u5728\u5B9A\u9AD8\u5BB9\u5668\u91CC\u65F6\u7531\u8C03\u7528\u65B9\u7ED9 --dshpc-dock-h\uFF08\u5982 420px / 100%\uFF09\u3002 */\n height:var(--dshpc-dock-h,100vh);max-height:var(--dshpc-dock-h,100vh);min-width:0;\n background:var(--dshpc-surface-base);color:var(--dshpc-fg);\n border-left:1px solid var(--dshpc-border);\n transition:border-color var(--dshpc-dur-fast) var(--dshpc-ease);\n box-shadow:var(--dshpc-shadow-2);\n /* \u5165\u573A\uFF1A\u4ECE 0 \u5BBD\u6ED1\u51FA\u6765\uFF08keyframes \u53EA\u5199 from\uFF0C\u7EC8\u70B9\u53D6\u5185\u8054 width\uFF09\uFF0C\u6253\u5F00 / \u8033\u6735\u5C55\u5F00\u90FD\u8D70\u8FD9\u6761\u3002 */\n animation:dshpc-dock-in .22s var(--dshpc-ease);\n}\n/* overflow:hidden \u53EA\u5728\u52A8\u753B\u524D\u6BB5\uFF08\u79BB\u6563\u5C5E\u6027\u5728 50% \u7FFB\u8F6C\uFF09\u2014\u2014\u5E73\u65F6\u4E0D\u80FD\u88C1\uFF0C\u5426\u5219\u6302\u5728\u5DE6\u7F18\u5916\u7684\n \u6536\u8D77\u94AE\u4F1A\u88AB\u5207\u6389\u4E00\u534A\u3002 */\n@keyframes dshpc-dock-in{from{width:0;opacity:0;overflow:hidden}}\n/* \u6536\u8D77\u7684\u51FA\u573A\uFF1A\u5BBD\u5EA6\u6536\u5230 0\u3001\u900F\u660E\u6DE1\u51FA\uFF1B\u843D\u5B9A\u540E\u7EC4\u4EF6\u624D\u771F\u6B63\u6458\u6389\u8FD9\u4E00\u680F\uFF08JS \u5EF6\u65F6 220ms \u914D\u5408\uFF09\u3002 */\n.dshpc-dock__panel--closing{\n width:0!important;min-width:0!important;opacity:0;border-left-width:0;\n transition:width .2s var(--dshpc-ease),opacity .2s var(--dshpc-ease),border-left-width .2s var(--dshpc-ease);\n}\n\n.dshpc-dock__head{\n flex:none;display:flex;align-items:center;gap:8px;\n /* \u53F3\u4FA7 34px = 8(\u8FB9\u8DDD) + 20(\u5173\u94AE) + 6(\u547C\u5438)\uFF1A\u7ED9\u7EDD\u5BF9\u5B9A\u4F4D\u7684\u5173\u94AE\u7559\u4F4D\uFF0C\u6807\u9898/extra \u4E0D\u4ECE\u5B83\u5E95\u4E0B\u94BB */\n padding:10px 34px 10px 14px;\n border-bottom:1px solid var(--dshpc-border-faint);\n}\n/* \u56FE\u6807\u4F4D / \u6807\u9898\u53F3\u4FA7\u7684\u5185\u5BB9\u4F4D\uFF1A\u6D88\u8D39\u65B9\u4F20 ReactNode\uFF0C\u53EF\u585E\u591A\u4E2A\uFF1B\u5E93\u53EA\u8D1F\u8D23\u6392\u5E03\uFF0C\u4E0D\u62A2\u5BBD\u5EA6\u3002 */\n.dshpc-dock__lead{display:inline-flex;align-items:center;gap:6px;flex:none;color:var(--dshpc-fg-2)}\n.dshpc-dock__extra{display:inline-flex;align-items:center;gap:6px;flex:none;margin-left:auto}\n/* \u81EA\u5B9A\u4E49\u5934\u90E8\uFF1A\u6574\u884C\u5F52\u8C03\u7528\u65B9 \u2014\u2014 \u4E0D\u52A0\u5185\u8FB9\u8DDD/\u8FB9\u6846/\u80CC\u666F\uFF0C\u4E5F\u4E0D\u7ED9\u5173\u94AE\u7559\u5185\u8054\u7A7A\u95F4\uFF08\u5173\u94AE\u662F\u7EDD\u5BF9\u5B9A\u4F4D\u7684\uFF09\u3002 */\n.dshpc-dock__head--custom{display:block;padding:0;border-bottom:none}\n.dshpc-dock__title{\n flex:1 1 auto;min-width:0;\n overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\n font-size:var(--dshpc-font-md);font-weight:600;\n}\n/* \u5173\u95ED\u94AE\uFF1A20\xD720 \u65B9\u89D2\u56FE\u6807\u4F4D\uFF08\u4E0E Modal \u7684\u5173\u95ED\u94AE\u540C\u89C4\u683C\uFF0C\u4E0D\u501F Picker \u89E6\u53D1\u5668\u76AE\u80A4\uFF09\u3002 */\n.dshpc-dock__close{\n display:inline-flex;align-items:center;justify-content:center;flex:none;\n width:20px;height:20px;padding:0;border:none;border-radius:var(--dshpc-radius-sm);\n background:transparent;color:var(--dshpc-fg-3);\n font-family:inherit;font-size:13px;line-height:1;cursor:pointer;\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-dock__close:hover{background:var(--dshpc-hover);color:var(--dshpc-fg)}\n.dshpc-dock__close:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n/* \u5934\u90E8\u5173\u94AE\uFF1A\u7EDD\u5BF9\u5B9A\u4F4D\uFF0C\u4F4D\u7F6E\u4E0E\u5185\u7F6E\u5934\u5B8C\u5168\u4E00\u81F4\uFF08top 10 / right 8\uFF09\uFF1B\u81EA\u5B9A\u4E49\u5934\u4E5F\u7528\u8FD9\u4E00\u4E2A\u4F4D\u7F6E\u3002\n \u951A\u70B9\u662F\u9762\u677F\u672C\u8EAB\uFF08position:sticky \u5373\u5B9A\u4F4D\u4E0A\u4E0B\u6587\uFF09\uFF0C\u4E0D\u5728\u6EDA\u52A8\u5185\u5BB9\u91CC\uFF0C\u6240\u4EE5\u6B63\u6587\u6EDA\u52A8\u5B83\u4E0D\u8DDF\u6EDA\u3002 */\n.dshpc-dock__close--abs{position:absolute;top:10px;right:8px;z-index:8}\n/* \u6D6E\u52A8\u5173\u94AE\uFF1A\u65E0\u5934\u90E8\u9762\u677F\u7528\uFF0C\u7565\u6536\u4E00\u70B9\u8FB9\u8DDD\u3002 */\n.dshpc-dock__close--floating{\n position:absolute;top:6px;right:6px;z-index:8;\n background:var(--dshpc-surface-menu);border:1px solid var(--dshpc-border-faint);\n}\n\n/* \u5185\u5BB9\u533A\u81EA\u5DF1\u6EDA\uFF1A\u9762\u677F\u9AD8\u5EA6\u9501 100vh\uFF0C\u5185\u5BB9\u4E0D\u8BBE\u5185\u90E8\u6EDA\u52A8\u5C31\u4F1A\u628A\u6574\u9875\u6491\u9AD8\u3002 */\n.dshpc-dock__body{flex:1 1 auto;min-height:0;overflow:auto}\n\n/* \u62D6\u62FD\u6761\uFF1A\u5DE6\u7F18 6px \u547D\u4E2D\u533A\uFF0C**\u81EA\u5DF1\u4E0D\u753B\u4EFB\u4F55\u7EBF**\u3002\n hover / \u62D6\u52A8\u65F6\u628A\u9762\u677F\u81EA\u5DF1\u7684 border-left \u67D3\u6210\u84DD\uFF08\u7528\u6237 2026-10-28 \u56DB\u8F6E\uFF1A\u84DD\u7EBF\u53EA\u51C6\u6539\u539F\u7EBF\uFF0C\n \u4E0D\u51C6\u5728\u539F\u7EBF\u65C1\u8FB9\u52A0\u4E00\u6761 \u2014\u2014 \u4E4B\u524D\u5728 padding box \u5DE6\u7F18\u753B\u6E10\u53D8\uFF0C\u6B63\u597D\u53E0\u51FA\u53CC\u7EBF\uFF09\u3002\n \u547D\u4E2D\u533A\u5728 padding box \u4E0A\u3001border \u5728\u5B83\u5DE6\u5916\u4FA7\uFF0C\u6240\u4EE5\u53EA\u80FD\u6539\u9762\u677F\u7684 border \u8272\u3002\n z-index 7 \u5FC5\u987B\u9AD8\u4E8E\u9762\u677F\u5185\u5BB9\u91CC\u7684\u6D6E\u5C42\uFF08\u590D\u5236\u94AE\u4E00\u7C7B\uFF09\uFF0C\u5426\u5219\u547D\u4E2D\u533A\u4F1A\u88AB\u5185\u5BB9\u76D6\u4F4F\u3002 */\n.dshpc-dock__resizer{\n position:absolute;left:0;top:0;bottom:0;width:6px;\n z-index:7;cursor:col-resize;background:transparent;\n}\n.dshpc-dock__panel:has(> .dshpc-dock__resizer:hover),\n.dshpc-dock__panel--resizing{\n /* \u539F\u7EBF\u4FDD\u7559\u300C\u4E0A\u4E0B\u6E10\u9690\u300D\u5DE5\u4F5C\u533A\u6307\u793A\u6761\u8D28\u611F\uFF1A\u628A\u9762\u677F\u81EA\u5DF1\u7684 border-left \u6362\u6210\u540C\u6B3E\u6E10\u53D8\n \uFF08\u4E0D\u662F\u53E6\u52A0\u4E00\u6761\u7EBF\uFF09\u3002\u9762\u677F\u53EA\u6709\u8FD9\u4E00\u6761\u8FB9\u6846\u3001\u65E0\u5706\u89D2\uFF0C\u6240\u4EE5\u53EA\u4F5C\u7528\u5728\u7EBF\u4E0A\u3002 */\n border-image:linear-gradient(180deg,transparent,var(--dshpc-business) 30% 70%,transparent) 1;\n}\n\n/* \u62D6\u52A8\u671F\uFF1A\u2460 <iframe>\uFF08PDF / HTML \u9884\u89C8\uFF09\u662F\u72EC\u7ACB\u6587\u6863\uFF0C\u4F1A\u541E\u6389\u7236\u6587\u6863\u7684 pointermove\uFF0C\n \u5411\u53F3\u62D6\u8FDB iframe \u5C31\u5361\u6B7B \u2014\u2014 \u6574\u7247\u8BA9\u51FA\u6307\u9488\u4E8B\u4EF6\uFF1B\u2461 contain \u628A\u91CD\u6392\u9694\u79BB\u5728\u680F\u5185\uFF0C\n \u5426\u5219\u6BCF\u5E27\u6539\u5BBD\u5EA6\u90FD\u4F1A\u7275\u52A8\u6574\u9875\u91CD\u6392\uFF08\u5144\u5F1F\u9879\u76EE 2026-10-04 \u771F\u673A\u300C\u632A\u5F88\u4E45\u624D\u52A8\u4E00\u4E0B\u300D\uFF09\u3002 */\n.dshpc-dock.dshpc-dock--resizing iframe{pointer-events:none}\n.dshpc-dock.dshpc-dock--resizing .dshpc-dock__panel{contain:layout paint;will-change:width}\n\n/* \u6536\u8D77\u94AE\uFF1A**\u5F85\u5728\u9762\u677F\u81EA\u5DF1\u7684\u6846\u91CC**\uFF08\u7528\u6237 2026-10-28 \u4E09\u8F6E\uFF1A\u5360\u9762\u677F\u5185\u90E8\u7A7A\u95F4\uFF0C\u4E0D\u4F38\u5230\u5916\u9762\u53BB\uFF09\u3002\n left:0 \u4ECE\u5185\u4FA7\u8D34\u7740\u5206\u9694\u7EBF \u2014\u2014 \u8D34\u7EBF\u7684\u4E00\u8FB9\u4E0D\u63CF\u8FB9\uFF08\u7EBF\u662F\u9762\u677F\u81EA\u5DF1\u7684 border-left\uFF09\uFF0C\u9875\u7B7E\u4E0E\u7EBF\u4E0D\u91CD\u5408\u3002\n 20\xD744\uFF08\u7528\u6237 2026-10-28 \u56DB\u8F6E\u5B9A\u5C3A\u5BF8\uFF09\uFF1B\u5B9E\u8272\u5E95\uFF08--dshpc-plate\uFF0C\u660E\u6697\u5404\u6709\u5B9E\u503C\uFF09\uFF0Chover \u4EAE\u4E00\u6863\u3002\n padding-right:2px \u662F**\u89C6\u89C9\u5C45\u4E2D**\uFF1A\u53F3\u4FA7\u662F\u5706\u89D2\uFF0C\u7BAD\u5934\u5F80\u76F4\u7EBF\u90A3\u8FB9\u632A 1px\uFF08\u7528\u6237 2026-10-28 \u56DB\u8F6E\uFF09\u3002 */\n.dshpc-dock__collapse{\n position:absolute;left:0;top:50%;transform:translateY(-50%);\n z-index:8;display:inline-flex;align-items:center;justify-content:center;\n width:20px;height:44px;padding:0 2px 0 0;\n border-top:1px solid var(--dshpc-border);\n border-bottom:1px solid var(--dshpc-border);\n border-right:1px solid var(--dshpc-border);\n border-left:none;\n border-radius:0 var(--dshpc-radius-sm) var(--dshpc-radius-sm) 0;\n background:var(--dshpc-plate);color:var(--dshpc-fg-3);\n font-family:inherit;font-size:16px;line-height:1;cursor:pointer;\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-dock__collapse:hover{background:var(--dshpc-plate-hover);color:var(--dshpc-fg)}\n.dshpc-dock__collapse:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n\n/* \u6536\u8D77\u540E\u7684\u6D6E\u52A8\u8033\u6735\uFF1A**fixed \u8D34\u53F3\u7F18\u3001\u5782\u76F4\u5C45\u4E2D\u3001\u72EC\u7ACB\u4E8E\u5206\u680F**\uFF08\u7528\u6237 2026-10-28 \u5B9A\u7A3F\uFF1A\n \u5C0F\u9875\u7B7E\u6302\u4E2D\u95F4\u3001\u91CC\u9762\u653E\u9762\u677F\u56FE\u6807\u3001\u4E0D\u663E\u793A\u6587\u5B57\uFF0C\u7BAD\u5934\u4E0E\u6536\u8D77\u94AE\u53CD\u5411\uFF09\u3002\u591A\u4E2A\u6309\u6536\u8D77\u987A\u5E8F\u7EB5\u5411\u5806\u53E0\u3002\n z \u8D70 dock \u6863\uFF08\u4F4E\u4E8E\u5BBF\u4E3B\u5F39\u7A97\uFF09\uFF0C\u907F\u514D\u76D6\u4F4F\u5BBF\u4E3B portal \u5C42\u3002 */\n.dshpc-dock__ears{\n position:fixed;top:50%;right:0;transform:translateY(-50%);\n z-index:var(--dshpc-z-dock,1030);\n display:flex;flex-direction:column;gap:8px;align-items:flex-end;\n pointer-events:none;\n}\n.dshpc-dock__ear{\n pointer-events:auto;display:inline-flex;align-items:center;justify-content:center;\n /* \u4E0E\u6536\u8D77\u94AE**\u540C\u5C3A\u5BF8**\uFF0820\xD744\uFF0C\u7528\u6237 2026-10-28 \u56DB\u8F6E\uFF09\uFF1A\u4E0A/\u4E0B/\u5DE6\u63CF\u8FB9\uFF0C\u8D34\u53F3\u7F18\u7684\u4E00\u4FA7\u4E0D\u63CF\u3002\n \u5B9E\u8272\u5E95\uFF08--dshpc-plate\uFF09\uFF0C\u4E0D\u7528\u900F\u660E\u8272 \u2014\u2014 \u900F\u660E\u5E95\u4E0B\u900F\u51FA\u4E1C\u897F\u5F88\u96BE\u770B\u3002\n padding-left:2px \u662F**\u89C6\u89C9\u5C45\u4E2D**\uFF1A\u5DE6\u4FA7\u662F\u5706\u89D2\uFF0C\u7BAD\u5934\u5F80\u76F4\u7EBF\uFF08\u53F3\u7F18\uFF09\u90A3\u8FB9\u632A 1px\u3002 */\n width:20px;height:44px;box-sizing:border-box;padding:0 0 0 2px;\n border-top:1px solid var(--dshpc-border);\n border-bottom:1px solid var(--dshpc-border);\n border-left:1px solid var(--dshpc-border);\n border-right:none;\n border-radius:var(--dshpc-radius-sm) 0 0 var(--dshpc-radius-sm);\n background:var(--dshpc-plate);color:var(--dshpc-fg-2);\n cursor:pointer;font-family:inherit;line-height:1;\n animation:dshpc-ear-in .2s var(--dshpc-ease);\n transition:background-color var(--dshpc-dur-fast) var(--dshpc-ease),color var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n/* \u5165\u573A\uFF1A\u4ECE\u53F3\u7F18\u5916\u6ED1\u8FDB\u6765\uFF0C\u522B\u300C\u7A81\u7136\u51FA\u73B0\u300D\uFF08\u7528\u6237 2026-10-28\uFF09\u3002 */\n@keyframes dshpc-ear-in{from{opacity:0;transform:translateX(14px)}}\n.dshpc-dock__ear:hover{background:var(--dshpc-plate-hover);color:var(--dshpc-fg)}\n.dshpc-dock__ear:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:1px}\n/* \u4E0E\u6536\u8D77\u94AE\u7684\u7BAD\u5934\u540C\u4E00\u5B57\u53F7\uFF0816px\uFF09\uFF1A\u6536\u8FDB\u53BB\u524D\u540E\u7BAD\u5934\u4E00\u6A21\u4E00\u6837\u5927\uFF08\u7528\u6237 2026-10-28\uFF09\u3002 */\n.dshpc-dock__ear-arrow{font-size:16px;color:var(--dshpc-fg-3)}\n.dshpc-dock__ear:hover .dshpc-dock__ear-arrow{color:var(--dshpc-fg)}\n/* \u52A8\u6548\u793C\u8C8C\uFF1A\u7CFB\u7EDF\u58F0\u660E\u51CF\u5C11\u52A8\u6548\u65F6\u5168\u90E8\u5173\u6389\uFF08\u4E0E Segmented \u540C\u4E00\u7EA6\u5B9A\uFF09\uFF0C\u6536\u8D77\u9000\u5316\u4E3A\u77AC\u65F6\u3001\u529F\u80FD\u4E0D\u53D7\u5F71\u54CD\u3002 */\n@media (prefers-reduced-motion:reduce){\n .dshpc-dock__panel{animation:none}\n .dshpc-dock__panel--closing{transition:none}\n .dshpc-dock__ear{animation:none}\n}\n";
215
215
 
216
216
  // dist/explorer/explorer-css.generated.js
217
217
  var EXPLORER_CSS = "/* \u5DE5\u4F5C\u533A\u6587\u4EF6\u6D4F\u89C8\u5668\uFF08dshpc-fb-*\uFF09\u3002\n *\n * \u5EA6\u91CF\u771F\u6E90 = \u5144\u5F1F\u9879\u76EE dsh-task-dispatch-table \u7684 src/client/archive-session-css.ts\n * \uFF08.dsh-tdt-sv-* \u5168\u65CF\uFF09\u3002**\u9010\u6761\u7167\u6284\uFF0C\u4E0D\u8BB8\u81EA\u5DF1\u4F30**\uFF1Apadding / gap / \u5706\u89D2 / \u5B57\u53F7 / \u884C\u9AD8 /\n * \u8FB9\u6846\u8272 / \u60AC\u505C\u8272 / \u900F\u660E\u5EA6\u52A8\u753B / \u6EA2\u51FA\u7B56\u7565\uFF0C\u4E00\u4E00\u5BF9\u5E94\uFF0C\u6539\u8FD9\u91CC\u4E4B\u524D\u5148\u53BB\u90A3\u8FB9\u5BF9\u539F\u6587\u3002\n * \u524D\u7F00\u4E0E\u53D8\u91CF\u540D\u6362\u6210\u672C\u4ED3\u53E3\u5F84\uFF08--tdt-* \u2192 --dshpc-*\uFF09\uFF0C\u6570\u503C\u4E0D\u6362\u3002\n *\n * \u63A7\u4EF6\uFF1A\u80FD\u6838\u5FC3\u5C31\u6838\u5FC3\uFF08\u9762\u5305\u5C51 = Button ghost\u3001\u884C\u5C3E = Button outline\u3001\u5C55\u5F00 / \u56FE\u6807 = IconButton\u3001\n * \u5206\u6BB5 = Segmented\u3001\u6587\u5B57 = MarqueeText\uFF09\u3002\u6838\u5FC3\u63A7\u4EF6\u81EA\u5E26\u7684 padding / \u9AD8\u5EA6 / \u76AE\u80A4\u5728\u672C\u6587\u4EF6\u91CC\n * **\u6309\u5144\u5F1F\u6570\u503C\u8986\u76D6**\uFF08\u9009\u62E9\u5668\u5E26 .dshpc-fb \u524D\u7F00\u63D0\u9AD8\u7279\u5F02\u6027\uFF0C\u786E\u4FDD\u76D6\u5F97\u4F4F\u63A7\u4EF6\u9ED8\u8BA4\u503C\uFF09\u3002\n */\n.dshpc-fb{\n position:relative;display:flex;flex-direction:column;height:100%;min-height:0;\n background:var(--dshpc-surface-base);color:var(--dshpc-fg);\n}\n\n/* \u7B2C\u4E00\u6392\uFF1A\u25BE \u9009\u5C42 + \u9762\u5305\u5C51 + \u52A8\u4F5C\uFF08\u5144\u5F1F .dsh-tdt-sv-crumbbar\uFF09\n \u26A0\uFE0F \u4E0D\u80FD overflow:hidden \u2014\u2014 \u4E0B\u62C9\u6D6E\u5C42\u6302\u5728\u5B83\u4E0B\u9762\uFF0C\u88C1\u4E86\u5C31\u770B\u4E0D\u89C1\u3002 */\n.dshpc-fb__bar{\n position:relative;flex:none;display:flex;align-items:center;gap:2px;\n padding:4px 10px;border-bottom:1px solid var(--dshpc-border);white-space:nowrap;\n}\n.dshpc-fb__menu-wrap{position:relative;flex:none;display:inline-flex}\n.dshpc-fb__crumbs{position:relative;flex:1;min-width:0;display:flex;align-items:center;gap:2px;overflow:hidden}\n.dshpc-fb__crumbs-measure{\n position:absolute;top:0;left:0;display:inline-flex;align-items:center;gap:2px;\n visibility:hidden;pointer-events:none;white-space:nowrap;\n}\n\n/* \u9762\u5305\u5C51\uFF1A\u6838\u5FC3 ghost \u94AE\uFF0C\u4F46\u76AE\u80A4\u4E0E\u5C3A\u5BF8\u53D6\u5144\u5F1F .dsh-tdt-sv-crumb\uFF08\u9AD8\u7531\u5185\u5BB9\u51B3\u5B9A\uFF0C\u4E0D\u9501\u63A7\u5236\u9AD8\uFF09\u3002 */\n.dshpc-fb .dshpc-fb__crumb{\n appearance:none;background:0 0;border:none;height:auto;\n padding:2px 4px;border-radius:var(--dshpc-radius-sm);\n font:inherit;font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);\n color:var(--dshpc-fg-2);cursor:pointer;\n display:inline-flex;align-items:center;min-width:0;overflow:hidden;text-overflow:ellipsis;\n}\n.dshpc-fb .dshpc-fb__crumb:hover{background:var(--dshpc-hover);color:var(--dshpc-fg)}\n.dshpc-fb .dshpc-fb__crumb:disabled{color:var(--dshpc-fg-2);cursor:default}\n.dshpc-fb .dshpc-fb__crumb--current{cursor:default;color:var(--dshpc-fg);font-weight:600;min-width:0}\n.dshpc-fb .dshpc-fb__crumb--current:hover{background:0 0}\n.dshpc-fb__crumb-mq{flex:1 1 auto;min-width:0}\n.dshpc-fb__crumb-sep{flex:none;color:var(--dshpc-fg-3)}\n\n/* \u8D8A\u754C\uFF08outside-workspace\uFF09\u7B2C\u4E00\u6392\uFF1A\u53EA\u8BFB\u5B8C\u6574\u8DEF\u5F84\uFF08\u5144\u5F1F .dsh-tdt-sv-crumbbar-plain-inner\uFF09\u3002 */\n.dshpc-fb__bar-plain{\n font-family:var(--dshpc-font-mono,ui-monospace,SFMono-Regular,Menlo,Consolas,monospace);\n font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);color:var(--dshpc-fg-2);\n white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:default;user-select:none;\n}\n.dshpc-fb__actions{flex:none;display:flex;align-items:center;gap:4px}\n\n/* \u25BE \u9009\u5C42\u6D6E\u5C42\uFF08\u5144\u5F1F .dsh-tdt-sv-crumbs-*\uFF09\u3002\n \u5C42\u5E8F\uFF1A\u5144\u5F1F\u662F 30/31\uFF1B\u672C\u4ED3 picker \u9762\u677F\u662F 1100\uFF0C\u906E\u7F69\u5FC5\u987B\u9AD8\u4E8E\u5B83\uFF0C\u5426\u5219\u83DC\u5355\u5F00\u7740\u70B9\u9762\u677F\u4E0D\u7B97\u300C\u70B9\u5916\u90E8\u300D\u3002 */\n.dshpc-fb__crumbs-backdrop{position:fixed;inset:0;z-index:1200;background:transparent}\n.dshpc-fb__crumbs-menu{\n position:absolute;top:calc(100% + 4px);left:0;z-index:1201;min-width:160px;max-height:240px;overflow:auto;\n background:var(--dshpc-surface-menu);border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-sm);\n box-shadow:0 4px 16px rgba(0,0,0,.18);padding:4px;display:flex;flex-direction:column;\n}\n.dshpc-fb__menu-item{\n appearance:none;background:0 0;border:none;text-align:left;font:inherit;\n font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-md);\n padding:4px 8px;border-radius:var(--dshpc-radius-sm);color:var(--dshpc-fg);cursor:pointer;\n max-width:280px;display:flex;align-items:center;gap:2px;\n overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\n}\n.dshpc-fb__menu-item:hover{background:var(--dshpc-hover)}\n.dshpc-fb__menu-empty{\n font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-md);padding:4px 8px;color:var(--dshpc-fg-3);\n}\n.dshpc-fb__menu-icon{flex:none;display:inline-flex}\n.dshpc-fb__menu-chev{flex:none;color:var(--dshpc-fg-3);margin-right:1px}\n.dshpc-fb__menu-chev-slot{flex:none;width:11px;height:11px;margin-right:1px}\n.dshpc-fb__menu-label{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}\n\n/* \u7B2C\u4E8C\u6392\uFF08\u4EC5\u9884\u89C8\u6001\uFF09\uFF1A\u6587\u4EF6\u540D + \u5DE5\u5177\uFF08\u5144\u5F1F .dsh-tdt-sv-titlebar / -preview-title-inner\uFF09\u3002 */\n.dshpc-fb__title{\n flex:none;display:flex;align-items:center;gap:8px;\n padding:8px 14px;border-bottom:1px solid var(--dshpc-border);\n}\n.dshpc-fb__title-inner{\n font-family:var(--dshpc-font-mono,ui-monospace,SFMono-Regular,Menlo,Consolas,monospace);\n font-size:var(--dshpc-font-sm);line-height:var(--dshpc-line-sm);color:var(--dshpc-fg);\n white-space:nowrap;overflow:hidden;text-overflow:ellipsis;cursor:default;\n}\n\n/* \u4E3B\u4F53\uFF08\u5144\u5F1F .dsh-tdt-sv-preview-body / -hint / -preview-err\uFF09 */\n.dshpc-fb__body{flex:1;min-height:0;overflow-x:hidden;overflow-y:auto;padding:12px 14px}\n.dshpc-fb__note{font-size:var(--dshpc-font-sm);color:var(--dshpc-fg-2);text-align:center;padding:12px 0}\n.dshpc-fb__err{\n display:flex;flex-direction:column;align-items:flex-start;gap:10px;\n font-size:var(--dshpc-font-sm);line-height:1.6;color:var(--dshpc-fg-2);padding:8px 0;\n}\n\n/* \u76EE\u5F55\u6811\uFF08\u5144\u5F1F .dsh-tdt-sv-tree*\uFF09 */\n.dshpc-fb__tree{flex:1;min-height:0;overflow:auto;padding:6px 8px}\n.dshpc-fb__row{\n display:flex;align-items:center;gap:8px;padding:6px 8px;\n border-radius:var(--dshpc-radius-sm);cursor:pointer;user-select:none;\n}\n.dshpc-fb__row:hover{background:var(--dshpc-hover)}\n.dshpc-fb__row:focus-visible{outline:2px solid var(--dshpc-focus);outline-offset:-2px}\n.dshpc-fb__row-icon{flex:none;display:inline-flex;color:var(--dshpc-fg-2)}\n.dshpc-fb__row-name{\n flex:1;min-width:0;font-size:var(--dshpc-font-md);line-height:var(--dshpc-line-md);color:var(--dshpc-fg);\n overflow:hidden;text-overflow:ellipsis;white-space:nowrap;\n}\n\n/* \u5C55\u5F00\u5F00\u5173\uFF1A\u6838\u5FC3 IconButton\uFF0C\u547D\u4E2D\u4F4D 20\xD720 + \u5C55\u5F00\u65F6\u8F6C 90\xB0\uFF08\u5144\u5F1F .dsh-tdt-sv-tree-toggle{,-open}\uFF09\u3002 */\n.dshpc-fb .dshpc-fb__row-toggle{\n appearance:none;background:0 0;border:none;flex:none;\n width:20px;height:20px;padding:0;margin:0;border-radius:var(--dshpc-radius-sm);\n color:var(--dshpc-fg-2);cursor:pointer;\n display:inline-flex;align-items:center;justify-content:center;\n transition:transform var(--dshpc-dur-fast) var(--dshpc-ease),background var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-fb .dshpc-fb__row-toggle--open{transform:rotate(90deg)}\n\n/* \u884C\u5C3E\u300C\u8FDB\u5165 / \u9009\u62E9\u300D\uFF1A\u6838\u5FC3 outline \u94AE\uFF0C\u76AE\u80A4\u53D6\u5144\u5F1F .dsh-tdt-sv-tree-act\uFF08\u9AD8\u7531\u5185\u5BB9\u51B3\u5B9A\uFF09\u3002\n \u5E73\u65F6\u9690\u8EAB\u4F46\u5360\u4F4D\uFF08opacity \u800C\u975E display\uFF09\u21D2 \u51FA\u73B0\u65F6\u4E0D\u9876\u52A8\u884C\u5185\u5E03\u5C40\u3002 */\n.dshpc-fb .dshpc-fb__row-act{\n flex:none;margin-left:auto;appearance:none;background:0 0;\n border:1px solid var(--dshpc-border);border-radius:var(--dshpc-radius-sm);\n height:auto;padding:2px 8px;font-size:var(--dshpc-font-sm);line-height:1.4;\n color:var(--dshpc-fg-2);cursor:pointer;\n opacity:0;pointer-events:none;\n transition:opacity var(--dshpc-dur-fast) var(--dshpc-ease);\n}\n.dshpc-fb__row:hover .dshpc-fb__row-act,.dshpc-fb .dshpc-fb__row-act:focus-visible{opacity:1;pointer-events:auto}\n.dshpc-fb .dshpc-fb__row-act:hover{background:var(--dshpc-hover);color:var(--dshpc-fg)}\n\n.dshpc-fb__row-children{\n margin-left:9px;padding-left:7px;border-left:1px solid var(--dshpc-border);\n display:flex;flex-direction:column;\n}\n.dshpc-fb__row-note{flex:none;padding:8px 10px;font-size:var(--dshpc-font-sm);color:var(--dshpc-fg-3)}\n.dshpc-fb__row-err{padding:4px 8px 4px 36px;font-size:var(--dshpc-font-sm);color:var(--dshpc-danger)}\n\n/* \u9884\u89C8\u4F53\u5185\u90E8\u5BB9\u5668\uFF08\u4EC5\u672C\u4ED3\u9884\u89C8\u7EC4\u4EF6\u7528\uFF1B\u5144\u5F1F\u5BF9\u5E94 preview-fill / preview-body-code \u4E00\u7C7B\uFF09\u3002\n \u5FC5\u987B border-box\uFF1A\u6E32\u67D3\u6001 inline \u52A0\u4E86 padding:12px 14px\uFF0Ccontent-box \u4E0B width:100%+padding\n \u4F1A\u6EA2\u51FA\u7236\u5C42 28px\uFF08\u7236 .dshpc-fb \u65E0 overflow \u88C1\u5207\uFF09\u2192 \u6052\u591A\u4E00\u6761\u6A2A\u6EDA\u6761\uFF1Bborder-box \u628A padding\n \u7B97\u8FDB 100%\uFF0C\u4ECE\u6839\u6D88\u9664\u8BE5\u6EA2\u51FA\u3002 */\n.dshpc-fb__text{flex:1;min-height:0;overflow:auto;width:100%;box-sizing:border-box}\n.dshpc-fb__banner{padding:6px 10px;background:var(--dshpc-open-bg);color:var(--dshpc-fg-2);font-size:var(--dshpc-font-sm)}\n.dshpc-fb__more{display:flex;justify-content:center;padding:10px}\n.dshpc-fb__image{max-width:100%;border-radius:var(--dshpc-radius-sm);border:1px solid var(--dshpc-border)}\n/* iframe \u7684\u5916\u58F3\uFF08\u5144\u5F1F .dsh-tdt-sv-preview-fill\uFF09\uFF1Aiframe \u5FC5\u987B\u5305\u5728\u8FD9\u4E00\u5C42\u91CC\u624D\u62FF\u5F97\u5230\u9AD8\u5EA6\u2014\u2014\n \u88F8\u6302 iframe \u65F6\u66FF\u6362\u5143\u7D20\u7684\u81EA\u52A8\u6700\u5C0F\u5C3A\u5BF8\u4F1A\u8BA9\u9AD8\u5EA6\u7B97\u4E0D\u51FA\u6765\uFF08\u8868\u73B0\u4E3A\u9884\u89C8\u533A\u6574\u7247\u7A7A\u767D\u3001\u50CF\u6CA1\u53CD\u5E94\uFF09\u3002 */\n.dshpc-fb__fill{flex:1;min-height:0;display:flex;overflow:hidden;padding:0}\n.dshpc-fb__frame{flex:1;min-height:0;width:100%;height:100%;border:none;background:var(--dshpc-surface-1)}\n";
@@ -2870,6 +2870,8 @@ var DICT = {
2870
2870
  modalClose: "\u5173\u95ED",
2871
2871
  dockClose: "\u5173\u95ED\u9762\u677F",
2872
2872
  dockResize: "\u62D6\u52A8\u8C03\u6574\u5BBD\u5EA6",
2873
+ dockCollapse: "\u6536\u8D77\u9762\u677F",
2874
+ dockExpand: "\u5C55\u5F00\u9762\u677F",
2873
2875
  errorRetry: "\u91CD\u8BD5",
2874
2876
  confirm: "\u786E\u5B9A",
2875
2877
  cancel: "\u53D6\u6D88",
@@ -3126,6 +3128,8 @@ var DICT = {
3126
3128
  modalClose: "Close",
3127
3129
  dockClose: "Close panel",
3128
3130
  dockResize: "Drag to resize",
3131
+ dockCollapse: "Collapse panel",
3132
+ dockExpand: "Expand panel",
3129
3133
  errorRetry: "Retry",
3130
3134
  confirm: "Confirm",
3131
3135
  cancel: "Cancel",
@@ -4379,6 +4383,10 @@ var WorkspaceListStore = class {
4379
4383
  }
4380
4384
  };
4381
4385
  var workspaceList = new WorkspaceListStore();
4386
+ var workspaceFiles;
4387
+ function getWorkspaceFiles() {
4388
+ return workspaceFiles;
4389
+ }
4382
4390
  function isWorkspaceSource(value) {
4383
4391
  if (value === null || typeof value !== "object")
4384
4392
  return false;
@@ -4391,6 +4399,13 @@ function connectHost(ctx, options = {}) {
4391
4399
  if (isWorkspaceSource(source))
4392
4400
  workspaceList.setSource(source);
4393
4401
  });
4402
+ ctx.inject(["remote", "remote.workspaceFiles"], (sub) => {
4403
+ const rec = sub;
4404
+ const candidate = rec?.["remote.workspaceFiles"] ?? rec?.remote?.workspaceFiles;
4405
+ if (typeof candidate?.list === "function") {
4406
+ workspaceFiles = candidate;
4407
+ }
4408
+ });
4394
4409
  const modelsPath = options.modelsPath;
4395
4410
  if (modelsPath === void 0)
4396
4411
  return;
@@ -6358,7 +6373,7 @@ var import_react28 = require("react");
6358
6373
  // dist/ui/panel-dock-logic.js
6359
6374
  var DEFAULT_PANEL_ID = "default";
6360
6375
  function emptyDock() {
6361
- return { ids: [], widths: {} };
6376
+ return { ids: [], widths: {}, collapsed: [] };
6362
6377
  }
6363
6378
  function clampWidth(value, min2, max2) {
6364
6379
  const wide = Number.isFinite(value) ? value : min2;
@@ -6368,26 +6383,60 @@ function clampWidth(value, min2, max2) {
6368
6383
  function isOpen(state, id3) {
6369
6384
  return state.ids.includes(id3);
6370
6385
  }
6386
+ function isCollapsed(state, id3) {
6387
+ return state.collapsed.includes(id3);
6388
+ }
6371
6389
  function openPanel(state, id3, maxPanels) {
6372
6390
  if (isOpen(state, id3))
6373
6391
  return { state, result: { ok: true, id: id3, created: false } };
6374
6392
  if (state.ids.length >= maxPanels)
6375
6393
  return { state, result: { ok: false, id: id3, reason: "limit" } };
6376
- return { state: { ids: [...state.ids, id3], widths: state.widths }, result: { ok: true, id: id3, created: true } };
6394
+ return {
6395
+ state: {
6396
+ ids: [...state.ids, id3],
6397
+ widths: state.widths,
6398
+ collapsed: state.collapsed.filter((item) => item !== id3)
6399
+ },
6400
+ result: { ok: true, id: id3, created: true }
6401
+ };
6377
6402
  }
6378
6403
  function closePanel(state, id3) {
6379
- if (!isOpen(state, id3))
6404
+ const open = isOpen(state, id3);
6405
+ const ear = isCollapsed(state, id3);
6406
+ if (!open && !ear)
6380
6407
  return state;
6381
6408
  const widths = { ...state.widths };
6382
6409
  delete widths[id3];
6383
- return { ids: state.ids.filter((item) => item !== id3), widths };
6410
+ return {
6411
+ ids: open ? state.ids.filter((item) => item !== id3) : state.ids,
6412
+ widths,
6413
+ collapsed: ear ? state.collapsed.filter((item) => item !== id3) : state.collapsed
6414
+ };
6384
6415
  }
6385
6416
  function setPanelWidth(state, id3, width) {
6386
6417
  if (!isOpen(state, id3))
6387
6418
  return state;
6388
6419
  if (state.widths[id3] === width)
6389
6420
  return state;
6390
- return { ids: state.ids, widths: { ...state.widths, [id3]: width } };
6421
+ return { ids: state.ids, widths: { ...state.widths, [id3]: width }, collapsed: state.collapsed };
6422
+ }
6423
+ function collapsePanel(state, id3) {
6424
+ if (!isOpen(state, id3))
6425
+ return state;
6426
+ return {
6427
+ ids: state.ids.filter((item) => item !== id3),
6428
+ widths: state.widths,
6429
+ collapsed: state.collapsed.includes(id3) ? state.collapsed : [...state.collapsed, id3]
6430
+ };
6431
+ }
6432
+ function expandPanel(state, id3) {
6433
+ if (!isCollapsed(state, id3))
6434
+ return state;
6435
+ return {
6436
+ ids: state.ids.includes(id3) ? state.ids : [...state.ids, id3],
6437
+ widths: state.widths,
6438
+ collapsed: state.collapsed.filter((item) => item !== id3)
6439
+ };
6391
6440
  }
6392
6441
  function othersWidth(state, id3, fallbackOf) {
6393
6442
  return state.ids.reduce((sum, item) => {
@@ -6399,6 +6448,7 @@ function othersWidth(state, id3, fallbackOf) {
6399
6448
 
6400
6449
  // dist/ui/PanelDock.js
6401
6450
  var INSET_VAR = "--dshpc-page-inset-right";
6451
+ var DOCK_GAP = 1;
6402
6452
  var dockInsets = /* @__PURE__ */ new Map();
6403
6453
  var dockSeq = 0;
6404
6454
  function publishInset(key, width, el) {
@@ -6476,7 +6526,7 @@ function createPanelDock(options = {}) {
6476
6526
  return result;
6477
6527
  },
6478
6528
  close(id3 = DEFAULT_PANEL_ID, reason = "api") {
6479
- if (!isOpen(state, id3))
6529
+ if (!isOpen(state, id3) && !isCollapsed(state, id3))
6480
6530
  return;
6481
6531
  if (options.onBeforeClose?.({ id: id3, reason }) === false)
6482
6532
  return;
@@ -6490,9 +6540,26 @@ function createPanelDock(options = {}) {
6490
6540
  }
6491
6541
  return controller.open(id3);
6492
6542
  },
6543
+ collapse(id3 = DEFAULT_PANEL_ID) {
6544
+ if (!isOpen(state, id3))
6545
+ return;
6546
+ emit(collapsePanel(state, id3));
6547
+ },
6548
+ expand(id3 = DEFAULT_PANEL_ID) {
6549
+ if (!isCollapsed(state, id3))
6550
+ return;
6551
+ if (state.ids.length >= maxPanels) {
6552
+ options.onLimitReached?.({ id: id3 });
6553
+ return;
6554
+ }
6555
+ emit(expandPanel(state, id3));
6556
+ },
6493
6557
  isOpen(id3 = DEFAULT_PANEL_ID) {
6494
6558
  return isOpen(state, id3);
6495
6559
  },
6560
+ isCollapsed(id3 = DEFAULT_PANEL_ID) {
6561
+ return isCollapsed(state, id3);
6562
+ },
6496
6563
  ids() {
6497
6564
  return state.ids;
6498
6565
  },
@@ -6534,6 +6601,24 @@ function PanelDock(props) {
6534
6601
  const panes = panesOf(props.children);
6535
6602
  const { defaultWidth, minWidth: fallbackMin } = props.dock.defaults;
6536
6603
  const widthOf = (pane) => state.widths[pane.id] ?? clampWidth(pane.width ?? defaultWidth, pane.minWidth ?? fallbackMin, pane.maxWidth);
6604
+ const earLabelOf = (id3) => {
6605
+ const pane = panes.find((item) => item.id === id3);
6606
+ if (pane === void 0)
6607
+ return id3;
6608
+ if (typeof pane.title === "string")
6609
+ return pane.title;
6610
+ if (typeof pane.ariaLabel === "string")
6611
+ return pane.ariaLabel;
6612
+ return id3;
6613
+ };
6614
+ const [closing4, setClosing] = (0, import_react28.useState)([]);
6615
+ const collapseWithAnim = (id3) => {
6616
+ setClosing((prev) => prev.includes(id3) ? prev : [...prev, id3]);
6617
+ window.setTimeout(() => {
6618
+ setClosing((prev) => prev.filter((item) => item !== id3));
6619
+ props.dock.collapse(id3);
6620
+ }, 220);
6621
+ };
6537
6622
  const insetKey = (0, import_react28.useRef)("");
6538
6623
  if (insetKey.current === "")
6539
6624
  insetKey.current = `dock-${++dockSeq}`;
@@ -6543,7 +6628,7 @@ function PanelDock(props) {
6543
6628
  });
6544
6629
  const totalWidth = panes.filter((pane) => state.ids.includes(pane.id)).reduce((sum, pane) => sum + widthOf(pane), 0);
6545
6630
  (0, import_react28.useEffect)(() => {
6546
- publishInset(insetKey.current, totalWidth, rootRef.current);
6631
+ publishInset(insetKey.current, state.ids.length > 0 ? totalWidth + DOCK_GAP : 0, rootRef.current);
6547
6632
  });
6548
6633
  (0, import_react28.useEffect)(() => () => {
6549
6634
  publishInset(insetKey.current, 0, null);
@@ -6561,6 +6646,7 @@ function PanelDock(props) {
6561
6646
  const startWidth = widthOf(pane);
6562
6647
  const min2 = pane.minWidth ?? fallbackMin;
6563
6648
  const mainMin = props.mainMinWidth ?? 480;
6649
+ element.classList.add("dshpc-dock__panel--resizing");
6564
6650
  startResizeLayoutWidth({
6565
6651
  startEvent: event,
6566
6652
  root: rootRef.current,
@@ -6574,9 +6660,10 @@ function PanelDock(props) {
6574
6660
  },
6575
6661
  onMove: (width) => {
6576
6662
  element.style.width = `${width}px`;
6577
- publishInset(insetKey.current, restWidth(pane.id) + width, rootRef.current);
6663
+ publishInset(insetKey.current, restWidth(pane.id) + width + DOCK_GAP, rootRef.current);
6578
6664
  },
6579
6665
  onCommit: (width) => {
6666
+ element.classList.remove("dshpc-dock__panel--resizing");
6580
6667
  props.dock.setWidth(pane.id, width);
6581
6668
  }
6582
6669
  });
@@ -6616,30 +6703,69 @@ function PanelDock(props) {
6616
6703
  onClick: () => props.dock.close(pane.id, "button")
6617
6704
  }, pane.closeIcon ?? "\u2715");
6618
6705
  };
6619
- return (0, import_react28.createElement)("div", {
6620
- ref: rootRef,
6621
- className: props.className === void 0 ? "dshpc-dock" : `dshpc-dock ${props.className}`
6622
- }, panes.filter((pane) => state.ids.includes(pane.id)).map((pane) => (0, import_react28.createElement)("section", {
6623
- key: pane.id,
6624
- ref: (element) => {
6625
- if (element === null)
6626
- panelRefs.current.delete(pane.id);
6627
- else
6628
- panelRefs.current.set(pane.id, element);
6706
+ const rootClass = `dshpc-dock${state.ids.length > 0 ? " dshpc-dock--open" : ""}${props.className === void 0 ? "" : ` ${props.className}`}`;
6707
+ return (0, import_react28.createElement)(
6708
+ "div",
6709
+ {
6710
+ ref: rootRef,
6711
+ className: rootClass
6629
6712
  },
6630
- className: "dshpc-dock__panel",
6631
- style: { width: `${widthOf(pane)}px` },
6632
- "data-panel": pane.id,
6633
- "aria-label": pane.ariaLabel ?? (typeof pane.title === "string" ? pane.title : pane.id)
6634
- }, (0, import_react28.createElement)("div", {
6635
- className: "dshpc-dock__resizer",
6636
- role: "separator",
6637
- "aria-orientation": "vertical",
6638
- "aria-label": tt("dockResize"),
6639
- onPointerDown: (event) => {
6640
- beginResize(pane, event);
6641
- }
6642
- }), renderHeader(pane), headerCloseOf(pane), floatingCloseOf(pane), (0, import_react28.createElement)("div", { className: "dshpc-dock__body" }, pane.children ?? null))));
6713
+ panes.filter((pane) => state.ids.includes(pane.id)).map((pane) => (0, import_react28.createElement)(
6714
+ "section",
6715
+ {
6716
+ key: pane.id,
6717
+ ref: (element) => {
6718
+ if (element === null)
6719
+ panelRefs.current.delete(pane.id);
6720
+ else
6721
+ panelRefs.current.set(pane.id, element);
6722
+ },
6723
+ className: closing4.includes(pane.id) ? "dshpc-dock__panel dshpc-dock__panel--closing" : "dshpc-dock__panel",
6724
+ style: { width: `${widthOf(pane)}px` },
6725
+ "data-panel": pane.id,
6726
+ "aria-label": pane.ariaLabel ?? (typeof pane.title === "string" ? pane.title : pane.id)
6727
+ },
6728
+ (0, import_react28.createElement)("div", {
6729
+ className: "dshpc-dock__resizer",
6730
+ role: "separator",
6731
+ "aria-orientation": "vertical",
6732
+ "aria-label": tt("dockResize"),
6733
+ onPointerDown: (event) => {
6734
+ beginResize(pane, event);
6735
+ }
6736
+ }),
6737
+ // 收起钮是 resizer 的**兄弟**,不是子元素 —— 用户 2026-10-28:鼠标停在按钮上时,
6738
+ // 拖宽线不能亮、也不能出蓝色发光(那是在拖宽,不是点按钮)。挂在面板左缘外。
6739
+ (0, import_react28.createElement)("button", {
6740
+ type: "button",
6741
+ className: "dshpc-dock__collapse",
6742
+ "aria-label": tt("dockCollapse"),
6743
+ onClick: () => collapseWithAnim(pane.id)
6744
+ }, "\u203A"),
6745
+ renderHeader(pane),
6746
+ headerCloseOf(pane),
6747
+ floatingCloseOf(pane),
6748
+ (0, import_react28.createElement)("div", { className: "dshpc-dock__body" }, pane.children ?? null)
6749
+ )),
6750
+ // 收起后的耳朵:**独立的 fixed 浮层**,与分栏不是一体(用户 2026-10-28 口径)。
6751
+ // 多个耳朵按收起顺序纵向堆叠,点一只展开回来。
6752
+ state.collapsed.length === 0 ? null : (0, import_react28.createElement)("div", { className: "dshpc-dock__ears" }, state.collapsed.map((id3) => {
6753
+ const label = earLabelOf(id3);
6754
+ return (0, import_react28.createElement)(
6755
+ "button",
6756
+ {
6757
+ key: id3,
6758
+ type: "button",
6759
+ className: "dshpc-dock__ear",
6760
+ // 不放 title:原生 tooltip 会把面板标题弹出来,用户明确「不要显示任何标题」。
6761
+ "aria-label": `${label} \xB7 ${tt("dockExpand")}`,
6762
+ onClick: () => props.dock.expand(id3)
6763
+ },
6764
+ // 只有一个箭头,与收起钮同尺寸反向:收起钮 ›(往右收),耳朵 ‹(往左拉回来)。
6765
+ (0, import_react28.createElement)("span", { className: "dshpc-dock__ear-arrow", "aria-hidden": true }, "\u2039")
6766
+ );
6767
+ }))
6768
+ );
6643
6769
  }
6644
6770
 
6645
6771
  // dist/ui/Field.js
@@ -6754,8 +6880,8 @@ var FileServicesStore = class {
6754
6880
  this.snapshot = { ...this.snapshot, ...patch };
6755
6881
  for (const listener of this.listeners) listener();
6756
6882
  }
6757
- setFiles(workspaceFiles) {
6758
- this.set({ workspaceFiles });
6883
+ setFiles(workspaceFiles2) {
6884
+ this.set({ workspaceFiles: workspaceFiles2 });
6759
6885
  }
6760
6886
  setOffice(officeToPdf) {
6761
6887
  this.set({ officeToPdf });
@@ -55017,7 +55143,7 @@ var DICT2 = {
55017
55143
  installDesc: "\u5F85\u8865\uFF1A\n\xB7 \u4F9D\u8D56\u58F0\u660E\u600E\u4E48\u88C5\uFF08git \u5B89\u88C5\uFF0C\u5BBF\u4E3B\u4E0D\u8DD1\u6784\u5EFA\u811A\u672C\uFF09\n\xB7 \u5165\u53E3\u5FC5\u987B\u505A\u7684\u4E24\u884C\uFF1AsetStyleKit + ensureControls\n\xB7 \u4E3A\u4EC0\u4E48 @deepseek-ai/* \u5FC5\u987B\u6807 external\uFF08\u4E0D\u6807\u6253\u5305\u4F1A\u5931\u8D25\uFF09\n\xB7 \u5BBF\u4E3B slots \u6CE8\u518C\uFF1Asidebar.panellist / main / plugins.bundle.config\uFF08\u8BBE\u7F6E\u9875\uFF09\n\xB7 \u88C5\u4E0D\u4E0A\u7684\u6392\u67E5\u6E05\u5355\uFF08\u5148\u770B build \u7F16\u7801\u662F\u5426\u53D8\u4E86\uFF09",
55018
55144
  quickstartDesc: "\u5F85\u8865\uFF1A\n\xB7 \u4E00\u4E2A\u6700\u5C0F\u53EF\u8DD1\u63D2\u4EF6\u7684\u5B8C\u6574\u6E90\u7801\n\xB7 \u4ECE\u5EFA\u76EE\u5F55\u5230\u5728\u5BBF\u4E3B\u91CC\u770B\u89C1\u5B83\u7684\u5206\u6B65\u8BF4\u660E\n\xB7 \u672C\u9884\u89C8\u63D2\u4EF6\u81EA\u5DF1\u5C31\u662F\u6837\u4F8B\uFF0C\u53EF\u5BF9\u7167 packages/demo/src",
55019
55145
  namingDesc: "\u5F85\u8865\uFF1A\n\xB7 \u53D8\u91CF\u4E0E\u7C7B\u540D\u7EDF\u4E00 dshpc \u524D\u7F00\u7684\u7406\u7531\n\xB7 \u7C7B\u540D\u5FC5\u987B\u4E0E\u7EC4\u4EF6\u91CC\u786C\u7F16\u7801\u7684 className \u9010\u5B57\u4E00\u81F4\u2014\u2014\u4E0D\u4E00\u81F4\u4F1A\u6574\u7247\u5931\u6548\n\xB7 createStyleKit({ id }) \u9694\u79BB\u5230\u4EC0\u4E48\u7C92\u5EA6\n\xB7 \u6CE8\u5165\u987A\u5E8F\uFF1A\u540C\u7279\u5F02\u6027\u65F6\u540E\u6CE8\u5165\u8005\u80DC\u51FA\n\xB7 \u660E\u6697\u5224\u636E\u4E3A\u4EC0\u4E48\u662F body[data-ds-dark-theme] \u800C\u4E0D\u662F\u7CFB\u7EDF\u8BBE\u7F6E",
55020
- dockHint: "\u53F3\u4FA7\u505C\u9760\u5206\u680F\uFF0C\u6302\u5728\u6574\u9875\u4E0A\uFF1A\u7ED3\u6784\u5199\u5728\u9875\u9762\u91CC\uFF08DockPanel\uFF09\uFF0Copen(id) \u53EA\u7BA1\u663E\u9690\u3002\n\u8BD5\u4E00\u904D\uFF1A\u5F00 A\uFF08\u56FE\u6807 + \u6807\u9898 + \u53F3\u4FA7\u6807\u7B7E\uFF09\u2192 \u5F00 B\uFF08\u6574\u5757\u81EA\u5B9A\u4E49\u5934\u90E8\uFF09\u2192 \u5F00 C\uFF08\u65E0\u5934\u90E8\u3001\u5173\u95ED\u94AE\u6D6E\u5728\u53F3\u4E0A\u89D2\uFF09\u2192 \u5173 A \u540E\u518D\u5F00\u65B0\u7EC4\u540D \u2192 \u6EE1 3 \u680F\u518D\u5F00\u4F1A\u88AB\u62D2\u7EDD\u3002",
55146
+ dockHint: "\u53F3\u4FA7\u505C\u9760\u5206\u680F\uFF0C\u6302\u5728\u6574\u9875\u4E0A\uFF1A\u7ED3\u6784\u5199\u5728\u9875\u9762\u91CC\uFF08DockPanel\uFF09\uFF0Copen(id) \u53EA\u7BA1\u663E\u9690\u3002\n\u8BD5\u4E00\u904D\uFF1A\u5F00 A\uFF08\u56FE\u6807 + \u6807\u9898 + \u53F3\u4FA7\u6807\u7B7E\uFF09\u2192 \u5F00 B\uFF08\u6574\u5757\u81EA\u5B9A\u4E49\u5934\u90E8\uFF09\u2192 \u5F00 C\uFF08\u65E0\u5934\u90E8\u3001\u5173\u95ED\u94AE\u6D6E\u5728\u53F3\u4E0A\u89D2\uFF09\u2192 \u5173 A \u540E\u518D\u5F00\u65B0\u7EC4\u540D \u2192 \u6EE1 3 \u680F\u518D\u5F00\u4F1A\u88AB\u62D2\u7EDD\u3002\n\u53E6\uFF1A\u70B9\u5206\u5272\u7EBF\u4E2D\u95F4\u7684 \u203A \u53EF\u628A\u8BE5\u680F\u6536\u8D77\u6210\u53F3\u4FA7\u8033\u6735\uFF08\u5206\u680F\u6D88\u5931\u3001\u4E0D\u5360\u5BBD\uFF09\uFF0C\u70B9\u8033\u6735\u5C55\u5F00\u3002",
55021
55147
  dockMainText: "\u5206\u680F\u662F\u5E03\u5C40\u6210\u5458\uFF1A\u5B83\u628A\u8FD9\u4E00\u9875\u7684\u6B63\u6587\u6324\u7A84\uFF0C\u800C\u4E0D\u662F\u76D6\u5728\u4E0A\u9762\u3002\u4E09\u4E2A\u9762\u677F\u5206\u522B\u6F14\u793A\u5185\u7F6E\u5934\u3001\u81EA\u5B9A\u4E49\u5934\u3001\u65E0\u5934 + \u6D6E\u52A8\u5173\u95ED\u94AE\u3002",
55022
55148
  dockPanelA: "\u5185\u7F6E\u5934\uFF1A\u56FE\u6807 + \u6807\u9898 + \u53F3\u4FA7\u5185\u5BB9",
55023
55149
  dockPanelATag: "\u65B0",
@@ -55026,11 +55152,13 @@ var DICT2 = {
55026
55152
  dockCustomHeadHint: "\u5E93\u4E0D\u52A0\u5185\u8FB9\u8DDD\u3001\u4E0D\u52A0\u8FB9\u6846 \u2014\u2014 \u591A\u9AD8\u3001\u51E0\u884C\u3001\u653E\u4EC0\u4E48\u5F39\u5C42\u90FD\u968F\u4F60",
55027
55153
  dockPanelBody: "\u8FD9\u4E00\u680F\u7684\u5185\u5BB9\u3002\u518D\u5F00\u540C\u540D\u9762\u677F\u4F1A\u66FF\u6362\u5B83\uFF0C\u5BBD\u5EA6\u4E0E\u4F4D\u7F6E\u4FDD\u6301\u4E0D\u53D8\u3002",
55028
55154
  dockOpened: "\u5F53\u524D\u7A97\u53E3\uFF1A",
55155
+ dockCollapsed: "\u5DF2\u6536\u8D77\uFF1A",
55029
55156
  dockLimitWarn: "\u5DF2\u6EE1 3 \u680F\uFF0C\u65B0\u7EC4\u540D\u88AB\u62D2\u7EDD\uFF08open \u8FD4\u56DE ok:false / reason:limit\uFF09",
55030
55157
  dockBtnOpenA: "\u6253\u5F00 A",
55031
55158
  dockBtnOpenB: "\u6253\u5F00 B",
55032
55159
  dockBtnOpenA2: "\u518D\u5F00 A\uFF08\u4E0D\u4F1A\u591A\u5F00\uFF09",
55033
55160
  dockBtnCloseA: "\u5173\u95ED A",
55161
+ dockBtnCollapseA: "\u6536\u8D77 A",
55034
55162
  dockBtnDefault: "\u6253\u5F00\u9ED8\u8BA4\u7A97\u53E3",
55035
55163
  dockBtnOpenC: "\u6253\u5F00 C",
55036
55164
  dockBtnReset: "\u5168\u90E8\u5173\u95ED",
@@ -55245,7 +55373,7 @@ var DICT2 = {
55245
55373
  installDesc: "To be added:\n\xB7 How to install (via git \u2014 the host does not run build scripts)\n\xB7 The two mandatory entry lines: setStyleKit + ensureControls\n\xB7 Why @deepseek-ai/* must stay external (otherwise bundling fails)\n\xB7 Registering host slots: sidebar.panellist / main / plugins.bundle.config (settings page)\n\xB7 Checklist when it does not load (start by checking the build stamp)",
55246
55374
  quickstartDesc: "To be added:\n\xB7 Full source of a minimal working plugin\n\xB7 Step-by-step from empty folder to visible panel\n\xB7 This preview plugin is itself the sample \u2014 see packages/demo/src",
55247
55375
  namingDesc: "To be added:\n\xB7 Why variables and class names share the dshpc prefix\n\xB7 Class names must match the hard-coded className character for character \u2014 any drift kills the whole block\n\xB7 How far createStyleKit({ id }) isolates\n\xB7 Injection order: at equal specificity the later one wins\n\xB7 Why the theme switch is body[data-ds-dark-theme] and not prefers-color-scheme",
55248
- dockHint: "Right-side dock: a group name is one window; reopening the same name replaces its content in place (no extra column).\nTry it: open A \u2192 open B \u2192 reopen A (content replaced) \u2192 close A \u2192 open C (the freed slot is usable) \u2192 with 3 columns open, a new group name is rejected.",
55376
+ dockHint: "Right-side dock: a group name is one window; reopening the same name replaces its content in place (no extra column).\nTry it: open A \u2192 open B \u2192 reopen A (content replaced) \u2192 close A \u2192 open C (the freed slot is usable) \u2192 with 3 columns open, a new group name is rejected.\nTip: click \u203A in the middle of the splitter to collapse that column into a right-edge ear (it leaves the layout); click the ear to expand.",
55249
55377
  dockMainText: "The dock is a layout member: it squeezes the page content instead of covering it. The three panels demo a built-in header, a custom header, and a header-less panel with a floating close button.",
55250
55378
  dockPanelA: "Built-in header: icon + title + right-side content",
55251
55379
  dockPanelATag: "new",
@@ -55254,11 +55382,13 @@ var DICT2 = {
55254
55382
  dockCustomHeadHint: "No padding, no border from the library \u2014 height, rows and popovers are up to you",
55255
55383
  dockPanelBody: "Content of this column. Reopening the same name replaces it; width and position stay put.",
55256
55384
  dockOpened: "Open now: ",
55385
+ dockCollapsed: "Collapsed: ",
55257
55386
  dockLimitWarn: "All 3 columns are taken \u2014 the new group name was rejected (open returns ok:false / reason:limit)",
55258
55387
  dockBtnOpenA: "Open A",
55259
55388
  dockBtnOpenB: "Open B",
55260
55389
  dockBtnOpenA2: "Reopen A (no duplicate)",
55261
55390
  dockBtnCloseA: "Close A",
55391
+ dockBtnCollapseA: "Collapse A",
55262
55392
  dockBtnDefault: "Open default",
55263
55393
  dockBtnOpenC: "Open C",
55264
55394
  dockBtnReset: "Close all",
@@ -55631,8 +55761,16 @@ var docData = {
55631
55761
  "en": "Workspace file browsing and picking, driven by the host-provided workspace file snapshot."
55632
55762
  },
55633
55763
  {
55634
- "zh": "\u6D4F\u89C8\u6001\u505C\u9760\u662F\u5E03\u5C40\u6210\u5458\uFF08\u5360\u5BBD\u5EA6\u3001\u6324\u7A84\u4E3B\u533A\uFF09\uFF0C\u4E0D\u8981\u6302 `document.body` \u518D\u81EA\u5DF1\u5957 fixed\u3002",
55635
- "en": "The browse dock is a layout member (takes width, narrows the main area); never mount it on `document.body` with your own fixed positioning."
55764
+ "zh": "**\u63A5\u7EBF\u5F52\u6838\u5FC3**\uFF1Aclient `apply` \u91CC\u8C03\u4E00\u6B21 `connectHost(ctx)`\uFF0C\u8BFB\u6587\u4EF6\u670D\u52A1\u3001\u4F1A\u8BDD id\u3001\u5DE5\u4F5C\u533A\u5FEB\u7167\u90FD\u7531\u6838\u5FC3\u81EA\u5DF1\u89E3\uFF0C\u8C03\u7528\u65F6\u53EA\u7ED9\u5BB9\u5668\u548C\u8DEF\u5F84\u3002",
55765
+ "en": "**Wiring belongs to core**: call `connectHost(ctx)` once in the client apply; the file service, session id and workspace snapshot are resolved by core \u2014 you only pass a container and a path."
55766
+ },
55767
+ {
55768
+ "zh": "\u843D\u70B9\u53EA\u7ED9\u4E00\u4E2A\u5143\u7D20\uFF1A\u9875\u9762\u91CC**\u5305\u4F4F\u4E3B\u533A**\u7684\u90A3\u4E2A\uFF08\u6838\u5FC3\u4F1A\u8865\u6210 flex \u884C\u3001\u8BA9\u4E3B\u533A\u4F38\u5C55\uFF0C\u5173\u95ED\u65F6\u8FD8\u539F\uFF09\uFF0C\u4E0D\u8981\u4F20 `document.body` \u518D\u81EA\u5DF1\u5957 fixed\u2014\u2014\u90A3\u662F\u6D6E\u5C42\uFF0C\u4E0D\u662F\u5206\u680F\u3002",
55769
+ "en": "Pass one element: the one wrapping the main area. Core makes it a flex row and lets the main area stretch, restoring it on close. Never pass `document.body` with your own fixed positioning \u2014 that is an overlay, not a split."
55770
+ },
55771
+ {
55772
+ "zh": "\u7EDD\u5BF9\u8DEF\u5F84\u6309\u6700\u957F\u524D\u7F00\u5339\u914D\u6240\u5C5E\u5DE5\u4F5C\u533A\uFF1B\u843D\u5728\u4EFB\u4F55\u5DE5\u4F5C\u533A\u5916\u65F6\uFF0C\u6587\u4EF6\u7167\u6837\u80FD\u9884\u89C8\uFF08\u5B98\u65B9 read \u5141\u8BB8\u5DE5\u4F5C\u533A\u5916\u6587\u4EF6\uFF09\uFF0C\u53EA\u6709\u76EE\u5F55\u6811\u9000\u5316\u6210\u53EA\u8BFB\u8DEF\u5F84\u680F\u3002",
55773
+ "en": "Absolute paths are matched to their workspace by longest prefix. Outside every workspace the file still previews (official read allows it); only the directory tree degrades to a read-only path bar."
55636
55774
  }
55637
55775
  ]
55638
55776
  },
@@ -55658,15 +55796,15 @@ var docData = {
55658
55796
  },
55659
55797
  "prose": [
55660
55798
  {
55661
- "zh": "\u4ECE ctx \u53D6\u51FA\u5DE5\u4F5C\u533A\u5FEB\u7167\u518D\u4F20\u7ED9\u80FD\u529B\u63A5\u53E3\uFF0C\u4E0D\u8981\u4F20\u6574\u4E2A ctx\u3002",
55662
- "en": "Pull the workspace snapshot out of ctx and hand it to the capability APIs; do not pass the whole ctx."
55799
+ "zh": "`connectHost(ctx)` \u53EA\u6536\u8FD9\u4E00\u5C0F\u5757\uFF0C\u4E0D\u628A\u6574\u4E2A ctx \u4F20\u8FDB\u6838\u5FC3\u3002",
55800
+ "en": "`connectHost(ctx)` takes just that one slice; the whole ctx never enters core."
55663
55801
  }
55664
55802
  ],
55665
55803
  "code": [
55666
55804
  {
55667
55805
  "id": "explorer-usage-code",
55668
55806
  "lang": "tsx",
55669
- "src": "import { openFilePreview, pickWorkspaceFile } from 'dsh-plugin-core/explorer'\n\n// \u53F3\u4FA7\u5206\u680F\u9884\u89C8\uFF08\u5360\u5BBD\u5EA6\u3001\u6324\u7A84\u4E3B\u533A\uFF09\nopenFilePreview({ mount, workspaceFiles, officeToPdf, sessionId, path, rootName })\n\n// path \u4F20\u7EDD\u5BF9\u8DEF\u5F84\u65F6\uFF1A\u6309\u6700\u957F\u524D\u7F00\u5339\u914D\u6240\u5C5E\u5DE5\u4F5C\u533A\uFF0C\u9762\u5305\u5C51 / \u76EE\u5F55\u6811\u4E0E \u25BE\u300C\u5207\u5DE5\u4F5C\u533A\u300D\u81EA\u52A8\u53EF\u7528\nopenFilePreview({ mount, workspaceFiles, sessionId, path: '/abs/path.md' })\n// \u8981\u8986\u76D6\u5BBF\u4E3B\u5FEB\u7167\u624D\u663E\u5F0F\u4F20 workspaceAnchors\uFF08\u5E26 path + sessionIds\uFF09\nopenFilePreview({ mount, workspaceFiles, sessionId, path: '/abs/path.md', workspaceAnchors })\n\n// \u951A\u5B9A\u5F39\u7A97\u9009\u6587\u4EF6\uFF08Promise \u8FD4\u56DE\u8DEF\u5F84\uFF0C\u4E0D\u81EA\u5DF1\u6302 dock\uFF09\nconst r = await pickWorkspaceFile({ workspaceFiles, sessionId, anchor, rootName })"
55807
+ "src": "import { openFilePreview, pickWorkspaceFile } from 'dsh-plugin-core/explorer'\n\n// \u53EA\u5728 client apply \u91CC\u63A5\u7EBF\u4E00\u6B21\uFF08\u63A5\u5DE5\u4F5C\u533A\u5FEB\u7167 + \u8BFB\u6587\u4EF6\u670D\u52A1\uFF09\uFF0C\u4E4B\u540E\u4E0D\u7528\u518D\u78B0\u670D\u52A1\nconnectHost(ctx)\n\n// \u53F3\u4FA7\u5206\u680F\u9884\u89C8\uFF08\u5360\u5BBD\u5EA6\u3001\u6324\u7A84\u4E3B\u533A\uFF09\uFF1A\u4E00\u4E2A\u5BB9\u5668 + \u4E00\u4E2A\u8DEF\u5F84\u5C31\u591F\nopenFilePreview({ mount, path: '/abs/ledger' }) // \u6587\u4EF6\u5939 \u21D2 \u76EE\u5F55\u6811\uFF1B\u6587\u4EF6 \u21D2 \u76F4\u63A5\u9884\u89C8\nopenFilePreview({ mount, path: 'docs/README.md' }) // \u5DE5\u4F5C\u533A\u76F8\u5BF9\u8DEF\u5F84\u4E5F\u884C\n\n// \u8986\u76D6\u9879\uFF1A\u6307\u5B9A\u5DE5\u4F5C\u533A\u5FEB\u7167 / \u6307\u5B9A\u4F1A\u8BDD / Office \u8F6C PDF / \u4E0E\u522B\u5904\u5171\u7528\u7684\u6839\u7F13\u5B58\nopenFilePreview({ mount, path, workspaceAnchors, sessionId, officeToPdf, rootCache })\n\n// \u951A\u5B9A\u5F39\u7A97\u9009\u6587\u4EF6\uFF08Promise \u8FD4\u56DE\u8DEF\u5F84\uFF0C\u4E0D\u81EA\u5DF1\u6302 dock\uFF09\nconst r = await pickWorkspaceFile({ anchor, filter: { exts: ['md'] } })"
55670
55808
  }
55671
55809
  ]
55672
55810
  },
@@ -55695,8 +55833,8 @@ var docData = {
55695
55833
  "def": "\u2014",
55696
55834
  "required": "\u662F",
55697
55835
  "desc": {
55698
- "zh": "\u9875\u9762\u91CC\u7684 flex \u884C\uFF1B\u9884\u89C8\u9760\u5B83\u5360\u5BBD\u800C\u4E0D\u662F\u6D6E\u5728\u9875\u9762\u4E0A\u65B9",
55699
- "en": "The page\u2019s flex row; the preview takes width there instead of floating"
55836
+ "zh": "\u9875\u9762\u91CC**\u5305\u4F4F\u4E3B\u533A**\u7684\u90A3\u4E2A\u5143\u7D20\uFF1B\u4E0D\u5FC5\u81EA\u5DF1\u5199 flex\uFF08\u6838\u5FC3\u8865\u6210 flex \u884C\u5E76\u8BA9\u4E3B\u533A\u4F38\u5C55\uFF0C\u5173\u95ED\u65F6\u8FD8\u539F\uFF09\u3002\u4E0D\u8981\u4F20 `document.body`",
55837
+ "en": "The element wrapping the main area; no flex needed (core turns it into a flex row, stretches the main area, and restores it on close). Never `document.body`"
55700
55838
  }
55701
55839
  },
55702
55840
  {
@@ -55704,8 +55842,8 @@ var docData = {
55704
55842
  "type": "WorkspaceFilesFace",
55705
55843
  "def": "\u2014",
55706
55844
  "desc": {
55707
- "zh": "\u4ECE ctx \u53D6\u51FA\u7684\u5DE5\u4F5C\u533A\u6587\u4EF6\u670D\u52A1\uFF1B\u4F20 `content` \u65F6\u53EF\u7701",
55708
- "en": "Workspace file service taken from ctx; optional when passing `content`"
55845
+ "zh": "\u8BFB\u6587\u4EF6\u670D\u52A1\u3002**\u4E00\u822C\u4E0D\u7528\u4F20**\uFF1A`connectHost(ctx)` \u63A5\u7EBF\u540E\u6838\u5FC3\u81EA\u5DF1\u6301\u6709\uFF1B\u4F20\u4E86\u4EE5\u4F20\u5165\u4E3A\u51C6\u3002\u4F20 `content` \u65F6\u53EF\u7701",
55846
+ "en": "File service. **Usually unnecessary**: core holds it after `connectHost(ctx)`; when passed it wins. Optional when passing `content`"
55709
55847
  }
55710
55848
  },
55711
55849
  {
@@ -55713,8 +55851,8 @@ var docData = {
55713
55851
  "type": "string",
55714
55852
  "def": "\u2014",
55715
55853
  "desc": {
55716
- "zh": "\u8BE5\u5DE5\u4F5C\u533A\u7684\u771F\u5B9E\u4F1A\u8BDD id\uFF08\u670D\u52A1\u662F\u4F1A\u8BDD\u4F5C\u7528\u57DF\u7684\uFF09\uFF1B\u4F20 `content` \u65F6\u53EF\u7701",
55717
- "en": "A real session id of that workspace (the service is session-scoped); optional when passing `content`"
55854
+ "zh": "\u8BE5\u5DE5\u4F5C\u533A\u7684\u771F\u5B9E\u4F1A\u8BDD id\u3002**\u4E00\u822C\u4E0D\u7528\u4F20**\uFF1A\u6309\u8DEF\u5F84\u5339\u914D\u6240\u5C5E\u5DE5\u4F5C\u533A\uFF0C\u5339\u914D\u4E0D\u51FA\u5C31\u53D6\u6700\u8FD1\u6709\u4F1A\u8BDD\u7684\u5DE5\u4F5C\u533A\uFF1B\u4F20 `content` \u65F6\u53EF\u7701",
55855
+ "en": "A real session id. **Usually unnecessary**: resolved from the path\u2019s workspace, else the most recently updated workspace with a session; optional when passing `content`"
55718
55856
  }
55719
55857
  },
55720
55858
  {
@@ -57646,12 +57784,16 @@ var docData = {
57646
57784
  "en": "A generic shell for right-side columns \u2014 a **layout member**, not an overlay: it takes width and narrows the main area, so the caller puts it in their own flex root. Split of work: structure at the call site (children), visibility in state (`open`/`close` take only an id)."
57647
57785
  },
57648
57786
  {
57649
- "zh": "\u9762\u677F\u9AD8\u5EA6\u9ED8\u8BA4\u89C6\u53E3\u9AD8\uFF1B\u5D4C\u5728\u5B9A\u9AD8\u5BB9\u5668\u91CC\u65F6\u7531\u8C03\u7528\u65B9\u7ED9 `--dshpc-dock-h`\u3002\u4E0D\u652F\u6301\uFF1A\u540C\u540D\u591A\u5B9E\u4F8B\u3001tab \u5207\u6362\u6761\u3001\u81EA\u52A8\u6DD8\u6C70\u3001\u6D6E\u5C42\u2014\u2014\u6807\u7B7E\u5207\u6362\u8BF7\u6D88\u8D39\u65B9\u5728\u81EA\u5DF1\u7684\u9762\u677F\u5185\u5BB9\u91CC\u5B9E\u73B0\u3002",
57650
- "en": "Panel height defaults to viewport height; in a fixed-height container the caller sets `--dshpc-dock-h`. Not supported: same-name duplicates, tab bars, auto-eviction, floating layers \u2014 tab switching belongs in the consumer\u2019s own panel content."
57787
+ "zh": "\u9762\u677F\u9AD8\u5EA6\u9ED8\u8BA4\u89C6\u53E3\u9AD8\uFF1B\u5D4C\u5728\u5B9A\u9AD8\u5BB9\u5668\u91CC\u65F6\u7531\u8C03\u7528\u65B9\u7ED9 `--dshpc-dock-h`\u3002\u4E0D\u652F\u6301\uFF1A\u540C\u540D\u591A\u5B9E\u4F8B\u3001tab \u5207\u6362\u6761\u3001\u81EA\u52A8\u6DD8\u6C70\u2014\u2014\u6807\u7B7E\u5207\u6362\u8BF7\u6D88\u8D39\u65B9\u5728\u81EA\u5DF1\u7684\u9762\u677F\u5185\u5BB9\u91CC\u5B9E\u73B0\u3002\uFF08\u6536\u8D77\u540E\u7684\u8033\u6735\u662F\u72EC\u7ACB `fixed` \u6D6E\u5C42\uFF0C\u4E0D\u662F\u628A\u9762\u677F\u53D8\u6210\u6D6E\u5C42\u3002\uFF09",
57788
+ "en": "Panel height defaults to viewport height; in a fixed-height container the caller sets `--dshpc-dock-h`. Not supported: same-name duplicates, tab bars, auto-eviction \u2014 tab switching belongs in the consumer\u2019s own panel content. (The collapsed ear is a standalone `fixed` overlay; the panel itself never floats.)"
57789
+ },
57790
+ {
57791
+ "zh": "\u5360\u5BBD\u5951\u7EA6\uFF1A\u5DF2\u5F00\u680F\u5BBD\u4E4B\u548C\uFF08\u5916\u52A0\u5F00\u7740\u65F6\u7ED9\u4E3B\u533A\u6EDA\u52A8\u6761\u7559\u7684 1px \u7F1D\uFF0C\u53EF\u7528 `--dshpc-dock-gap` \u8C03\uFF09\u5B9E\u65F6\u5199\u8FDB\u6839\u5143\u7D20 `--dshpc-page-inset-right`\uFF08\u62D6\u62FD\u9010\u5E27\u66F4\u65B0\uFF0C\u5168\u5173\u5373\u79FB\u9664\uFF09\uFF0C\u5168\u5C4F\u906E\u7F69\u636E\u6B64\u8BA9\u4F4D\uFF1B\u540C\u9875\u591A\u4E2A dock \u6C42\u548C\u3002",
57792
+ "en": "Width contract: the sum of open widths plus a 1px scrollbar gutter while open (tunable via `--dshpc-dock-gap`) goes to `--dshpc-page-inset-right` on the root element (every frame while dragging, removed when all close), and full-screen masks yield to it; multiple docks on one page are summed."
57651
57793
  },
57652
57794
  {
57653
- "zh": "\u5360\u5BBD\u5951\u7EA6\uFF1A\u5DF2\u5F00\u680F\u5BBD\u4E4B\u548C\u5B9E\u65F6\u5199\u8FDB\u6839\u5143\u7D20 `--dshpc-page-inset-right`\uFF08\u62D6\u62FD\u9010\u5E27\u66F4\u65B0\uFF0C\u5168\u5173\u5373\u79FB\u9664\uFF09\uFF0C\u5168\u5C4F\u906E\u7F69\u636E\u6B64\u8BA9\u4F4D\uFF1B\u540C\u9875\u591A\u4E2A dock \u6C42\u548C\u3002",
57654
- "en": "Width contract: the sum of open widths goes to `--dshpc-page-inset-right` on the root element (every frame while dragging, removed when all close), and full-screen masks yield to it; multiple docks on one page are summed."
57795
+ "zh": "\u6536\u8D77 / \u5C55\u5F00\uFF1A`dock.collapse(id)` \u8BA9\u9762\u677F\u9000\u51FA\u5E03\u5C40\uFF08\u7ACB\u523B\u4E0D\u5360\u5BBD\uFF09\u3001\u5728\u53F3\u4FA7\u51FA\u4E00\u53EA\u56FA\u5B9A\u8033\u6735\uFF1B`dock.expand(id)` \u628A\u8033\u6735\u6536\u56DE\u3001\u6309\u8BB0\u5FC6\u5BBD\u5EA6\u8FD8\u539F\uFF1B`dock.isCollapsed(id)`\u3002\u8033\u6735\u662F\u5782\u76F4\u5C45\u4E2D\u7684\u5C0F\u56FE\u6807\u9875\u7B7E\uFF08\u4E0D\u653E\u6587\u5B57\uFF09\uFF0C\u5F00\u5408\u5E26\u6ED1\u5165 / \u6536\u62E2\u52A8\u6548\uFF1B\u8033\u6735\u662F\u72EC\u7ACB\u6D6E\u5C42\uFF0C\u4E0E\u5206\u680F\u4E0D\u662F\u4E00\u4F53\uFF1B`close` \u4E0D\u7559\u8033\u6735\u3002",
57796
+ "en": "Collapse / expand: `dock.collapse(id)` takes the panel out of the layout (it stops taking width) and shows a fixed ear at the right edge; `dock.expand(id)` pulls the ear back and restores the remembered width; `dock.isCollapsed(id)`. The ear is a small icon-only tab at the vertical center, with slide/collapse animations; it is a standalone overlay, not part of the dock; `close` leaves no ear."
57655
57797
  }
57656
57798
  ],
57657
57799
  "api": [
@@ -59566,6 +59708,9 @@ if (!result.ok) showToast('\u6700\u591A\u540C\u65F6\u5F00 3 \u680F')
59566
59708
  dock.close('files')
59567
59709
  dock.toggle('preview')
59568
59710
  dock.isOpen('files')
59711
+ dock.collapse('files') // \u6536\u8D77\uFF1A\u9000\u51FA\u5E03\u5C40\u3001\u53D8\u6210\u53F3\u4FA7\u56FA\u5B9A\u8033\u6735\uFF08\u5BBD\u5EA6\u4FDD\u7559\uFF09
59712
+ dock.expand('files') // \u5C55\u5F00\uFF1A\u56DE\u5230\u5E03\u5C40\u3001\u539F\u5BBD\u8FD8\u539F
59713
+ dock.isCollapsed('files')
59569
59714
 
59570
59715
  // 4) \u8BA2\u9605\u72B6\u6001\u9A71\u52A8 UI\uFF08React\uFF09
59571
59716
  const state = useSyncExternalStore(dock.subscribe, dock.getSnapshot, dock.getSnapshot)`;
@@ -59580,7 +59725,12 @@ function LayoutPage() {
59580
59725
  demoDock.close(id3);
59581
59726
  setNotice(null);
59582
59727
  };
59728
+ const collapse = (id3) => {
59729
+ demoDock.collapse(id3);
59730
+ setNotice(null);
59731
+ };
59583
59732
  const opened = state.ids;
59733
+ const collapsedIds = state.collapsed;
59584
59734
  return (0, import_react57.createElement)(
59585
59735
  "div",
59586
59736
  null,
@@ -59595,6 +59745,7 @@ function LayoutPage() {
59595
59745
  (0, import_react57.createElement)(Button, { size: "sm", onClick: () => open("B") }, t3("dockBtnOpenB")),
59596
59746
  (0, import_react57.createElement)(Button, { size: "sm", variant: "primary", onClick: () => open("A") }, t3("dockBtnOpenA2")),
59597
59747
  (0, import_react57.createElement)(Button, { size: "sm", onClick: () => close("A") }, t3("dockBtnCloseA")),
59748
+ (0, import_react57.createElement)(Button, { size: "sm", onClick: () => collapse("A") }, t3("dockBtnCollapseA")),
59598
59749
  (0, import_react57.createElement)(Button, { size: "sm", onClick: () => open("default") }, t3("dockBtnDefault")),
59599
59750
  (0, import_react57.createElement)(Button, { size: "sm", onClick: () => open("C") }, t3("dockBtnOpenC")),
59600
59751
  (0, import_react57.createElement)(
@@ -59603,7 +59754,7 @@ function LayoutPage() {
59603
59754
  size: "sm",
59604
59755
  variant: "ghost",
59605
59756
  onClick: () => {
59606
- for (const id3 of demoDock.ids()) demoDock.close(id3);
59757
+ for (const id3 of [...state.ids, ...state.collapsed]) demoDock.close(id3);
59607
59758
  setNotice(null);
59608
59759
  }
59609
59760
  },
@@ -59614,6 +59765,7 @@ function LayoutPage() {
59614
59765
  "div",
59615
59766
  { style: { fontSize: "12px", color: "var(--dshpc-fg-3)" } },
59616
59767
  `${t3("dockOpened")}${opened.length === 0 ? "\u2014" : opened.join(", ")}`,
59768
+ collapsedIds.length === 0 ? "" : `\u3000${t3("dockCollapsed")}${collapsedIds.join(", ")}`,
59617
59769
  notice === null ? "" : `\u3000${notice}`
59618
59770
  ),
59619
59771
  (0, import_react57.createElement)(
@@ -59860,8 +60012,8 @@ function relativizeToRoot(cache5, sessionId, dir) {
59860
60012
  return dir.slice(norm.length + 1);
59861
60013
  return dir;
59862
60014
  }
59863
- async function findAnyFileAbs(workspaceFiles, sessionId, startDir) {
59864
- const stat = workspaceFiles.stat;
60015
+ async function findAnyFileAbs(workspaceFiles2, sessionId, startDir) {
60016
+ const stat = workspaceFiles2.stat;
59865
60017
  if (stat === void 0)
59866
60018
  return null;
59867
60019
  let frontier = [startDir];
@@ -59870,7 +60022,7 @@ async function findAnyFileAbs(workspaceFiles, sessionId, startDir) {
59870
60022
  for (const dir of frontier.slice(0, 5)) {
59871
60023
  let entries2;
59872
60024
  try {
59873
- const parsed = listingOf(await workspaceFiles.list(sessionId, listPathOf(dir)));
60025
+ const parsed = listingOf(await workspaceFiles2.list(sessionId, listPathOf(dir)));
59874
60026
  if (parsed === null || isFailed(parsed))
59875
60027
  continue;
59876
60028
  entries2 = parsed.entries;
@@ -59896,14 +60048,14 @@ async function findAnyFileAbs(workspaceFiles, sessionId, startDir) {
59896
60048
  }
59897
60049
  return null;
59898
60050
  }
59899
- async function absolutizeDir(cache5, workspaceFiles, sessionId, dir, canonical, entries2) {
60051
+ async function absolutizeDir(cache5, workspaceFiles2, sessionId, dir, canonical, entries2) {
59900
60052
  if (isAbsoluteish(dir))
59901
60053
  return dir;
59902
60054
  const rel = canonical !== "" ? canonical : dir;
59903
60055
  const cached = cache5.get(sessionId);
59904
60056
  if (cached !== void 0)
59905
60057
  return `${cached}/${rel}`;
59906
- const stat = workspaceFiles.stat;
60058
+ const stat = workspaceFiles2.stat;
59907
60059
  if (stat === void 0)
59908
60060
  return dir;
59909
60061
  const file = entries2.find((entry) => entry.type === "file");
@@ -59917,7 +60069,7 @@ async function absolutizeDir(cache5, workspaceFiles, sessionId, dir, canonical,
59917
60069
  } catch {
59918
60070
  }
59919
60071
  }
59920
- const found = await findAnyFileAbs(workspaceFiles, sessionId, rel);
60072
+ const found = await findAnyFileAbs(workspaceFiles2, sessionId, rel);
59921
60073
  if (found === null)
59922
60074
  return dir;
59923
60075
  const root = learnRoot(cache5, sessionId, found.relativePath, found.absolutePath);
@@ -60823,7 +60975,7 @@ function PreviewBody(props) {
60823
60975
  const entryTitle = workspaceAnchorForPath(options.path ?? "", anchors)?.title ?? options.rootName ?? "";
60824
60976
  const [picked, setPicked] = (0, import_react64.useState)(null);
60825
60977
  const wsTitle = picked ?? entryTitle;
60826
- const sessionId = anchorSessionForTitle(anchors, wsTitle) ?? options.sessionId;
60978
+ const sessionId = anchorSessionForTitle(anchors, wsTitle) ?? options.sessionId ?? pickWorkspaceAnchor(anchors)?.sessionId ?? "";
60827
60979
  const switchable = anchors.filter((a) => (a.sessionIds?.length ?? 0) > 0).map((a) => a.title);
60828
60980
  return (0, import_react64.createElement)(FileBrowser, {
60829
60981
  // key 带工作区+会话 ⇒ 切换即重挂载(FileBrowser 的 dir/listing/学根全属于旧工作区)。
@@ -60851,22 +61003,58 @@ function PreviewBody(props) {
60851
61003
  }
60852
61004
  var PREVIEW_HOST_ID = "dshpc-file-preview-host";
60853
61005
  var PREVIEW_PANEL_ID = "file-preview";
60854
- var activePreviewClose = null;
61006
+ var DOCK_HOST_CLASS = "dshpc-dock-host";
61007
+ var activePreview = null;
60855
61008
  function openFilePreview(options) {
60856
61009
  if (typeof document === "undefined")
60857
61010
  return null;
60858
- if (typeof getComputedStyle === "function") {
60859
- const cs = getComputedStyle(options.mount);
60860
- if (cs.display !== "flex" && cs.display !== "inline-flex") {
60861
- console.warn("[dsh-plugin-core/explorer] openFilePreview: mount \u4E0D\u662F flex \u884C \u2014\u2014 PanelDock \u662F\u5E03\u5C40\u6210\u5458\uFF08\u505C\u9760\u53F3\u4FA7 + \u6324\u7A84\u4E3B\u533A\uFF09\u3002\u8BF7\u4F20\u4F60\u9875\u9762\u300C\u4E3B\u533A + \u4FA7\u680F\u300D\u90A3\u4E00\u5C42 flex \u5BB9\u5668\uFF0C\u4E0D\u8981\u4F20 document.body \u6216\u65E0\u5B9A\u9AD8\u7684\u7A84\u5BB9\u5668\u3002");
60862
- }
61011
+ const custom = options.content !== void 0;
61012
+ const files = options.workspaceFiles ?? getWorkspaceFiles();
61013
+ const anchors = options.workspaceAnchors ?? workspaceList.getSnapshot();
61014
+ const sessionId = options.sessionId ?? workspaceAnchorForPath(options.path ?? "", anchors)?.sessionId ?? pickWorkspaceAnchor(anchors)?.sessionId;
61015
+ if (!custom && (files === void 0 || sessionId === void 0)) {
61016
+ console.warn("[dsh-plugin-core/explorer] openFilePreview: " + (files === void 0 ? "\u6CA1\u6709\u5DE5\u4F5C\u533A\u6587\u4EF6\u670D\u52A1\uFF08client apply \u91CC\u6CA1\u8C03 connectHost\uFF0C\u6216\u5BBF\u4E3B\u6CA1\u63D0\u4F9B remote.workspaceFiles\uFF09" : "\u627E\u4E0D\u5230\u53EF\u7528\u7684\u5DE5\u4F5C\u533A\u4F1A\u8BDD\uFF08\u5BBF\u4E3B workspaces \u91CC\u6CA1\u6709\u5E26\u4F1A\u8BDD\u7684\u5DE5\u4F5C\u533A\uFF09") + " \u21D2 \u4E0D\u6253\u5F00\u9884\u89C8");
61017
+ return null;
61018
+ }
61019
+ const opts = { ...options, workspaceFiles: files, sessionId };
61020
+ if (activePreview !== null) {
61021
+ activePreview.keepWidth();
61022
+ activePreview.adopt(opts.mount);
61023
+ activePreview.draw(opts);
61024
+ return { close: activePreview.close, path: opts.path ?? "" };
60863
61025
  }
60864
- activePreviewClose?.();
60865
61026
  const container = document.createElement("div");
60866
61027
  container.id = PREVIEW_HOST_ID;
60867
61028
  container.setAttribute("data-dshpc-file-preview", "");
60868
61029
  container.style.cssText = "display:contents";
60869
- options.mount.appendChild(container);
61030
+ let hostEl = null;
61031
+ let hostPrevDisplay = "";
61032
+ let hostHadClass = false;
61033
+ const restoreHost = () => {
61034
+ if (hostEl === null)
61035
+ return;
61036
+ hostEl.style.display = hostPrevDisplay;
61037
+ if (!hostHadClass)
61038
+ hostEl.classList.remove(DOCK_HOST_CLASS);
61039
+ hostEl = null;
61040
+ };
61041
+ const adopt = (next) => {
61042
+ if (next === hostEl)
61043
+ return;
61044
+ restoreHost();
61045
+ if (next === document.body) {
61046
+ console.warn("[dsh-plugin-core/explorer] openFilePreview: \u4E0D\u8981\u4F20 document.body \u2014\u2014 PanelDock \u662F\u5E03\u5C40\u6210\u5458\uFF08\u505C\u9760\u53F3\u4FA7 + \u6324\u7A84\u4E3B\u533A\uFF09\u3002\u8BF7\u4F20\u4F60\u9875\u9762\u91CC\u5305\u4F4F\u4E3B\u533A\u7684\u90A3\u4E2A\u5143\u7D20\u3002");
61047
+ }
61048
+ hostPrevDisplay = next.style.display;
61049
+ hostHadClass = next.classList.contains(DOCK_HOST_CLASS);
61050
+ next.classList.add(DOCK_HOST_CLASS);
61051
+ const display = typeof getComputedStyle === "function" ? getComputedStyle(next).display : "";
61052
+ if (display !== "flex" && display !== "inline-flex")
61053
+ next.style.display = "flex";
61054
+ next.appendChild(container);
61055
+ hostEl = next;
61056
+ };
61057
+ adopt(options.mount);
60870
61058
  const dock = createPanelDock({
60871
61059
  maxPanels: 1,
60872
61060
  defaultWidth: options.width ?? 460,
@@ -60885,11 +61073,12 @@ function openFilePreview(options) {
60885
61073
  if (closed)
60886
61074
  return;
60887
61075
  closed = true;
60888
- if (activePreviewClose === close)
60889
- activePreviewClose = null;
61076
+ if (activePreview?.close === close)
61077
+ activePreview = null;
60890
61078
  window.removeEventListener("keydown", onKeyDown);
60891
61079
  root.unmount();
60892
61080
  container.remove();
61081
+ restoreHost();
60893
61082
  options.onClose?.();
60894
61083
  };
60895
61084
  const onKeyDown = (event) => {
@@ -60898,40 +61087,59 @@ function openFilePreview(options) {
60898
61087
  };
60899
61088
  window.addEventListener("keydown", onKeyDown);
60900
61089
  ensureControls(getStyleKit());
60901
- const internalSwitch = options.onSelectWorkspace === void 0;
60902
- root.render((0, import_react64.createElement)(
60903
- "div",
60904
- // 高度吃调用方给的 --dshpc-dock-h(demo 的页面行给 100%);退化成视口高是整页场景。
60905
- { style: { display: "contents", ["--dshpc-dock-h"]: "100%" } },
60906
- (0, import_react64.createElement)(PanelDock, { dock, mainMinWidth: options.mainMinWidth ?? 480, translate: options.translate }, (0, import_react64.createElement)(DockPanel, {
60907
- id: PREVIEW_PANEL_ID,
60908
- // 不要头部(用户 2026-10-21:核心的『无 header』那版)——上面不再多一条线。
60909
- header: null,
60910
- // 关闭钮不用核心浮动的(那是 absolute 固定偏移、不垂直居中);关掉它的,
60911
- // 改用 FileBrowser 自己的 ✕(和 pick 弹窗同一个 crumb-bar 钮,垂直居中)。
60912
- closeButton: "none",
60913
- ariaLabel: options.title,
60914
- width: options.width ?? 460,
60915
- minWidth: options.minWidth ?? 320,
60916
- maxWidth: options.maxWidth
60917
- }, options.content !== void 0 ? options.content() : internalSwitch ? (0, import_react64.createElement)(PreviewBody, { options, onClose: close }) : (0, import_react64.createElement)(FileBrowser, {
60918
- workspaceFiles: options.workspaceFiles,
60919
- officeToPdf: options.officeToPdf ?? null,
60920
- sessionId: options.sessionId,
60921
- path: options.path,
60922
- rootName: options.rootName,
60923
- workspaces: options.workspaces,
60924
- workspaceAnchors: options.workspaceAnchors,
60925
- onSelectWorkspace: options.onSelectWorkspace,
60926
- rootCache: options.rootCache,
60927
- translate: options.translate,
60928
- // 传 onClose ⇒ FileBrowser 在面包屑行尾渲染自己的 ✕(垂直居中,与 pick 一致)。
60929
- onClose: close,
60930
- style: { height: "100%", minHeight: 0 }
60931
- })))
60932
- ));
60933
- activePreviewClose = close;
60934
- return { close, path: options.path ?? "" };
61090
+ let pinnedWidth = null;
61091
+ const keepWidth = () => {
61092
+ const panel = container.querySelector(".dshpc-dock__panel");
61093
+ if (panel === null)
61094
+ return;
61095
+ const width = Math.round(panel.getBoundingClientRect().width);
61096
+ if (width < (options.minWidth ?? 320))
61097
+ return;
61098
+ pinnedWidth = width;
61099
+ dock.setWidth(PREVIEW_PANEL_ID, width);
61100
+ };
61101
+ const draw = (o) => {
61102
+ if (dock.isCollapsed(PREVIEW_PANEL_ID))
61103
+ dock.expand(PREVIEW_PANEL_ID);
61104
+ const internalSwitch = o.onSelectWorkspace === void 0;
61105
+ const contentKey = o.path ?? "";
61106
+ root.render((0, import_react64.createElement)(
61107
+ "div",
61108
+ // 高度吃调用方给的 --dshpc-dock-h(demo 的页面行给 100%);退化成视口高是整页场景。
61109
+ { style: { display: "contents", ["--dshpc-dock-h"]: "100%" } },
61110
+ (0, import_react64.createElement)(PanelDock, { dock, mainMinWidth: o.mainMinWidth ?? 480, translate: o.translate }, (0, import_react64.createElement)(DockPanel, {
61111
+ id: PREVIEW_PANEL_ID,
61112
+ // 不要头部(用户 2026-10-21:核心的『无 header』那版)——上面不再多一条线。
61113
+ header: null,
61114
+ // 关闭钮不用核心浮动的(那是 absolute 固定偏移、不垂直居中);关掉它的,
61115
+ // 改用 FileBrowser 自己的 ✕(和 pick 弹窗同一个 crumb-bar 钮,垂直居中)。
61116
+ closeButton: "none",
61117
+ ariaLabel: o.title,
61118
+ // 重画时沿用用户拖出来的宽度(pinnedWidth),不回到默认值。
61119
+ width: pinnedWidth ?? o.width ?? 460,
61120
+ minWidth: o.minWidth ?? 320,
61121
+ maxWidth: o.maxWidth
61122
+ }, o.content !== void 0 ? o.content() : internalSwitch ? (0, import_react64.createElement)(PreviewBody, { key: contentKey, options: o, onClose: close }) : (0, import_react64.createElement)(FileBrowser, {
61123
+ key: contentKey,
61124
+ workspaceFiles: o.workspaceFiles,
61125
+ officeToPdf: o.officeToPdf ?? null,
61126
+ sessionId: o.sessionId,
61127
+ path: o.path,
61128
+ rootName: o.rootName,
61129
+ workspaces: o.workspaces,
61130
+ workspaceAnchors: o.workspaceAnchors,
61131
+ onSelectWorkspace: o.onSelectWorkspace,
61132
+ rootCache: o.rootCache,
61133
+ translate: o.translate,
61134
+ // 传 onClose ⇒ FileBrowser 在面包屑行尾渲染自己的 ✕(垂直居中,与 pick 一致)。
61135
+ onClose: close,
61136
+ style: { height: "100%", minHeight: 0 }
61137
+ })))
61138
+ ));
61139
+ };
61140
+ draw(opts);
61141
+ activePreview = { adopt, keepWidth, draw, close };
61142
+ return { close, path: opts.path ?? "" };
60935
61143
  }
60936
61144
  var PICKER_WIDTH = 480;
60937
61145
  var PICKER_MAX_H = 660;
@@ -60943,6 +61151,13 @@ function pickWorkspaceFile(options) {
60943
61151
  resolve(null);
60944
61152
  return;
60945
61153
  }
61154
+ const files = options.workspaceFiles ?? getWorkspaceFiles();
61155
+ const sessionId = options.sessionId ?? pickWorkspaceAnchor(workspaceList.getSnapshot())?.sessionId;
61156
+ if (files === void 0 || sessionId === void 0) {
61157
+ console.warn("[dsh-plugin-core/explorer] pickWorkspaceFile: " + (files === void 0 ? "\u6CA1\u6709\u5DE5\u4F5C\u533A\u6587\u4EF6\u670D\u52A1\uFF08client apply \u91CC\u6CA1\u8C03 connectHost\uFF09" : "\u627E\u4E0D\u5230\u53EF\u7528\u7684\u5DE5\u4F5C\u533A\u4F1A\u8BDD") + " \u21D2 \u4E0D\u5F39\u9009\u62E9\u6846");
61158
+ resolve(null);
61159
+ return;
61160
+ }
60946
61161
  let settled = false;
60947
61162
  const backdrop = document.createElement("div");
60948
61163
  backdrop.setAttribute("data-dshpc-picker-backdrop", "");
@@ -60991,9 +61206,9 @@ function pickWorkspaceFile(options) {
60991
61206
  ensureControls(getStyleKit());
60992
61207
  const root = (0, import_client5.createRoot)(panel);
60993
61208
  root.render((0, import_react64.createElement)(FileBrowser, {
60994
- workspaceFiles: options.workspaceFiles,
61209
+ workspaceFiles: files,
60995
61210
  officeToPdf: options.officeToPdf ?? null,
60996
- sessionId: options.sessionId,
61211
+ sessionId,
60997
61212
  path: "",
60998
61213
  rootName: options.rootName,
60999
61214
  rootCache: options.rootCache,
@@ -61065,21 +61280,18 @@ async function findSamples(files, sessionId) {
61065
61280
  var CODE_OPEN = `// \u53F3\u4FA7\u5206\u680F\u9884\u89C8\uFF08\u5360\u5BBD\u5EA6\u3001\u6324\u7A84\u4E3B\u533A\uFF1B\u4E0D\u662F\u6D6E\u5C42\uFF09
61066
61281
  import { openFilePreview } from 'dsh-plugin-core/explorer'
61067
61282
 
61283
+ // apply \u91CC connectHost(ctx) \u63A5\u7EBF\u4E00\u6B21\uFF0C\u4E4B\u540E\u53EA\u8981\u4E00\u4E2A\u5BB9\u5668 + \u4E00\u4E2A\u8DEF\u5F84\uFF1A
61068
61284
  openFilePreview({
61069
- mount, // \u4F60\u9875\u9762\u91CC\u90A3\u4E00\u5C42 flex \u884C\uFF0C\u4E0D\u8981\u4F20 document.body \u518D\u81EA\u5DF1\u5957 fixed
61070
- workspaceFiles, // \u4ECE ctx \u53D6\u51FA\u540E\u6CE8\u5165\uFF08host \u80FD\u529B\uFF09
61071
- sessionId, // \u4F1A\u8BDD\u4F5C\u7528\u57DF\uFF08\u9ED8\u8BA4\u951A\u70B9\uFF09
61072
- path: p, // \u7EDD\u5BF9\u8DEF\u5F84\u4E5F\u53EF\u4EE5
61073
- rootName: '\u6211\u7684\u9879\u76EE',
61285
+ mount, // \u4F60\u9875\u9762\u91CC\u5305\u4F4F\u4E3B\u533A\u7684\u90A3\u4E2A\u5143\u7D20\uFF08\u4E0D\u5FC5\u5199\u6210 flex\uFF0C\u6838\u5FC3\u4F1A\u8865\u3001\u5173\u95ED\u5373\u8FD8\u539F\uFF09
61286
+ path: p, // \u6587\u4EF6\u6216\u6587\u4EF6\u5939\u90FD\u884C\uFF1B\u7EDD\u5BF9\u8DEF\u5F84\u4E5F\u53EF\u4EE5
61074
61287
  })
61075
- // path \u662F\u7EDD\u5BF9\u8DEF\u5F84\u65F6\uFF1A\u6838\u5FC3\u81EA\u52A8\u8BFB\u5BBF\u4E3B workspaces \u5FEB\u7167\uFF08\u63D2\u4EF6 apply \u91CC connectHost \u6CE8\u5165\u8FC7\uFF09\uFF0C
61076
- // \u6309\u6700\u957F\u524D\u7F00\u5339\u914D\u6240\u5C5E\u5DE5\u4F5C\u533A\u3001list \u6362\u8BE5\u5DE5\u4F5C\u533A\u7684\u4F1A\u8BDD \u21D2 \u9762\u5305\u5C51/\u76EE\u5F55\u6811\u6B63\u5E38\uFF1B
61077
- // \u25BE \u4E0B\u62C9\u300C\u5207\u5DE5\u4F5C\u533A\u300D\u540C\u6837\u81EA\u52A8\u53EF\u7528\uFF08\u65E0\u4F1A\u8BDD\u7684\u5DE5\u4F5C\u533A\u4E0D\u8FDB\u5217\u8868\uFF09\u3002
61078
- // \u8981\u8986\u76D6\u5FEB\u7167\u624D\u663E\u5F0F\u4F20 workspaceAnchors\uFF08\u5BBF\u4E3B workspaces \u5FEB\u7167\u539F\u6837\uFF09\u3002`;
61288
+ // \u6587\u4EF6\u670D\u52A1 / \u4F1A\u8BDD / \u5DE5\u4F5C\u533A\u5FEB\u7167\u5168\u7531\u6838\u5FC3\u89E3\uFF1A\u7EDD\u5BF9\u8DEF\u5F84\u6309\u6700\u957F\u524D\u7F00\u5339\u914D\u6240\u5C5E\u5DE5\u4F5C\u533A\uFF08connectHost \u6CE8\u5165\u7684
61289
+ // \u5BBF\u4E3B workspaces \u5FEB\u7167\uFF09\uFF1B\u843D\u5728\u5DE5\u4F5C\u533A\u5916 \u21D2 \u6587\u4EF6\u7167\u5E38\u9884\u89C8\u3001\u76EE\u5F55\u6811\u9000\u5316\u6210\u53EA\u8BFB\u8DEF\u5F84\u680F\u3002
61290
+ // \u8981\u8986\u76D6\u5FEB\u7167\u624D\u4F20 workspaceAnchors\uFF0C\u8981\u6307\u5B9A\u4F1A\u8BDD\u624D\u4F20 sessionId\u3002`;
61079
61291
  var CODE_PICK = `// \u951A\u5B9A\u6309\u94AE\u65C1\u5F39\u6A21\u6001\u9009\u6587\u4EF6\uFF08Promise \u8FD4\u56DE\u5DE5\u4F5C\u533A\u76F8\u5BF9\u8DEF\u5F84\uFF0C\u4E0D\u81EA\u5DF1\u6302 dock\uFF09
61080
61292
  import { pickWorkspaceFile } from 'dsh-plugin-core/explorer'
61081
61293
 
61082
- const r = await pickWorkspaceFile({ workspaceFiles, sessionId, anchor: btn, filter: { exts: ['js', 'md'] } })
61294
+ const r = await pickWorkspaceFile({ anchor: btn, filter: { exts: ['js', 'md'] } })
61083
61295
  // r = { path, isDir }`;
61084
61296
  var CODE_SESSION_REAL = `// \u771F\u5B9E\u5BBF\u4E3B\uFF1Asessions.list \u5FEB\u7167\uFF08\u51B7\u5B89\u5168\uFF0C\u4E0D\u6FC0\u6D3B Agent\uFF09\u2192 \u70B9\u5F00\u771F\u9884\u89C8
61085
61297
  // \u670D\u52A1\u6765\u81EA package.json dsh.client.inject \u7684\u4E09\u4E2A\u5B98\u65B9\u5305\uFF1A
@@ -61102,7 +61314,7 @@ h(SessionViewModal, {
61102
61314
  forkSession: (id, atSeq) => sessions.fork({ sessionId: id, increaseTitle: true, atSeq }),
61103
61315
  openHostSession: (id) => uiWorkspace.openSession(id),
61104
61316
  // \u6587\u4EF6\u94FE\u63A5 \u2192 **\u9875\u9762\u53F3\u4FA7**\u5F00\u6838\u5FC3\u6587\u4EF6\u9884\u89C8 dock\uFF08\u6324\u7A84\u4E3B\u533A\uFF09
61105
- onOpenFile: (path) => openFilePreview({ mount: pageRow.element, workspaceFiles, path, ... }),
61317
+ onOpenFile: (path) => openFilePreview({ mount: pageRow.element, path, ... }),
61106
61318
  // \u4E0D\u7528\u7ED9\u5F39\u7A97\u4EFB\u4F55\u5BBD\u5EA6\u53C2\u6570\uFF1Adock \u628A\u5360\u5BBD\u53D1\u5E03\u6210 CSS \u53D8\u91CF\uFF0C\u906E\u7F69\u81EA\u5DF1\u8BA9\u4F4D\uFF08\u7528\u6237 2026-10-22\uFF09
61107
61319
  })`;
61108
61320
  var CODE_BLOCKS_USAGE = `pnpm add dsh-plugin-core
@@ -61110,10 +61322,10 @@ var CODE_BLOCKS_USAGE = `pnpm add dsh-plugin-core
61110
61322
  import { openFilePreview, pickWorkspaceFile } from 'dsh-plugin-core/explorer'
61111
61323
  import { openSessionView, SessionViewModal } from 'dsh-plugin-core/session'`;
61112
61324
  function useExplorerHost() {
61113
- const { workspaceFiles, officeToPdf } = (0, import_react65.useSyncExternalStore)(fileServices.subscribe, fileServices.getSnapshot);
61325
+ const { workspaceFiles: workspaceFiles2, officeToPdf } = (0, import_react65.useSyncExternalStore)(fileServices.subscribe, fileServices.getSnapshot);
61114
61326
  const wsItems = (0, import_react65.useSyncExternalStore)(workspaceList.subscribe, workspaceList.getSnapshot);
61115
61327
  const anchor = pickWorkspaceAnchor(wsItems);
61116
- return { workspaceFiles, officeToPdf, anchor, workspaceNames: wsItems.map((w) => w.title) };
61328
+ return { workspaceFiles: workspaceFiles2, officeToPdf, anchor, workspaceNames: wsItems.map((w) => w.title) };
61117
61329
  }
61118
61330
  function NotReady(props) {
61119
61331
  return (0, import_react65.createElement)(
@@ -61123,23 +61335,23 @@ function NotReady(props) {
61123
61335
  );
61124
61336
  }
61125
61337
  function OpenPreviewDemo() {
61126
- const { workspaceFiles, anchor, workspaceNames } = useExplorerHost();
61338
+ const { workspaceFiles: workspaceFiles2, anchor, workspaceNames } = useExplorerHost();
61127
61339
  const [samples, setSamples] = (0, import_react65.useState)(null);
61128
61340
  const [phase, setPhase] = (0, import_react65.useState)("idle");
61129
61341
  const [last2, setLast] = (0, import_react65.useState)(null);
61130
61342
  const pending = (0, import_react65.useRef)(null);
61131
61343
  const sessionId = anchor === null ? null : anchor.sessionId;
61132
61344
  (0, import_react65.useEffect)(() => {
61133
- if (workspaceFiles === null || sessionId === null) return;
61345
+ if (workspaceFiles2 === null || sessionId === null) return;
61134
61346
  if (pending.current !== null) return;
61135
61347
  setPhase("probing");
61136
- pending.current = findSamples(workspaceFiles, sessionId).then((s) => {
61348
+ pending.current = findSamples(workspaceFiles2, sessionId).then((s) => {
61137
61349
  setSamples(s);
61138
61350
  setPhase(s === null ? "missing" : "found");
61139
61351
  return s;
61140
61352
  });
61141
- }, [workspaceFiles, sessionId]);
61142
- if (workspaceFiles === null) return (0, import_react65.createElement)(NotReady, { which: "files" });
61353
+ }, [workspaceFiles2, sessionId]);
61354
+ if (workspaceFiles2 === null) return (0, import_react65.createElement)(NotReady, { which: "files" });
61143
61355
  if (anchor === null) return (0, import_react65.createElement)(NotReady, { which: "anchor" });
61144
61356
  const open = (path, rootName, workspaces) => {
61145
61357
  const mount = pageRow.element;
@@ -61147,7 +61359,7 @@ function OpenPreviewDemo() {
61147
61359
  console.warn("[demo] pageRow \u672A\u5C31\u7EEA\uFF0C\u65E0\u6CD5\u505C\u9760\u9884\u89C8");
61148
61360
  return;
61149
61361
  }
61150
- openFilePreview({ mount, workspaceFiles, sessionId: anchor.sessionId, path, rootName, workspaces });
61362
+ openFilePreview({ mount, sessionId: anchor.sessionId, path, rootName, workspaces });
61151
61363
  setLast(path === "" ? `${rootName}\uFF08\u6839\uFF09` : path);
61152
61364
  };
61153
61365
  const sampleLabel = (normal3) => phase === "missing" ? t3("samplesNotFound") : t3(normal3);
@@ -61171,13 +61383,12 @@ function OpenPreviewDemo() {
61171
61383
  );
61172
61384
  }
61173
61385
  function PickFileDemo() {
61174
- const { workspaceFiles, anchor } = useExplorerHost();
61386
+ const { workspaceFiles: workspaceFiles2, anchor } = useExplorerHost();
61175
61387
  const [picked, setPicked] = (0, import_react65.useState)(null);
61176
- if (workspaceFiles === null) return (0, import_react65.createElement)(NotReady, { which: "files" });
61388
+ if (workspaceFiles2 === null) return (0, import_react65.createElement)(NotReady, { which: "files" });
61177
61389
  if (anchor === null) return (0, import_react65.createElement)(NotReady, { which: "anchor" });
61178
61390
  const pick2 = (anchorBtn, filter2) => {
61179
61391
  void pickWorkspaceFile({
61180
- workspaceFiles,
61181
61392
  sessionId: anchor.sessionId,
61182
61393
  anchor: anchorBtn,
61183
61394
  rootName: anchor.title,
@@ -61213,15 +61424,14 @@ function RealSessionListDemo() {
61213
61424
  const anchor = pickWorkspaceAnchor(wsItems);
61214
61425
  const [openId, setOpenId] = (0, import_react65.useState)(null);
61215
61426
  const view = (0, import_react65.useMemo)(() => openId === null ? null : openRealSessionView(openId), [openId]);
61216
- const workspaceFiles = files.workspaceFiles;
61217
- const canOpenFile = workspaceFiles !== null && anchor !== null;
61427
+ const workspaceFiles2 = files.workspaceFiles;
61428
+ const canOpenFile = workspaceFiles2 !== null && anchor !== null;
61218
61429
  const openLinkedFile = (path, sessionId) => {
61219
61430
  console.log("[preview] openLinkedFile path=", JSON.stringify(path), "sessionId=", sessionId, "anchorSessionId=", anchor?.sessionId);
61220
61431
  const mount = pageRow.element;
61221
- if (mount === null || workspaceFiles === null || anchor === null) return;
61432
+ if (mount === null || workspaceFiles2 === null || anchor === null) return;
61222
61433
  openFilePreview({
61223
61434
  mount,
61224
- workspaceFiles,
61225
61435
  officeToPdf: files.officeToPdf,
61226
61436
  // 文件 RPC 按会话作用域取工作区:优先用调用方透传的「文件所属会话」,
61227
61437
  // 兜底才用当前工作区锚点会话(explorer 页那种没上下文的入口)。
@@ -61237,7 +61447,6 @@ function RealSessionListDemo() {
61237
61447
  let handle = null;
61238
61448
  handle = openFilePreview({
61239
61449
  mount,
61240
- workspaceFiles: workspaceFiles ?? void 0,
61241
61450
  sessionId: loc.sessionId,
61242
61451
  path: "",
61243
61452
  content: () => (0, import_react65.createElement)(ChangedFileDiff, {
@@ -61518,9 +61727,9 @@ function ReferencePage() {
61518
61727
  "tbody",
61519
61728
  null,
61520
61729
  [
61521
- [t3("buildCore"), `v${"0.6.1"}`],
61522
- [t3("buildDemo"), `v${"0.6.1"}`],
61523
- [t3("buildStamp"), "261028-041151-097"]
61730
+ [t3("buildCore"), `v${"0.7.1"}`],
61731
+ [t3("buildDemo"), `v${"0.7.1"}`],
61732
+ [t3("buildStamp"), "261028-075655-587"]
61524
61733
  ].map(
61525
61734
  ([label, value]) => (0, import_react67.createElement)(
61526
61735
  "tr",
@@ -61842,9 +62051,9 @@ function DemoPage() {
61842
62051
  lineHeight: "14px"
61843
62052
  }
61844
62053
  },
61845
- (0, import_react69.createElement)("span", null, `core v${"0.6.1"}`),
61846
- (0, import_react69.createElement)("span", null, `demo v${"0.6.1"}`),
61847
- (0, import_react69.createElement)("span", { style: { marginTop: "4px", fontSize: "9px" } }, "261028-041151-097")
62054
+ (0, import_react69.createElement)("span", null, `core v${"0.7.1"}`),
62055
+ (0, import_react69.createElement)("span", null, `demo v${"0.7.1"}`),
62056
+ (0, import_react69.createElement)("span", { style: { marginTop: "4px", fontSize: "9px" } }, "261028-075655-587")
61848
62057
  )
61849
62058
  )
61850
62059
  ),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-core-demo",
3
- "version": "0.6.1",
3
+ "version": "0.7.1",
4
4
  "description": "The shared UI foundation for DSH plugins, with a live component preview: design tokens, common controls, workspace browsing and notifications maintained in one place — install it to preview every component in a real host.",
5
5
  "icon": "./assets/icon-components.svg",
6
6
  "keywords": [