dsh-vscode-mode 0.1.61 → 0.1.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/client.js +646 -50
- package/lib/client.js.map +1 -1
- package/lib/index.js +3 -1
- package/lib/index.js.map +1 -1
- package/package.json +1 -1
- package/src/client/index.ts +23 -4
- package/src/client/keybindings.ts +2 -0
- package/src/client/monaco/loader.ts +3 -3
- package/src/client/monaco/theme.ts +313 -7
- package/src/client/officialSidebar.ts +45 -0
- package/src/client/outline/index.ts +4 -3
- package/src/client/sidebar/SidebarView.ts +16 -1
- package/src/client/sidebar/panels/FileExplorer.ts +58 -4
- package/src/client/sidebar/panels/index.ts +12 -10
- package/src/client/sidebar/types.ts +2 -2
- package/src/client/styles/editor.css +34 -29
- package/src/client/ui/ClaimRouter.ts +96 -0
- package/src/client/ui/EditorView.ts +70 -14
- package/src/client/ui/OfficialSideTab.ts +8 -9
- package/src/client-primitives.d.ts +37 -0
- package/src/shared/keybindings.ts +3 -0
package/lib/client.js
CHANGED
|
@@ -29,9 +29,10 @@ window.__ModuleLoader__.load({
|
|
|
29
29
|
let react = require("react");
|
|
30
30
|
react = __toESM(react, 1);
|
|
31
31
|
let react_dom_client = require("react-dom/client");
|
|
32
|
+
let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
|
|
32
33
|
let react_dom = require("react-dom");
|
|
33
34
|
//#region \0dsh-css:/home/runner/work/DSH_VsCodeMode/DSH_VsCodeMode/src/client/styles/editor.css.mjs
|
|
34
|
-
const css$1 = "/* dsh-vscode-mode 编辑区样式(原 ensureEdrvStyles 字符串,落盘为真 .css,由 tsdown CSS-inline 注入) */\n/* 浅色主题(对齐参考图:#f8f8f8 近白底 + 薄荷绿药丸 + 青绿文字 + 三文鱼 undo + 浅灰边框):\n 在 [data-edrv-view] 作用域内重定义 --dsw-alias-*,级联命中组件内联样式与 CSS。 */\n[data-edrv-view] { box-sizing: border-box; --edrv-tab-h: 34px; --dsw-alias-bg-base: #f8f8f8; --dsw-alias-bg-layer-1: #ffffff; --dsw-alias-bg-layer-2: #f0f4f4; --dsw-alias-bg-overlay: #ffffff; --dsw-alias-label-primary: #1f2933; --dsw-alias-label-secondary: #52606d; --dsw-alias-label-tertiary: #9aa5b1; --dsw-alias-border-l1: #e0e6e8; --dsw-alias-border-l2: #cbd2d9; --dsw-alias-brand-primary: #0f9d58; --dsw-alias-state-success-primary: #0f9d58; --dsw-alias-state-error-primary: #d9534f; --dsw-alias-state-warn-primary: #d97706; --dsw-alias-interactive-bg-hover: rgba(15,157,88,.08); }\n\n[data-edrv-view] .edrv-tabs { display: flex; align-items: center; gap: 2px; padding: 2px 8px 0; background: var(--dsw-alias-bg-layer-1, transparent); overflow-x: auto; scrollbar-width: thin; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 8px 0 12px; border: none; border-radius: 6px 6px 0 0; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); font-size: 12px; cursor: pointer; white-space: nowrap; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-tab.edrv-tab-active { background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); box-shadow: inset 0 -2px 0 var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-tab .edrv-tab-dot { width: 7px; height: 7px; border-radius: 50%; background: var(--dsw-alias-brand-primary, #4f8cff); flex-shrink: 0; }\n[data-edrv-view] .edrv-tab .edrv-tab-x { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 4px; color: var(--dsw-alias-label-tertiary, #888); font-size: 11px; }\n[data-edrv-view] .edrv-tab .edrv-tab-x:hover { background: rgba(255,255,255,.12); color: var(--dsw-alias-label-primary, #eee); }\n[data-edrv-view] .edrv-tab-add { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; margin-left: 2px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); font-size: 14px; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab-add:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-pathbar { display: flex; align-items: center; gap: 8px; height: 26px; padding: 0 10px; background: var(--dsw-alias-bg-layer-1, #ffffff); border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); font-size: 12px; flex-shrink: 0; overflow: hidden; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-name { font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); white-space: nowrap; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-full { flex: 1; min-width: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; direction: rtl; text-align: left; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-meta { flex-shrink: 0; font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-variant-numeric: tabular-nums; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-status { color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-path-input { flex: 1; min-width: 140px; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search-wrap { position: relative; flex-shrink: 0; display: flex; align-items: center; padding: 2px 8px 2px 4px; }\n[data-edrv-view] .edrv-search { width: 190px; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-search-pop { position: absolute; top: calc(100% + 4px); right: 8px; width: min(460px, calc(100vw - 24px)); max-height: 300px; overflow: auto; background: var(--dsw-alias-bg-overlay, #1c1c1c); border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 10px; box-shadow: 0 6px 20px rgba(0,0,0,.4); z-index: 60; padding: 4px; }\n[data-edrv-view] .edrv-search-item { display: flex; flex-direction: column; gap: 1px; padding: 5px 8px; border-radius: 6px; cursor: pointer; }\n[data-edrv-view] .edrv-search-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.07)); }\n[data-edrv-view] .edrv-search-item .n { color: var(--dsw-alias-label-primary, #eee); font-size: 12px; word-break: break-all; }\n[data-edrv-view] .edrv-search-item .d { color: var(--dsw-alias-label-tertiary, #888); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-search-empty { padding: 8px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #888); }\n[data-edrv-view] .edrv-btn-mini { font-size: 11px; padding: 2px 9px; border: none; border-radius: 999px; cursor: pointer; color: #fff; font-weight: 600; white-space: nowrap; }\n[data-edrv-view] .edrv-btn-keep { background: var(--dsw-alias-state-success-primary, #2e9e44); }\n[data-edrv-view] .edrv-btn-undo { background: var(--dsw-alias-state-warn-primary, #d97706); }\n[data-edrv-view] .edrv-btn-mini:disabled { opacity: .45; cursor: default; }\n[data-edrv-view] .edrv-statusbar { display: flex; align-items: center; gap: 10px; padding: 3px 10px; border-top: 1px solid var(--dsw-alias-border-l1, #333); background: var(--dsw-alias-bg-layer-1, transparent); font-size: 11px; color: var(--dsw-alias-label-tertiary, #888); flex-shrink: 0; white-space: nowrap; overflow: hidden; }\n[data-edrv-view] .edrv-statusbar .edrv-sp-path { flex: 1; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-statusbar .edrv-sp-lsp { flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-statusbar .edrv-sp-progress-message { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-statusbar .edrv-sp-progress { flex: 0 0 auto; min-width: 36px; text-align: right; font-variant-numeric: tabular-nums; color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-lsp-status-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; background: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-lsp-status-dot.ready { background: var(--dsw-alias-state-success-primary, #0f9d58); }\n[data-edrv-view] .edrv-lsp-status-dot.busy { background: var(--dsw-alias-state-warn-primary, #d97706); animation: edrv-lsp-pulse 1.2s ease-in-out infinite; }\n@keyframes edrv-lsp-pulse { 50% { opacity: .45; } }\n/* Ctrl+hover 可导航标识符下划线提示(绑定 Monaco inlineClassName 装饰) */\n[data-edrv-view] .edrv-nav-underline { text-decoration: underline; text-decoration-color: var(--dsw-alias-interactive-primary, #4fc1ff); text-underline-offset: 1px; cursor: pointer; }\n[data-edrv-view] .edrv-diffchip { font-size: 11px; padding: 2px 10px; border: 1px solid var(--dsw-alias-border-l1, #333); border-radius: 999px; background: var(--dsw-alias-bg-layer-2, transparent); color: var(--dsw-alias-state-warn-primary, #b7791f); cursor: pointer; white-space: nowrap; flex-shrink: 0; }\n[data-edrv-view] .edrv-chip-btn { font-size: 12px; padding: 2px 6px; border: none; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); cursor: pointer; border-radius: 4px; flex-shrink: 0; }\n[data-edrv-view] .edrv-chip-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-chip-btn:disabled { opacity: .35; cursor: default; }\n[data-edrv-view] .edrv-chip-btn:disabled:hover { background: transparent; }\n[data-edrv-view] .edrv-mn-add-line { background: rgba(15,157,88,.10); }\n[data-edrv-view] .edrv-mn-gutter-add { color: #0f9d58 !important; font-weight: 700; display: flex !important; align-items: center; justify-content: center; }\n[data-edrv-view] .edrv-mn-gutter-add::before { content: \"+\"; }\n[data-edrv-view] .edrv-del-zone { background: #fdeaea; border-top: 1px solid rgba(217,83,79,.35); border-bottom: 1px solid rgba(217,83,79,.35); box-shadow: inset 0 0 0 1px rgba(217,83,79,.12); }\n[data-edrv-view] .edrv-del-row { white-space: pre; font-family: var(--ds-font-family-code, ui-monospace, monospace); font-size: 12.5px; line-height: 20px; color: #c0392b; }\n[data-edrv-view] .edrv-del-text { display: inline-block; white-space: pre; }\n[data-edrv-view] .edrv-minus-overlay { position: absolute; left: 0; top: 0; width: 100%; height: 100%; max-width: 100%; overflow: visible; pointer-events: none; z-index: 6; }\n[data-edrv-view] .edrv-minus-item { position: absolute; box-sizing: border-box; max-width: 100%; overflow: hidden; }\n[data-edrv-view] .edrv-minus-item::before { content: ''; position: absolute; left: 4px; top: 50%; width: 8px; height: 2px; transform: translateY(-50%); border-radius: 2px; background: #d9534f; }\n[data-edrv-view] .edrv-monaco-host { flex: 1 1 auto; min-width: 0; min-height: 0; position: relative; overflow: hidden; }\n[data-edrv-view] .edrv-monaco-host > div { position: absolute; inset: 0; min-width: 0; min-height: 0; }\n[data-edrv-view] .edrv-imgview { flex: 1 1 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }\n[data-edrv-view] .edrv-imgview-bar { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px; flex-shrink: 0; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); background: var(--dsw-alias-bg-layer-1, transparent); }\n[data-edrv-view] .edrv-imgview-meta { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; }\n[data-edrv-view] .edrv-imgview-stage { flex: 1 1 auto; min-height: 0; display: flex; align-items: center; justify-content: center; overflow: auto; padding: 14px; background-color: var(--dsw-alias-bg-layer-1, #f0f4f4); background-image: conic-gradient(rgba(128,128,128,.14) 25%, transparent 0 50%, rgba(128,128,128,.14) 0 75%, transparent 0); background-size: 16px 16px; }\n[data-edrv-view] .edrv-imgview-img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 4px; box-shadow: 0 2px 12px rgba(31,41,51,.18); }\n[data-edrv-view] .edrv-imgview-broken { display: flex; flex-direction: column; align-items: center; gap: 10px; font-size: 13px; color: var(--dsw-alias-label-tertiary, #777); }\n[data-edrv-view] .edrv-pdf-host { flex: 1 1 auto; min-width: 0; min-height: 0; position: relative; overflow: hidden; }\n[data-edrv-view] .edrv-pdf-host > .edrv-pdf { position: absolute; inset: 0; }\n[data-edrv-view] .edrv-pdf { min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }\n[data-edrv-view] .edrv-pdf-bar { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px; flex-shrink: 0; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); background: var(--dsw-alias-bg-layer-1, transparent); }\n[data-edrv-view] .edrv-pdf-page { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; min-width: 52px; text-align: center; }\n[data-edrv-view] .edrv-pdf-zoom { min-width: 26px; text-align: center; padding: 3px 7px; }\n[data-edrv-view] .edrv-pdf-sep { width: 1px; height: 16px; background: var(--dsw-alias-border-l1, #e0e6e8); margin: 0 2px; }\n[data-edrv-view] .edrv-pdf-mode-on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); color: var(--dsw-alias-brand-primary, #0f9d58); border-color: var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-pdf-dirty { color: var(--dsw-alias-state-warn-primary, #d97706); border-color: var(--dsw-alias-state-warn-primary, #d97706); }\n[data-edrv-view] .edrv-pdf-stage { position: absolute; top: 34px; left: 0; right: 0; bottom: 0; overflow: auto; }\n[data-edrv-view] .edrv-pdf-stage .edrv-pdf-viewer { margin: 0 auto; }\n[data-edrv-view] .edrv-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; height: 100%; color: var(--dsw-alias-label-tertiary, #777); font-size: 13px; }\n[data-edrv-view] .edrv-diffbar { position: absolute; left: 0; right: 0; bottom: 10px; margin: 0 auto; z-index: 25; width: fit-content; max-width: calc(100% - 20px); border-radius: 12px; background: var(--dsw-specific-tip, var(--dsw-alias-bg-layer-2, #f0f4f4)); border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); box-shadow: none; overflow: visible; display: flex; flex-direction: column; }\n[data-edrv-view] .edrv-editor-area > .edrv-diffbar { max-height: calc(100% - 20px); }\n[data-edrv-view] .edrv-diffbar-row { display: flex; align-items: center; gap: 6px; height: 36px; padding: 4px 5px 4px 12px; flex-wrap: nowrap; }\n[data-edrv-view] .edrv-diffbar-count { font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); min-width: 42px; text-align: center; white-space: nowrap; cursor: pointer; }\n[data-edrv-view] .edrv-diffbar-count.edrv-count-file { min-width: 64px; cursor: default; }\n[data-edrv-view] .edrv-diffbar-file { flex: 1; min-width: 0; font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-pill { font-size: 11px; padding: 3px 10px; border: none; border-radius: 999px; cursor: pointer; white-space: nowrap; font-weight: 600; }\n[data-edrv-view] .edrv-pill-keep { background: #e8f8e8; color: #0f7a45; border: 1px solid rgba(15,157,88,.4); }\n[data-edrv-view] .edrv-pill-undo { background: #fdeaea; color: #c0392b; border: 1px solid rgba(217,83,79,.4); }\n[data-edrv-view] .edrv-pill-ghost { background: #ffffff; color: var(--dsw-alias-label-secondary, #52606d); border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-pill:disabled { opacity: .45; cursor: default; }\n[data-edrv-view] .edrv-diffbar-menu { position: absolute; right: 8px; bottom: calc(100% + 6px); z-index: 45; min-width: 160px; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 6px 20px rgba(31,41,51,.16); padding: 4px; display: flex; flex-direction: column; gap: 2px; }\n[data-edrv-view] .edrv-diffmenu-item { display: flex; align-items: center; gap: 8px; font-size: 12px; padding: 6px 10px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; text-align: left; }\n[data-edrv-view] .edrv-diffmenu-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-diffmenu-item.danger { color: var(--dsw-alias-state-error-primary, #d9534f); }\n[data-edrv-view] .edrv-diffmenu-sep { height: 1px; margin: 2px 4px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n/* 编辑区 / Tab 右键菜单(添加文件/选中内容到对话) */\n[data-edrv-view] .edrv-ctxmenu { position: fixed; z-index: 71; min-width: 200px; max-width: 320px; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 8px 26px rgba(31,41,51,.2); padding: 4px; display: flex; flex-direction: column; gap: 1px; }\n[data-edrv-view] .edrv-ctxmenu-item { display: flex; align-items: center; gap: 8px; font-size: 12px; line-height: 18px; padding: 7px 10px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-ctxmenu-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-ctxmenu-item.edrv-ctxmenu-danger { color: var(--dsw-alias-state-error-primary, #d9534f); }\n[data-edrv-view] .edrv-ctxmenu-item:disabled,\n[data-edrv-view] .edrv-ctxmenu-item.edrv-ctxmenu-disabled { color: var(--dsw-alias-label-disabled, #b0b7c0); cursor: default; background: transparent; }\n[data-edrv-view] .edrv-ctxmenu-sep { height: 1px; margin: 3px 4px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-diffbar-body { max-height: 130px; max-width: min(560px, calc(100vw - 40px)); overflow: auto; padding: 4px 8px 8px; display: flex; flex-direction: column; gap: 4px; border-top: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-diffrow { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 6px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); cursor: pointer; flex-wrap: wrap; }\n[data-edrv-view] .edrv-diffrow:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-diffrow-l { font-size: 11px; color: var(--dsw-alias-label-primary, #1f2933); min-width: 74px; font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-o { font-size: 11px; color: var(--dsw-alias-state-error-primary, #d9534f); font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-n { font-size: 11px; color: var(--dsw-alias-state-success-primary, #0f9d58); font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-tag { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-diffrow-stale { border-color: rgba(217,119,6,.5); cursor: default; }\n[data-edrv-view] .edrv-diffbox-others { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 4px 2px 0; border-top: 1px solid var(--dsw-alias-border-l1, #e0e6e8); margin-top: 2px; }\n[data-edrv-view] .edrv-diffrow-file { font-size: 11px; padding: 2px 10px; border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 999px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); color: var(--dsw-alias-label-secondary, #52606d); cursor: pointer; white-space: nowrap; max-width: 200px; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-diffrow-file:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); color: var(--dsw-alias-label-primary, #1f2933); }\n/* 编辑区 hover 差异块的 Keep/Undo 浮层 */\n[data-edrv-view] .edrv-hoveract { position: absolute; z-index: 30; display: flex; align-items: center; gap: 4px; padding: 2px 6px; border-radius: 8px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 4px 14px rgba(31,41,51,.14); }\n[data-edrv-view] .edrv-launch { position: absolute; left: 12px; right: 12px; bottom: 12px; z-index: 40; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #1c1c1c); border: 1px solid var(--dsw-alias-border-l2, #555); box-shadow: 0 6px 24px rgba(0,0,0,.5); display: flex; flex-direction: column; max-height: 60%; overflow: hidden; }\n[data-edrv-view] .edrv-launch-head { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-bottom: 1px solid var(--dsw-alias-border-l1, #333); }\n[data-edrv-view] .edrv-launch-tab { font-size: 12px; padding: 3px 12px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); cursor: pointer; }\n[data-edrv-view] .edrv-launch-tab.on { background: var(--dsw-alias-bg-layer-2, transparent); color: var(--dsw-alias-label-primary, #eee); font-weight: 600; }\n[data-edrv-view] .edrv-launch-body { flex: 1; min-height: 0; overflow: auto; padding: 6px 8px; display: flex; flex-direction: column; gap: 4px; }\n[data-edrv-view] .edrv-launch-row { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1, #333); border-radius: 6px; cursor: pointer; flex-wrap: wrap; }\n[data-edrv-view] .edrv-launch-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-launch-path { flex: 1; min-width: 0; font-size: 12px; color: var(--dsw-alias-label-primary, #eee); word-break: break-all; }\n[data-edrv-view] .edrv-launch-cnt { font-size: 11px; color: var(--dsw-alias-label-tertiary, #888); white-space: nowrap; }\n[data-edrv-view] .edrv-launch-arch { display: flex; flex-direction: column; gap: 6px; }\n[data-edrv-view] .monaco-editor { overflow: hidden !important; }\n[data-edrv-view] .monaco-editor .sticky-widget { z-index: 30 !important; background: var(--dsw-alias-bg-base, #f8f8f8) !important; }\n[data-edrv-view] .monaco-editor .sticky-widget .sticky-line-content,\n[data-edrv-view] .monaco-editor .sticky-widget .sticky-line-number { background: var(--dsw-alias-bg-base, #f8f8f8) !important; }\n[data-edrv-view] .monaco-editor, [data-edrv-view] .monaco-editor .margin, [data-edrv-view] .monaco-editor-background { background: transparent !important; }\n[data-edrv-view] .monaco-editor .scrollbar .slider { background: rgba(128,128,128,.3) !important; }\n[data-edrv-view] .edrv-loading { gap: 8px; padding: 20px; }\n[data-edrv-view] .edrv-loading-title { color: var(--dsw-alias-label-primary, #1f2933); font-size: 13px; }\n[data-edrv-view] .edrv-progress { width: min(360px, 72%); height: 6px; overflow: hidden; border-radius: 999px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-progress-value { height: 100%; border-radius: inherit; background: var(--dsw-alias-brand-primary, #0f9d58); transition: width .24s ease; }\n[data-edrv-view] .edrv-loading-percent { color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; font-variant-numeric: tabular-nums; }\n@media (prefers-reduced-motion: reduce) {\n [data-edrv-view] .edrv-progress-value { transition: none; }\n}\n\n/* ===== 唯一会话级差异 dock(遵循 DSH todo/queue 原生布局) ===== */\n[data-edrv-diff-dock-shell] {\n box-sizing: border-box;\n width: calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));\n max-width: calc(var(--dsh-composer-card-max-width) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));\n margin: 0 auto;\n padding: 0;\n flex: none;\n border: 1px solid var(--dsw-alias-border-l1, #e0e6e8);\n border-radius: 12px;\n background: var(--dsw-specific-tip, var(--dsw-alias-bg-layer-2, transparent));\n box-shadow: none;\n overflow: hidden;\n}\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock {\n box-sizing: border-box;\n position: relative;\n left: auto;\n right: auto;\n bottom: auto;\n z-index: auto;\n width: 100%;\n max-width: none;\n margin: 0;\n display: flex;\n flex-direction: column;\n border: none;\n border-radius: 0;\n background: transparent;\n box-shadow: none;\n overflow: visible;\n}\n[data-edrv-diff-dock-shell] .edrv-diffbar-row { min-height: 36px; padding: 6px 12px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock-row { min-height: 36px; padding: 6px 12px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-body { max-height: 180px; overflow: auto; padding: 6px 12px 10px; border-top: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock-button { box-sizing: border-box; display: flex; align-items: center; justify-content: center; width: 100%; height: 24px; border: none; border-radius: 8px; padding: 0 12px; background: transparent; color: var(--dsw-alias-label-primary); font-size: 13px; font-weight: 500; line-height: 24px; text-align: center; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock-button:hover { background: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-diffbar-count { display: inline-flex; align-items: center; color: var(--dsw-alias-label-primary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 500; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-file { display: inline-flex; align-items: center; color: var(--dsw-alias-label-tertiary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 400; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-editor-row { display: flex; align-items: center; height: 36px; min-height: 36px; padding: 4px 12px; overflow-x: auto; scrollbar-width: thin; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-editor-content { display: flex; align-items: center; gap: 10px; width: 100%; min-width: max-content; min-height: 28px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-nav,\n[data-edrv-diff-dock-shell] .edrv-diffbar-files,\n[data-edrv-diff-dock-shell] .edrv-diffbar-actions { display: flex; align-items: center; gap: 6px; flex: none; height: 28px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-actions { margin-left: auto; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-details-toggle { display: inline-flex; align-items: center; justify-content: center; width: 28px; min-width: 28px; padding: 0; font-size: 13px; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-details-toggle svg { width: 14px; height: 14px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-files { min-width: 0; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-files .edrv-diffbar-file { min-width: 72px; max-width: 240px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-progress { min-width: 0; color: var(--dsw-alias-label-tertiary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 400; line-height: 24px; font-variant-numeric: tabular-nums; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-summary { min-width: 0; color: var(--dsw-alias-label-tertiary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 400; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-pill { box-sizing: border-box; height: 28px; padding: 0 9px; border: none; border-radius: 999px; cursor: pointer; white-space: nowrap; font-size: 11px; line-height: 26px; font-weight: 600; }\n[data-edrv-diff-dock-shell] .edrv-pill-keep { background: var(--dsw-alias-state-success-tertiary); color: var(--dsw-alias-state-success-primary); border: 1px solid var(--dsw-alias-state-success-secondary); }\n[data-edrv-diff-dock-shell] .edrv-pill-undo { background: var(--dsw-alias-state-error-tertiary); color: var(--dsw-alias-state-error-primary); border: 1px solid var(--dsw-alias-state-error-secondary); }\n[data-edrv-diff-dock-shell] .edrv-pill-ghost { background: transparent; color: var(--dsw-alias-label-secondary); border: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-pill:hover:not(:disabled) { background-color: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-pill:focus-visible { outline: 2px solid var(--dsw-alias-label-tertiary); outline-offset: -2px; }\n[data-edrv-diff-dock-shell] .edrv-pill:disabled { opacity: .45; cursor: default; }\n[data-edrv-diff-dock-shell] .edrv-diffrow { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1); border-radius: 6px; background: transparent; cursor: pointer; flex-wrap: wrap; }\n[data-edrv-diff-dock-shell] .edrv-diffrow:hover { background: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-l { color: var(--dsw-alias-label-primary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-o { color: var(--dsw-alias-state-error-primary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-n { color: var(--dsw-alias-state-success-primary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-tag { color: var(--dsw-alias-label-tertiary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-stale { border-color: var(--dsw-alias-state-warn-secondary); cursor: default; }\n[data-edrv-diff-dock-shell] .edrv-diffbox-others { border-top: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-file { border-color: var(--dsw-alias-border-l1); background: transparent; color: var(--dsw-alias-label-secondary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-file:hover { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }\n[data-edrv-diff-dock-shell] .edrv-diff-details { display: flex; flex-direction: column; gap: 2px; padding: 6px 12px 8px; border-top: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item { display: flex; align-items: center; width: 100%; min-height: 28px; gap: 8px; padding: 4px 8px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary); cursor: pointer; text-align: left; font-size: 12px; line-height: 20px; }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item.danger { color: var(--dsw-alias-state-error-primary); }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item:disabled { opacity: .45; cursor: default; }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-sep { height: 1px; margin: 2px 4px; background: var(--dsw-alias-border-l1); }\n@media (max-width: 620px) {\n [data-edrv-diff-dock-shell] .edrv-diffbar-editor-content { width: max-content; }\n [data-edrv-diff-dock-shell] .edrv-diffbar-files .edrv-diffbar-file { max-width: 160px; }\n}\n\n/* ===== 侧边栏(活动栏 + 面板区 + 文件树) ===== */\n[data-edrv-view] .edrv-editor-row { display: flex; flex: 1 1 auto; min-width: 0; min-height: 0; overflow: hidden; }\n[data-edrv-view] .edrv-main-col { box-sizing: border-box; min-width: 0; min-height: 0; overflow: hidden; }\n[data-edrv-view] .edrv-main-col > .edrv-pathbar,\n[data-edrv-view] .edrv-main-col > .edrv-tabs { flex: 0 0 auto; }\n[data-edrv-view] .edrv-editor-area { position: relative; display: flex; flex: 1 1 auto; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; }\n[data-edrv-view] .edrv-sidebar { display: flex; flex-direction: row; flex-shrink: 1; min-width: 0; height: 100%; background: var(--dsw-alias-bg-layer-1, #ffffff); border-right: 1px solid var(--dsw-alias-border-l1, #e0e6e8); overflow: hidden; }\n[data-edrv-view] .edrv-rail { display: flex; flex-direction: column; align-items: center; width: 44px; flex-shrink: 0; padding: 6px 0; background: var(--dsw-alias-bg-layer-2, #f0f4f4); border-right: 1px solid var(--dsw-alias-border-l1, #e0e6e8); gap: 4px; }\n[data-edrv-view] .edrv-rail-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border: none; border-radius: 8px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-rail-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rail-btn.edrv-rail-on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); color: var(--dsw-alias-label-primary, #1f2933); box-shadow: inset 2px 0 0 var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-rail-icon { font-size: 15px; line-height: 1; }\n[data-edrv-view] .edrv-rail-badge { position: absolute; top: 2px; right: 2px; min-width: 14px; height: 14px; padding: 0 3px; border-radius: 999px; background: var(--dsw-alias-brand-primary, #0f9d58); color: #fff; font-size: 9px; font-weight: 600; line-height: 14px; text-align: center; box-sizing: border-box; }\n[data-edrv-view] .edrv-side-body { flex: 1; min-width: 0; min-height: 0; display: flex; overflow: hidden; }\n[data-edrv-view] .edrv-side-panel { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; position: relative; }\n[data-edrv-view] .edrv-side-head { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px 0 12px; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); flex-shrink: 0; }\n[data-edrv-view] .edrv-side-title { font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); white-space: nowrap; }\n[data-edrv-view] .edrv-side-root { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-side-btn { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 12px; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-side-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-tree { flex: 1; min-height: 0; overflow: auto; padding: 4px 6px 12px; font-size: 12px; }\n[data-edrv-view] .edrv-tree-row { display: flex; align-items: center; gap: 4px; height: 22px; padding-right: 6px; border-radius: 5px; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; white-space: nowrap; }\n[data-edrv-view] .edrv-tree-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-tree-row.edrv-tree-active { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); }\n[data-edrv-view] .edrv-tree-row.edrv-tree-context { box-shadow: inset 0 0 0 1px var(--dsw-alias-brand-primary, #0f9d58); background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); }\n[data-edrv-view] .edrv-tree-chev { width: 12px; flex-shrink: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 10px; text-align: center; }\n[data-edrv-view] .edrv-tree-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-tree-name.edrv-tree-dim { color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-tree-badge { min-width: 14px; height: 14px; padding: 0 4px; border-radius: 999px; background: var(--dsw-alias-state-warn-primary, #d97706); color: #fff; font-size: 9px; font-weight: 600; line-height: 14px; text-align: center; box-sizing: border-box; flex-shrink: 0; }\n[data-edrv-view] .edrv-tree-loading { height: 22px; line-height: 22px; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; }\n[data-edrv-view] .edrv-tree-error { display: flex; align-items: center; gap: 8px; margin: 4px 2px 6px; padding: 6px 8px; border: 1px solid rgba(217,83,79,.4); border-radius: 6px; background: #fdeaea; color: var(--dsw-alias-state-error-primary, #d9534f); font-size: 11px; }\n/* 大纲面板:kind 字形 / detail / 行号 */\n[data-edrv-view] .edrv-outline-kind { display: inline-flex; align-items: center; justify-content: center; width: 14px; flex-shrink: 0; font-size: 12px; font-weight: 600; text-align: center; }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-func { color: var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-type { color: var(--dsw-alias-label-primary, #1f2933); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-data { color: var(--dsw-alias-state-warn-primary, #d97706); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-ns { color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-key { color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-outline-detail { flex-shrink: 0; max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; }\n[data-edrv-view] .edrv-outline-ln { flex-shrink: 0; padding-right: 2px; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 10px; font-variant-numeric: tabular-nums; }\n[data-edrv-view] .edrv-side-resize { width: 5px; flex-shrink: 0; cursor: col-resize; background: transparent; }\n[data-edrv-view] .edrv-side-resize:hover { background: var(--dsw-alias-brand-primary, #0f9d58); opacity: .35; }\n[data-edrv-view] .edrv-chip-btn.edrv-chip-on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); color: var(--dsw-alias-label-primary, #1f2933); }\n\n/* ===== 侧栏形态(betterSidebar 面板内编辑区) ===== */\n[data-edrv-view][data-edrv-layout='side'] { box-sizing: border-box; height: 100%; }\n\n/* ===== 侧边栏引导条(旧页签形态、未装 betterSidebar 时) ===== */\n[data-edrv-view] .edrv-side-hint { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; flex-wrap: wrap; padding: 6px 12px; font-size: 12px; color: var(--dsw-alias-label-secondary, #52606d); background: var(--dsw-specific-tip, var(--dsw-alias-bg-layer-2, #f0f4f4)); border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-side-hint-text { white-space: nowrap; }\n[data-edrv-view] .edrv-side-hint-cmd { font-size: 11px; padding: 2px 6px; border-radius: 6px; background: var(--dsw-alias-bg-layer-1, #ffffff); border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); color: var(--dsw-alias-label-primary, #1f2933); white-space: nowrap; }\n[data-edrv-view] .edrv-side-hint-close { margin-left: auto; border: none; background: transparent; color: var(--dsw-alias-label-tertiary, #9aa5b1); cursor: pointer; font-size: 14px; line-height: 1; padding: 2px 6px; border-radius: 6px; flex-shrink: 0; }\n[data-edrv-view] .edrv-side-hint-close:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); color: var(--dsw-alias-label-primary, #1f2933); }\n\n/* ===== search panel (sidebar, VSCode search view) ===== */\n[data-edrv-view] .edrv-search-panel { display: flex; flex-direction: column; min-height: 0; flex: 1; padding: 6px; gap: 4px; }\n[data-edrv-view] .edrv-search-qrow { display: flex; gap: 4px; }\n[data-edrv-view] .edrv-search-input { flex: 1; min-width: 0; height: 26px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search-input:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-search-opts { display: flex; align-items: center; gap: 2px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-search-opt { min-width: 24px; height: 22px; padding: 0 6px; border: 1px solid transparent; border-radius: 5px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 11px; font-family: var(--ds-font-family-code, ui-monospace, monospace); cursor: pointer; }\n[data-edrv-view] .edrv-search-opt:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-opt.on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); color: var(--dsw-alias-label-primary, #1f2933); border-color: var(--dsw-alias-border-l2, #d5dde3); }\n[data-edrv-view] .edrv-search-spacer { flex: 1; }\n[data-edrv-view] .edrv-search-summary { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); padding: 2px 4px; }\n[data-edrv-view] .edrv-search-results { flex: 1; min-height: 0; overflow: auto; font-size: 12px; }\n[data-edrv-view] .edrv-search-group { margin-bottom: 2px; }\n[data-edrv-view] .edrv-search-file { display: flex; align-items: center; gap: 4px; height: 22px; padding: 0 4px; border-radius: 5px; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; white-space: nowrap; }\n[data-edrv-view] .edrv-search-file:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-chev { width: 12px; flex-shrink: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 10px; text-align: center; }\n[data-edrv-view] .edrv-search-fname { font-weight: 600; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-search-fdir { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; }\n[data-edrv-view] .edrv-search-fcount { flex-shrink: 0; min-width: 16px; height: 15px; padding: 0 4px; border-radius: 999px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); color: var(--dsw-alias-label-secondary, #52606d); font-size: 10px; line-height: 15px; text-align: center; }\n[data-edrv-view] .edrv-search-line { display: flex; gap: 6px; padding: 1px 4px 1px 16px; border-radius: 4px; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; overflow: hidden; }\n[data-edrv-view] .edrv-search-line.alt { background: var(--dsw-alias-bg-layer-1, #ffffff); }\n[data-edrv-view] .edrv-search-line:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-ln { flex-shrink: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; min-width: 26px; text-align: right; user-select: none; }\n[data-edrv-view] .edrv-search-text { overflow: hidden; text-overflow: ellipsis; white-space: pre; font-family: var(--ds-font-family-code, ui-monospace, monospace); font-size: 11px; }\n[data-edrv-view] .edrv-search-hit { background: var(--dsw-alias-state-warn-primary, #e5b93f); color: #1f2933; border-radius: 2px; padding: 0 1px; }\n[data-edrv-view] .edrv-search-empty { padding: 8px 4px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-search-error { padding: 6px 8px; border: 1px solid rgba(217,83,79,.4); border-radius: 6px; background: #fdeaea; color: var(--dsw-alias-state-error-primary, #d9534f); font-size: 11px; }\n[data-edrv-view] .edrv-search-warn { padding: 6px 8px; border: 1px solid rgba(240,173,78,.45); border-radius: 6px; background: #fdf6e3; color: #b8860b; font-size: 11px; word-break: break-all; }\n\n/* include/exclude filter rows (collapsible) */\n[data-edrv-view] .edrv-search-rows { display: flex; flex-direction: column; gap: 4px; padding: 2px 0 4px; }\n[data-edrv-view] .edrv-search-row { display: flex; align-items: center; gap: 4px; }\n[data-edrv-view] .edrv-search-field { flex: 1; min-width: 0; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 11px; outline: none; }\n[data-edrv-view] .edrv-search-field:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-search-field.dim { opacity: .45; }\n[data-edrv-view] .edrv-search-field::placeholder { color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-search-toggle { min-width: 24px; height: 24px; padding: 0 5px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 12px; line-height: 1; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-search-toggle:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-toggle.on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); color: var(--dsw-alias-label-primary, #1f2933); border-color: var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-search-toggle:disabled { opacity: .4; cursor: default; }\n\n/* ===== rules panel (sidebar, Codebuddy rules view) ===== */\n[data-edrv-view] .edrv-rules-panel { display: flex; flex-direction: column; min-width: 0; min-height: 0; flex: 1; padding: 6px; gap: 4px; }\n[data-edrv-view] .edrv-rules-tabs { display: flex; align-items: center; gap: 2px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-tab { height: 24px; padding: 0 10px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 12px; cursor: pointer; }\n[data-edrv-view] .edrv-rules-tab:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-tab.on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); color: var(--dsw-alias-label-primary, #1f2933); font-weight: 600; }\n[data-edrv-view] .edrv-rules-new { margin-left: auto; height: 24px; padding: 0 10px; border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); border-radius: 6px; background: var(--dsw-alias-bg-layer-1, #fff); color: var(--dsw-alias-label-primary, #1f2933); font-size: 11px; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-new:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-ws-line { font-size: 11px; color: var(--dsw-alias-label-secondary, #52606d); padding: 0 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 0 0 auto; user-select: none; }\n[data-edrv-view] .edrv-rules-hint { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); padding: 0 2px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-list { flex: 1; min-height: 0; overflow: auto; }\n[data-edrv-view] .edrv-rules-row { display: flex; align-items: center; gap: 4px; padding: 6px 4px; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 6px; }\n[data-edrv-view] .edrv-rules-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-row.off .edrv-rules-main { opacity: .5; }\n[data-edrv-view] .edrv-rules-main { flex: 1; min-width: 0; cursor: pointer; overflow: hidden; }\n[data-edrv-view] .edrv-rules-line1 { display: flex; align-items: center; gap: 6px; min-width: 0; }\n[data-edrv-view] .edrv-rules-sub { display: flex; align-items: center; gap: 5px; margin-top: 3px; min-width: 0; }\n[data-edrv-view] .edrv-rules-sublabel { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-file { font-weight: 600; font-size: 12px; color: var(--dsw-alias-label-primary, #1f2933); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-rules-path { font-size: 10px; color: var(--dsw-alias-label-tertiary, #9aa5b1); flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-rules-type { flex-shrink: 0; height: 15px; padding: 0 5px; border-radius: 999px; font-size: 10px; line-height: 15px; }\n[data-edrv-view] .edrv-rules-type-always { background: rgba(15,157,88,.15); color: #0b7c46; }\n[data-edrv-view] .edrv-rules-type-auto { background: rgba(79,140,255,.16); color: #3367c9; }\n[data-edrv-view] .edrv-rules-type-manual { background: var(--dsw-alias-bg-layer-2, #f0f4f4); color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-rules-offtag { font-size: 10px; color: var(--dsw-alias-label-tertiary, #9aa5b1); flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-desc { font-size: 11px; color: var(--dsw-alias-label-secondary, #52606d); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 0 1 auto; }\n[data-edrv-view] .edrv-rules-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; margin-left: auto; }\n[data-edrv-view] .edrv-rules-act { min-width: 22px; height: 22px; padding: 0 4px; border: none; border-radius: 5px; background: transparent; font-size: 12px; line-height: 1; cursor: pointer; color: var(--dsw-alias-label-secondary, #52606d); display: inline-flex; align-items: center; justify-content: center; }\n[data-edrv-view] .edrv-rules-act:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-switch { position: relative; width: 30px; height: 16px; border-radius: 999px; border: none; background: #b9c4cc; cursor: pointer; transition: background .15s; flex-shrink: 0; padding: 0; }\n[data-edrv-view] .edrv-rules-switch.on { background: #7c5cff; }\n[data-edrv-view] .edrv-rules-knob { position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 50%; background: #fff; transition: left .15s; }\n[data-edrv-view] .edrv-rules-switch.on .edrv-rules-knob { left: 16px; }\n[data-edrv-view] .edrv-rules-empty { padding: 10px 4px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #9aa5b1); line-height: 1.6; }\n[data-edrv-view] .edrv-rules-err { padding: 6px 8px; border: 1px solid rgba(217,83,79,.4); border-radius: 6px; background: #fdeaea; color: var(--dsw-alias-state-error-primary, #d9534f); font-size: 11px; word-break: break-all; }\n[data-edrv-view] .edrv-rules-editor { display: flex; flex-direction: column; min-height: 0; flex: 1; gap: 6px; }\n[data-edrv-view] .edrv-rules-editor-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-crumb { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-rules-editor-ctl { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-ctl-label { font-size: 11px; color: var(--dsw-alias-label-secondary, #52606d); flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-select { height: 24px; padding: 0 4px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 11px; outline: none; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-select:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-rules-desc-input { flex: 1; min-width: 0; }\n[data-edrv-view] .edrv-rules-input { flex: 1; min-width: 0; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 11px; outline: none; font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-rules-input:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-rules-body { flex: 1; min-height: 0; resize: none; padding: 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; line-height: 1.5; outline: none; font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-rules-body:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-rules-editor-hint { font-size: 10px; color: var(--dsw-alias-label-tertiary, #9aa5b1); line-height: 1.5; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-editor-foot { display: flex; justify-content: flex-end; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-save { height: 24px; padding: 0 14px; border: none; border-radius: 6px; background: var(--dsw-alias-brand-primary, #0f9d58); color: #fff; font-size: 12px; cursor: pointer; }\n[data-edrv-view] .edrv-rules-save:disabled { opacity: .5; cursor: default; }\n\n\n\n";
|
|
35
|
+
const css$1 = "/* dsh-vscode-mode 编辑区样式(原 ensureEdrvStyles 字符串,落盘为真 .css,由 tsdown CSS-inline 注入) */\n/* 主题:跟随官方 --dsw-alias-* 令牌(DSH 明暗与第三方皮肤生效)。\n 本作用域不再重定义官方令牌(旧实现曾在此硬覆盖浅色盘,导致插件不跟随 DSH 主题);\n 旧环境/缺令牌场景由每条声明的 var(--dsw-alias-*, 回落值) 兜底。\n @author ddj 2026-09-10 */\n[data-edrv-view] { box-sizing: border-box; --edrv-tab-h: 34px; }\n\n[data-edrv-view] .edrv-tabs { display: flex; align-items: center; gap: 2px; padding: 2px 8px 0; background: var(--dsw-alias-bg-layer-1, transparent); overflow-x: auto; scrollbar-width: thin; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab { display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 8px 0 12px; border: none; border-radius: 6px 6px 0 0; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); font-size: 12px; cursor: pointer; white-space: nowrap; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-tab.edrv-tab-active { background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); box-shadow: inset 0 -2px 0 var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-tab .edrv-tab-star { color: var(--dsw-alias-brand-primary, #4f8cff); font-size: 13px; font-weight: 700; line-height: 1; flex-shrink: 0; } /* 未保存修改星号 @author ddj 2026年09月09号 */\n[data-edrv-view] .edrv-tab .edrv-tab-x { display: inline-flex; align-items: center; justify-content: center; width: 16px; height: 16px; border-radius: 4px; color: var(--dsw-alias-label-tertiary, #888); font-size: 11px; }\n[data-edrv-view] .edrv-tab .edrv-tab-x:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.12)); color: var(--dsw-alias-label-primary, #eee); }\n[data-edrv-view] .edrv-tab-add { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; margin-left: 2px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); font-size: 14px; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-tab-add:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-pathbar { display: flex; align-items: center; gap: 8px; height: 26px; padding: 0 10px; background: var(--dsw-alias-bg-layer-1, #ffffff); border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); font-size: 12px; flex-shrink: 0; overflow: hidden; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-name { font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); white-space: nowrap; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-full { flex: 1; min-width: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; direction: rtl; text-align: left; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-meta { flex-shrink: 0; font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-variant-numeric: tabular-nums; }\n[data-edrv-view] .edrv-pathbar .edrv-pb-status { color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-path-input { flex: 1; min-width: 140px; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search-wrap { position: relative; flex-shrink: 0; display: flex; align-items: center; padding: 2px 8px 2px 4px; }\n[data-edrv-view] .edrv-search { width: 190px; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-search-pop { position: absolute; top: calc(100% + 4px); right: 8px; width: min(460px, calc(100vw - 24px)); max-height: 300px; overflow: auto; background: var(--dsw-alias-bg-overlay, #1c1c1c); border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 10px; box-shadow: 0 6px 20px rgba(0,0,0,.4); z-index: 60; padding: 4px; }\n[data-edrv-view] .edrv-search-item { display: flex; flex-direction: column; gap: 1px; padding: 5px 8px; border-radius: 6px; cursor: pointer; }\n[data-edrv-view] .edrv-search-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.07)); }\n[data-edrv-view] .edrv-search-item .n { color: var(--dsw-alias-label-primary, #eee); font-size: 12px; word-break: break-all; }\n[data-edrv-view] .edrv-search-item .d { color: var(--dsw-alias-label-tertiary, #888); font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-search-empty { padding: 8px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #888); }\n[data-edrv-view] .edrv-btn-mini { font-size: 11px; padding: 2px 9px; border: none; border-radius: 999px; cursor: pointer; color: var(--dsw-alias-label-primary-inverted, #fff); font-weight: 600; white-space: nowrap; }\n[data-edrv-view] .edrv-btn-keep { background: var(--dsw-alias-state-success-primary, #2e9e44); }\n[data-edrv-view] .edrv-btn-undo { background: var(--dsw-alias-state-warn-primary, #d97706); }\n[data-edrv-view] .edrv-btn-mini:disabled { opacity: .45; cursor: default; }\n[data-edrv-view] .edrv-statusbar { display: flex; align-items: center; gap: 10px; padding: 3px 10px; border-top: 1px solid var(--dsw-alias-border-l1, #333); background: var(--dsw-alias-bg-layer-1, transparent); font-size: 11px; color: var(--dsw-alias-label-tertiary, #888); flex-shrink: 0; white-space: nowrap; overflow: hidden; }\n[data-edrv-view] .edrv-statusbar .edrv-sp-path { flex: 1; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-statusbar .edrv-sp-lsp { flex: 0 1 auto; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-statusbar .edrv-sp-progress-message { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-statusbar .edrv-sp-progress { flex: 0 0 auto; min-width: 36px; text-align: right; font-variant-numeric: tabular-nums; color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-lsp-status-dot { width: 7px; height: 7px; border-radius: 50%; flex: 0 0 auto; background: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-lsp-status-dot.ready { background: var(--dsw-alias-state-success-primary, #0f9d58); }\n[data-edrv-view] .edrv-lsp-status-dot.busy { background: var(--dsw-alias-state-warn-primary, #d97706); animation: edrv-lsp-pulse 1.2s ease-in-out infinite; }\n@keyframes edrv-lsp-pulse { 50% { opacity: .45; } }\n/* Ctrl+hover 可导航标识符下划线提示(绑定 Monaco inlineClassName 装饰) */\n[data-edrv-view] .edrv-nav-underline { text-decoration: underline; text-decoration-color: var(--dsw-alias-interactive-primary, #4fc1ff); text-underline-offset: 1px; cursor: pointer; }\n[data-edrv-view] .edrv-diffchip { font-size: 11px; padding: 2px 10px; border: 1px solid var(--dsw-alias-border-l1, #333); border-radius: 999px; background: var(--dsw-alias-bg-layer-2, transparent); color: var(--dsw-alias-state-warn-primary, #b7791f); cursor: pointer; white-space: nowrap; flex-shrink: 0; }\n[data-edrv-view] .edrv-chip-btn { font-size: 12px; padding: 2px 6px; border: none; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); cursor: pointer; border-radius: 4px; flex-shrink: 0; }\n[data-edrv-view] .edrv-chip-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-chip-btn:disabled { opacity: .35; cursor: default; }\n[data-edrv-view] .edrv-chip-btn:disabled:hover { background: transparent; }\n[data-edrv-view] .edrv-mn-add-line { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.10)); }\n[data-edrv-view] .edrv-mn-gutter-add { color: var(--dsw-alias-state-success-primary, #0f9d58) !important; font-weight: 700; display: flex !important; align-items: center; justify-content: center; }\n[data-edrv-view] .edrv-mn-gutter-add::before { content: \"+\"; }\n[data-edrv-view] .edrv-del-zone { background: var(--dsw-alias-interactive-bg-hover-danger, rgba(217,83,79,.14)); border-top: 1px solid var(--dsw-alias-state-error-primary, rgba(217,83,79,.35)); border-bottom: 1px solid var(--dsw-alias-state-error-primary, rgba(217,83,79,.35)); box-shadow: inset 0 0 0 1px var(--dsw-alias-interactive-bg-hover-danger, rgba(217,83,79,.12)); }\n[data-edrv-view] .edrv-del-row { white-space: pre; font-family: var(--ds-font-family-code, ui-monospace, monospace); font-size: 12.5px; line-height: 20px; color: var(--dsw-alias-state-error-primary, #c0392b); }\n[data-edrv-view] .edrv-del-text { display: inline-block; white-space: pre; }\n[data-edrv-view] .edrv-minus-overlay { position: absolute; left: 0; top: 0; width: 100%; height: 100%; max-width: 100%; overflow: visible; pointer-events: none; z-index: 6; }\n[data-edrv-view] .edrv-minus-item { position: absolute; box-sizing: border-box; max-width: 100%; overflow: hidden; }\n[data-edrv-view] .edrv-minus-item::before { content: ''; position: absolute; left: 4px; top: 50%; width: 8px; height: 2px; transform: translateY(-50%); border-radius: 2px; background: var(--dsw-alias-state-error-primary, #d9534f); }\n[data-edrv-view] .edrv-monaco-host { flex: 1 1 auto; min-width: 0; min-height: 0; position: relative; overflow: hidden; }\n[data-edrv-view] .edrv-monaco-host > div { position: absolute; inset: 0; min-width: 0; min-height: 0; }\n[data-edrv-view] .edrv-imgview { flex: 1 1 auto; min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }\n[data-edrv-view] .edrv-imgview-bar { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px; flex-shrink: 0; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); background: var(--dsw-alias-bg-layer-1, transparent); }\n[data-edrv-view] .edrv-imgview-meta { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; }\n[data-edrv-view] .edrv-imgview-stage { flex: 1 1 auto; min-height: 0; display: flex; align-items: center; justify-content: center; overflow: auto; padding: 14px; background-color: var(--dsw-alias-bg-layer-1, #f0f4f4); background-image: conic-gradient(rgba(128,128,128,.14) 25%, transparent 0 50%, rgba(128,128,128,.14) 0 75%, transparent 0); background-size: 16px 16px; }\n[data-edrv-view] .edrv-imgview-img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 4px; box-shadow: 0 2px 12px rgba(31,41,51,.18); }\n[data-edrv-view] .edrv-imgview-broken { display: flex; flex-direction: column; align-items: center; gap: 10px; font-size: 13px; color: var(--dsw-alias-label-tertiary, #777); }\n[data-edrv-view] .edrv-pdf-host { flex: 1 1 auto; min-width: 0; min-height: 0; position: relative; overflow: hidden; }\n[data-edrv-view] .edrv-pdf-host > .edrv-pdf { position: absolute; inset: 0; }\n[data-edrv-view] .edrv-pdf { min-width: 0; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }\n[data-edrv-view] .edrv-pdf-bar { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px; flex-shrink: 0; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); background: var(--dsw-alias-bg-layer-1, transparent); }\n[data-edrv-view] .edrv-pdf-page { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; min-width: 52px; text-align: center; }\n[data-edrv-view] .edrv-pdf-zoom { min-width: 26px; text-align: center; padding: 3px 7px; }\n[data-edrv-view] .edrv-pdf-sep { width: 1px; height: 16px; background: var(--dsw-alias-border-l1, #e0e6e8); margin: 0 2px; }\n[data-edrv-view] .edrv-pdf-mode-on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); color: var(--dsw-alias-brand-primary, #0f9d58); border-color: var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-pdf-dirty { color: var(--dsw-alias-state-warn-primary, #d97706); border-color: var(--dsw-alias-state-warn-primary, #d97706); }\n[data-edrv-view] .edrv-pdf-stage { position: absolute; top: 34px; left: 0; right: 0; bottom: 0; overflow: auto; }\n[data-edrv-view] .edrv-pdf-stage .edrv-pdf-viewer { margin: 0 auto; }\n[data-edrv-view] .edrv-empty { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px; height: 100%; color: var(--dsw-alias-label-tertiary, #777); font-size: 13px; }\n[data-edrv-view] .edrv-diffbar { position: absolute; left: 0; right: 0; bottom: 10px; margin: 0 auto; z-index: 25; width: fit-content; max-width: calc(100% - 20px); border-radius: 12px; background: var(--dsw-specific-tip, var(--dsw-alias-bg-layer-2, #f0f4f4)); border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); box-shadow: none; overflow: visible; display: flex; flex-direction: column; }\n[data-edrv-view] .edrv-editor-area > .edrv-diffbar { max-height: calc(100% - 20px); }\n[data-edrv-view] .edrv-diffbar-row { display: flex; align-items: center; gap: 6px; height: 36px; padding: 4px 5px 4px 12px; flex-wrap: nowrap; }\n[data-edrv-view] .edrv-diffbar-count { font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); min-width: 42px; text-align: center; white-space: nowrap; cursor: pointer; }\n[data-edrv-view] .edrv-diffbar-count.edrv-count-file { min-width: 64px; cursor: default; }\n[data-edrv-view] .edrv-diffbar-file { flex: 1; min-width: 0; font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-pill { font-size: 11px; padding: 3px 10px; border: none; border-radius: 999px; cursor: pointer; white-space: nowrap; font-weight: 600; }\n[data-edrv-view] .edrv-pill-keep { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); color: var(--dsw-alias-state-success-primary, #0f7a45); border: 1px solid var(--dsw-alias-state-success-primary, rgba(15,157,88,.4)); }\n[data-edrv-view] .edrv-pill-undo { background: var(--dsw-alias-interactive-bg-hover-danger, rgba(217,83,79,.14)); color: var(--dsw-alias-state-error-primary, #c0392b); border: 1px solid var(--dsw-alias-state-error-primary, rgba(217,83,79,.4)); }\n[data-edrv-view] .edrv-pill-ghost { background: var(--dsw-alias-bg-layer-1, #ffffff); color: var(--dsw-alias-label-secondary, #52606d); border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-pill:disabled { opacity: .45; cursor: default; }\n[data-edrv-view] .edrv-diffbar-menu { position: absolute; right: 8px; bottom: calc(100% + 6px); z-index: 45; min-width: 160px; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 6px 20px rgba(31,41,51,.16); padding: 4px; display: flex; flex-direction: column; gap: 2px; }\n[data-edrv-view] .edrv-diffmenu-item { display: flex; align-items: center; gap: 8px; font-size: 12px; padding: 6px 10px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; text-align: left; }\n[data-edrv-view] .edrv-diffmenu-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-diffmenu-item.danger { color: var(--dsw-alias-state-error-primary, #d9534f); }\n[data-edrv-view] .edrv-diffmenu-sep { height: 1px; margin: 2px 4px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n/* 编辑区 / Tab 右键菜单(添加文件/选中内容到对话) */\n[data-edrv-view] .edrv-ctxmenu { position: fixed; z-index: 71; min-width: 200px; max-width: 320px; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 8px 26px rgba(31,41,51,.2); padding: 4px; display: flex; flex-direction: column; gap: 1px; }\n[data-edrv-view] .edrv-ctxmenu-item { display: flex; align-items: center; gap: 8px; font-size: 12px; line-height: 18px; padding: 7px 10px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; text-align: left; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-ctxmenu-item:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-ctxmenu-item.edrv-ctxmenu-danger { color: var(--dsw-alias-state-error-primary, #d9534f); }\n[data-edrv-view] .edrv-ctxmenu-item:disabled,\n[data-edrv-view] .edrv-ctxmenu-item.edrv-ctxmenu-disabled { color: var(--dsw-alias-label-disabled, #b0b7c0); cursor: default; background: transparent; }\n[data-edrv-view] .edrv-ctxmenu-sep { height: 1px; margin: 3px 4px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-diffbar-body { max-height: 130px; max-width: min(560px, calc(100vw - 40px)); overflow: auto; padding: 4px 8px 8px; display: flex; flex-direction: column; gap: 4px; border-top: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-diffrow { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 6px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); cursor: pointer; flex-wrap: wrap; }\n[data-edrv-view] .edrv-diffrow:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-diffrow-l { font-size: 11px; color: var(--dsw-alias-label-primary, #1f2933); min-width: 74px; font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-o { font-size: 11px; color: var(--dsw-alias-state-error-primary, #d9534f); font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-n { font-size: 11px; color: var(--dsw-alias-state-success-primary, #0f9d58); font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-diffrow-tag { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-diffrow-stale { border-color: var(--dsw-alias-state-warn-primary, rgba(217,119,6,.5)); cursor: default; }\n[data-edrv-view] .edrv-diffbox-others { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; padding: 4px 2px 0; border-top: 1px solid var(--dsw-alias-border-l1, #e0e6e8); margin-top: 2px; }\n[data-edrv-view] .edrv-diffrow-file { font-size: 11px; padding: 2px 10px; border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 999px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); color: var(--dsw-alias-label-secondary, #52606d); cursor: pointer; white-space: nowrap; max-width: 200px; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-diffrow-file:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); color: var(--dsw-alias-label-primary, #1f2933); }\n/* 编辑区 hover 差异块的 Keep/Undo 浮层 */\n[data-edrv-view] .edrv-hoveract { position: absolute; z-index: 30; display: flex; align-items: center; gap: 4px; padding: 2px 6px; border-radius: 8px; background: var(--dsw-alias-bg-overlay, #ffffff); border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); box-shadow: 0 4px 14px rgba(31,41,51,.14); }\n[data-edrv-view] .edrv-launch { position: absolute; left: 12px; right: 12px; bottom: 12px; z-index: 40; border-radius: 10px; background: var(--dsw-alias-bg-overlay, #1c1c1c); border: 1px solid var(--dsw-alias-border-l2, #555); box-shadow: 0 6px 24px rgba(0,0,0,.5); display: flex; flex-direction: column; max-height: 60%; overflow: hidden; }\n[data-edrv-view] .edrv-launch-head { display: flex; align-items: center; gap: 6px; padding: 6px 8px; border-bottom: 1px solid var(--dsw-alias-border-l1, #333); }\n[data-edrv-view] .edrv-launch-tab { font-size: 12px; padding: 3px 12px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #aaa); cursor: pointer; }\n[data-edrv-view] .edrv-launch-tab.on { background: var(--dsw-alias-bg-layer-2, transparent); color: var(--dsw-alias-label-primary, #eee); font-weight: 600; }\n[data-edrv-view] .edrv-launch-body { flex: 1; min-height: 0; overflow: auto; padding: 6px 8px; display: flex; flex-direction: column; gap: 4px; }\n[data-edrv-view] .edrv-launch-row { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1, #333); border-radius: 6px; cursor: pointer; flex-wrap: wrap; }\n[data-edrv-view] .edrv-launch-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(255,255,255,.06)); }\n[data-edrv-view] .edrv-launch-path { flex: 1; min-width: 0; font-size: 12px; color: var(--dsw-alias-label-primary, #eee); word-break: break-all; }\n[data-edrv-view] .edrv-launch-cnt { font-size: 11px; color: var(--dsw-alias-label-tertiary, #888); white-space: nowrap; }\n[data-edrv-view] .edrv-launch-arch { display: flex; flex-direction: column; gap: 6px; }\n[data-edrv-view] .monaco-editor { overflow: hidden !important; }\n[data-edrv-view] .monaco-editor .sticky-widget { z-index: 30 !important; background: var(--dsw-alias-bg-base, #f8f8f8) !important; }\n[data-edrv-view] .monaco-editor .sticky-widget .sticky-line-content,\n[data-edrv-view] .monaco-editor .sticky-widget .sticky-line-number { background: var(--dsw-alias-bg-base, #f8f8f8) !important; }\n[data-edrv-view] .monaco-editor, [data-edrv-view] .monaco-editor .margin, [data-edrv-view] .monaco-editor-background { background: transparent !important; }\n[data-edrv-view] .monaco-editor .scrollbar .slider { background: rgba(128,128,128,.3) !important; }\n[data-edrv-view] .edrv-loading { gap: 8px; padding: 20px; }\n[data-edrv-view] .edrv-loading-title { color: var(--dsw-alias-label-primary, #1f2933); font-size: 13px; }\n[data-edrv-view] .edrv-progress { width: min(360px, 72%); height: 6px; overflow: hidden; border-radius: 999px; background: var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-progress-value { height: 100%; border-radius: inherit; background: var(--dsw-alias-brand-primary, #0f9d58); transition: width .24s ease; }\n[data-edrv-view] .edrv-loading-percent { color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; font-variant-numeric: tabular-nums; }\n@media (prefers-reduced-motion: reduce) {\n [data-edrv-view] .edrv-progress-value { transition: none; }\n}\n\n/* ===== 唯一会话级差异 dock(遵循 DSH todo/queue 原生布局) ===== */\n[data-edrv-diff-dock-shell] {\n box-sizing: border-box;\n width: calc(100% - var(--dsh-composer-side-clearance) - var(--dsh-composer-side-clearance) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));\n max-width: calc(var(--dsh-composer-card-max-width) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset) - var(--dsh-composer-dock-inset));\n margin: 0 auto;\n padding: 0;\n flex: none;\n border: 1px solid var(--dsw-alias-border-l1, #e0e6e8);\n border-radius: 12px;\n background: var(--dsw-specific-tip, var(--dsw-alias-bg-layer-2, transparent));\n box-shadow: none;\n overflow: hidden;\n}\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock {\n box-sizing: border-box;\n position: relative;\n left: auto;\n right: auto;\n bottom: auto;\n z-index: auto;\n width: 100%;\n max-width: none;\n margin: 0;\n display: flex;\n flex-direction: column;\n border: none;\n border-radius: 0;\n background: transparent;\n box-shadow: none;\n overflow: visible;\n}\n[data-edrv-diff-dock-shell] .edrv-diffbar-row { min-height: 36px; padding: 6px 12px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock-row { min-height: 36px; padding: 6px 12px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-body { max-height: 180px; overflow: auto; padding: 6px 12px 10px; border-top: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock-button { box-sizing: border-box; display: flex; align-items: center; justify-content: center; width: 100%; height: 24px; border: none; border-radius: 8px; padding: 0 12px; background: transparent; color: var(--dsw-alias-label-primary); font-size: 13px; font-weight: 500; line-height: 24px; text-align: center; cursor: pointer; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-dock-button:hover { background: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-diffbar-count { display: inline-flex; align-items: center; color: var(--dsw-alias-label-primary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 500; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-file { display: inline-flex; align-items: center; color: var(--dsw-alias-label-tertiary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 400; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-editor-row { display: flex; align-items: center; height: 36px; min-height: 36px; padding: 4px 12px; overflow-x: auto; scrollbar-width: thin; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-editor-content { display: flex; align-items: center; gap: 10px; width: 100%; min-width: max-content; min-height: 28px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-nav,\n[data-edrv-diff-dock-shell] .edrv-diffbar-files,\n[data-edrv-diff-dock-shell] .edrv-diffbar-actions { display: flex; align-items: center; gap: 6px; flex: none; height: 28px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-actions { margin-left: auto; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-details-toggle { display: inline-flex; align-items: center; justify-content: center; width: 28px; min-width: 28px; padding: 0; font-size: 13px; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-details-toggle svg { width: 14px; height: 14px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-files { min-width: 0; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-files .edrv-diffbar-file { min-width: 72px; max-width: 240px; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-progress { min-width: 0; color: var(--dsw-alias-label-tertiary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 400; line-height: 24px; font-variant-numeric: tabular-nums; }\n[data-edrv-diff-dock-shell] .edrv-diffbar-summary { min-width: 0; color: var(--dsw-alias-label-tertiary); font-family: Inter, var(--dsw-font-family); font-size: 13px; font-weight: 400; line-height: 24px; }\n[data-edrv-diff-dock-shell] .edrv-pill { box-sizing: border-box; height: 28px; padding: 0 9px; border: none; border-radius: 999px; cursor: pointer; white-space: nowrap; font-size: 11px; line-height: 26px; font-weight: 600; }\n[data-edrv-diff-dock-shell] .edrv-pill-keep { background: var(--dsw-alias-state-success-tertiary); color: var(--dsw-alias-state-success-primary); border: 1px solid var(--dsw-alias-state-success-secondary); }\n[data-edrv-diff-dock-shell] .edrv-pill-undo { background: var(--dsw-alias-state-error-tertiary); color: var(--dsw-alias-state-error-primary); border: 1px solid var(--dsw-alias-state-error-secondary); }\n[data-edrv-diff-dock-shell] .edrv-pill-ghost { background: transparent; color: var(--dsw-alias-label-secondary); border: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-pill:hover:not(:disabled) { background-color: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-pill:focus-visible { outline: 2px solid var(--dsw-alias-label-tertiary); outline-offset: -2px; }\n[data-edrv-diff-dock-shell] .edrv-pill:disabled { opacity: .45; cursor: default; }\n[data-edrv-diff-dock-shell] .edrv-diffrow { display: flex; align-items: center; gap: 8px; padding: 3px 6px; border: 1px solid var(--dsw-alias-border-l1); border-radius: 6px; background: transparent; cursor: pointer; flex-wrap: wrap; }\n[data-edrv-diff-dock-shell] .edrv-diffrow:hover { background: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-l { color: var(--dsw-alias-label-primary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-o { color: var(--dsw-alias-state-error-primary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-n { color: var(--dsw-alias-state-success-primary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-tag { color: var(--dsw-alias-label-tertiary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-stale { border-color: var(--dsw-alias-state-warn-secondary); cursor: default; }\n[data-edrv-diff-dock-shell] .edrv-diffbox-others { border-top: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-file { border-color: var(--dsw-alias-border-l1); background: transparent; color: var(--dsw-alias-label-secondary); }\n[data-edrv-diff-dock-shell] .edrv-diffrow-file:hover { background: var(--dsw-alias-interactive-bg-hover); color: var(--dsw-alias-label-primary); }\n[data-edrv-diff-dock-shell] .edrv-diff-details { display: flex; flex-direction: column; gap: 2px; padding: 6px 12px 8px; border-top: 1px solid var(--dsw-alias-border-l1); }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item { display: flex; align-items: center; width: 100%; min-height: 28px; gap: 8px; padding: 4px 8px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-primary); cursor: pointer; text-align: left; font-size: 12px; line-height: 20px; }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover); }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item.danger { color: var(--dsw-alias-state-error-primary); }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-item:disabled { opacity: .45; cursor: default; }\n[data-edrv-diff-dock-shell] .edrv-diff-details .edrv-diffmenu-sep { height: 1px; margin: 2px 4px; background: var(--dsw-alias-border-l1); }\n@media (max-width: 620px) {\n [data-edrv-diff-dock-shell] .edrv-diffbar-editor-content { width: max-content; }\n [data-edrv-diff-dock-shell] .edrv-diffbar-files .edrv-diffbar-file { max-width: 160px; }\n}\n\n/* ===== 侧边栏(活动栏 + 面板区 + 文件树) ===== */\n[data-edrv-view] .edrv-editor-row { display: flex; flex: 1 1 auto; min-width: 0; min-height: 0; overflow: hidden; }\n[data-edrv-view] .edrv-main-col { box-sizing: border-box; min-width: 0; min-height: 0; overflow: hidden; }\n[data-edrv-view] .edrv-main-col > .edrv-pathbar,\n[data-edrv-view] .edrv-main-col > .edrv-tabs { flex: 0 0 auto; }\n[data-edrv-view] .edrv-editor-area { position: relative; display: flex; flex: 1 1 auto; flex-direction: column; min-width: 0; min-height: 0; overflow: hidden; }\n[data-edrv-view] .edrv-sidebar { display: flex; flex-direction: row; flex-shrink: 1; min-width: 0; height: 100%; background: var(--dsw-alias-bg-layer-1, #ffffff); border-right: 1px solid var(--dsw-alias-border-l1, #e0e6e8); overflow: hidden; }\n[data-edrv-view] .edrv-rail { display: flex; flex-direction: column; align-items: center; width: 44px; flex-shrink: 0; padding: 6px 0; background: var(--dsw-alias-bg-layer-2, #f0f4f4); border-right: 1px solid var(--dsw-alias-border-l1, #e0e6e8); gap: 4px; }\n[data-edrv-view] .edrv-rail-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; border: none; border-radius: 8px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-rail-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rail-btn.edrv-rail-on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); color: var(--dsw-alias-label-primary, #1f2933); box-shadow: inset 2px 0 0 var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-rail-icon { font-size: 15px; line-height: 1; display: inline-flex; align-items: center; justify-content: center; }\n/* 树行图标:官方原语(文件夹/文件类型),尺寸与行高对齐 @author ddj 2026-09-10 */\n[data-edrv-view] .edrv-tree-icon { flex-shrink: 0; display: inline-flex; align-items: center; color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-tree-row.edrv-tree-active .edrv-tree-icon { color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-rail-badge { position: absolute; top: 2px; right: 2px; min-width: 14px; height: 14px; padding: 0 3px; border-radius: 999px; background: var(--dsw-alias-brand-primary, #0f9d58); color: var(--dsw-alias-label-primary-inverted, #fff); font-size: 9px; font-weight: 600; line-height: 14px; text-align: center; box-sizing: border-box; }\n[data-edrv-view] .edrv-side-body { flex: 1; min-width: 0; min-height: 0; display: flex; overflow: hidden; }\n[data-edrv-view] .edrv-side-panel { flex: 1; min-width: 0; min-height: 0; display: flex; flex-direction: column; position: relative; }\n[data-edrv-view] .edrv-side-head { display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 10px 0 12px; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); flex-shrink: 0; }\n[data-edrv-view] .edrv-side-title { font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); white-space: nowrap; }\n[data-edrv-view] .edrv-side-root { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-side-btn { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 12px; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-side-btn:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-tree { flex: 1; min-height: 0; overflow: auto; padding: 4px 6px 12px; font-size: 12px; }\n[data-edrv-view] .edrv-tree-row { display: flex; align-items: center; gap: 4px; height: 22px; padding-right: 6px; border-radius: 5px; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; white-space: nowrap; }\n[data-edrv-view] .edrv-tree-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-tree-row.edrv-tree-active { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); }\n[data-edrv-view] .edrv-tree-row.edrv-tree-context { box-shadow: inset 0 0 0 1px var(--dsw-alias-brand-primary, #0f9d58); background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); }\n[data-edrv-view] .edrv-tree-chev { width: 12px; flex-shrink: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 10px; text-align: center; }\n[data-edrv-view] .edrv-tree-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-tree-name.edrv-tree-dim { color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-tree-badge { min-width: 14px; height: 14px; padding: 0 4px; border-radius: 999px; background: var(--dsw-alias-state-warn-primary, #d97706); color: var(--dsw-alias-label-primary-inverted, #fff); font-size: 9px; font-weight: 600; line-height: 14px; text-align: center; box-sizing: border-box; flex-shrink: 0; }\n[data-edrv-view] .edrv-tree-loading { height: 22px; line-height: 22px; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; }\n[data-edrv-view] .edrv-tree-error { display: flex; align-items: center; gap: 8px; margin: 4px 2px 6px; padding: 6px 8px; border: 1px solid var(--dsw-alias-state-error-primary, rgba(217,83,79,.4)); border-radius: 6px; background: var(--dsw-alias-interactive-bg-hover-danger, rgba(217,83,79,.12)); color: var(--dsw-alias-state-error-primary, #d9534f); font-size: 11px; }\n/* 大纲面板:kind 字形 / detail / 行号 */\n[data-edrv-view] .edrv-outline-kind { display: inline-flex; align-items: center; justify-content: center; width: 14px; flex-shrink: 0; font-size: 12px; font-weight: 600; text-align: center; }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-func { color: var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-type { color: var(--dsw-alias-label-primary, #1f2933); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-data { color: var(--dsw-alias-state-warn-primary, #d97706); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-ns { color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-outline-kind.edrv-ol-key { color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-outline-detail { flex-shrink: 0; max-width: 40%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; }\n[data-edrv-view] .edrv-outline-ln { flex-shrink: 0; padding-right: 2px; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 10px; font-variant-numeric: tabular-nums; }\n[data-edrv-view] .edrv-side-resize { width: 5px; flex-shrink: 0; cursor: col-resize; background: transparent; }\n[data-edrv-view] .edrv-side-resize:hover { background: var(--dsw-alias-brand-primary, #0f9d58); opacity: .35; }\n[data-edrv-view] .edrv-chip-btn.edrv-chip-on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.12)); color: var(--dsw-alias-label-primary, #1f2933); }\n\n/* ===== 侧栏形态(betterSidebar 面板内编辑区) ===== */\n[data-edrv-view][data-edrv-layout='side'] { box-sizing: border-box; height: 100%; }\n\n/* ===== 侧边栏引导条(旧页签形态、未装 betterSidebar 时) ===== */\n[data-edrv-view] .edrv-side-hint { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; flex-wrap: wrap; padding: 6px 12px; font-size: 12px; color: var(--dsw-alias-label-secondary, #52606d); background: var(--dsw-specific-tip, var(--dsw-alias-bg-layer-2, #f0f4f4)); border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); }\n[data-edrv-view] .edrv-side-hint-text { white-space: nowrap; }\n[data-edrv-view] .edrv-side-hint-cmd { font-size: 11px; padding: 2px 6px; border-radius: 6px; background: var(--dsw-alias-bg-layer-1, #ffffff); border: 1px solid var(--dsw-alias-border-l1, #e0e6e8); color: var(--dsw-alias-label-primary, #1f2933); white-space: nowrap; }\n[data-edrv-view] .edrv-side-hint-close { margin-left: auto; border: none; background: transparent; color: var(--dsw-alias-label-tertiary, #9aa5b1); cursor: pointer; font-size: 14px; line-height: 1; padding: 2px 6px; border-radius: 6px; flex-shrink: 0; }\n[data-edrv-view] .edrv-side-hint-close:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); color: var(--dsw-alias-label-primary, #1f2933); }\n\n/* ===== search panel (sidebar, VSCode search view) ===== */\n[data-edrv-view] .edrv-search-panel { display: flex; flex-direction: column; min-height: 0; flex: 1; padding: 6px; gap: 4px; }\n[data-edrv-view] .edrv-search-qrow { display: flex; gap: 4px; }\n[data-edrv-view] .edrv-search-input { flex: 1; min-width: 0; height: 26px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; outline: none; }\n[data-edrv-view] .edrv-search-input:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-search-opts { display: flex; align-items: center; gap: 2px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-search-opt { min-width: 24px; height: 22px; padding: 0 6px; border: 1px solid transparent; border-radius: 5px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 11px; font-family: var(--ds-font-family-code, ui-monospace, monospace); cursor: pointer; }\n[data-edrv-view] .edrv-search-opt:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-opt.on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); color: var(--dsw-alias-label-primary, #1f2933); border-color: var(--dsw-alias-border-l2, #d5dde3); }\n[data-edrv-view] .edrv-search-spacer { flex: 1; }\n[data-edrv-view] .edrv-search-summary { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); padding: 2px 4px; }\n[data-edrv-view] .edrv-search-results { flex: 1; min-height: 0; overflow: auto; font-size: 12px; }\n[data-edrv-view] .edrv-search-group { margin-bottom: 2px; }\n[data-edrv-view] .edrv-search-file { display: flex; align-items: center; gap: 4px; height: 22px; padding: 0 4px; border-radius: 5px; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; white-space: nowrap; }\n[data-edrv-view] .edrv-search-file:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-chev { width: 12px; flex-shrink: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 10px; text-align: center; }\n[data-edrv-view] .edrv-search-fname { font-weight: 600; overflow: hidden; text-overflow: ellipsis; }\n[data-edrv-view] .edrv-search-fdir { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; }\n[data-edrv-view] .edrv-search-fcount { flex-shrink: 0; min-width: 16px; height: 15px; padding: 0 4px; border-radius: 999px; background: var(--dsw-alias-bg-layer-2, #f0f4f4); color: var(--dsw-alias-label-secondary, #52606d); font-size: 10px; line-height: 15px; text-align: center; }\n[data-edrv-view] .edrv-search-line { display: flex; gap: 6px; padding: 1px 4px 1px 16px; border-radius: 4px; color: var(--dsw-alias-label-primary, #1f2933); cursor: pointer; overflow: hidden; }\n[data-edrv-view] .edrv-search-line.alt { background: var(--dsw-alias-bg-layer-1, #ffffff); }\n[data-edrv-view] .edrv-search-line:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-ln { flex-shrink: 0; color: var(--dsw-alias-label-tertiary, #9aa5b1); font-size: 11px; min-width: 26px; text-align: right; user-select: none; }\n[data-edrv-view] .edrv-search-text { overflow: hidden; text-overflow: ellipsis; white-space: pre; font-family: var(--ds-font-family-code, ui-monospace, monospace); font-size: 11px; }\n[data-edrv-view] .edrv-search-hit { background: var(--dsw-alias-state-warn-primary, #e5b93f); color: var(--dsw-alias-label-primary-inverted, #1f2933); border-radius: 2px; padding: 0 1px; }\n[data-edrv-view] .edrv-search-empty { padding: 8px 4px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-search-error { padding: 6px 8px; border: 1px solid var(--dsw-alias-state-error-primary, rgba(217,83,79,.4)); border-radius: 6px; background: var(--dsw-alias-interactive-bg-hover-danger, rgba(217,83,79,.12)); color: var(--dsw-alias-state-error-primary, #d9534f); font-size: 11px; }\n[data-edrv-view] .edrv-search-warn { padding: 6px 8px; border: 1px solid var(--dsw-alias-state-warn-primary, rgba(240,173,78,.45)); border-radius: 6px; background: var(--dsw-alias-interactive-bg-hover, rgba(240,173,78,.12)); color: var(--dsw-alias-state-warn-primary, #b8860b); font-size: 11px; word-break: break-all; }\n\n/* include/exclude filter rows (collapsible) */\n[data-edrv-view] .edrv-search-rows { display: flex; flex-direction: column; gap: 4px; padding: 2px 0 4px; }\n[data-edrv-view] .edrv-search-row { display: flex; align-items: center; gap: 4px; }\n[data-edrv-view] .edrv-search-field { flex: 1; min-width: 0; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 11px; outline: none; }\n[data-edrv-view] .edrv-search-field:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-search-field.dim { opacity: .45; }\n[data-edrv-view] .edrv-search-field::placeholder { color: var(--dsw-alias-label-tertiary, #9aa5b1); }\n[data-edrv-view] .edrv-search-toggle { min-width: 24px; height: 24px; padding: 0 5px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 12px; line-height: 1; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-search-toggle:hover:not(:disabled) { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-search-toggle.on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); color: var(--dsw-alias-label-primary, #1f2933); border-color: var(--dsw-alias-brand-primary, #0f9d58); }\n[data-edrv-view] .edrv-search-toggle:disabled { opacity: .4; cursor: default; }\n\n/* ===== rules panel (sidebar, Codebuddy rules view) ===== */\n[data-edrv-view] .edrv-rules-panel { display: flex; flex-direction: column; min-width: 0; min-height: 0; flex: 1; padding: 6px; gap: 4px; }\n[data-edrv-view] .edrv-rules-tabs { display: flex; align-items: center; gap: 2px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-tab { height: 24px; padding: 0 10px; border: none; border-radius: 6px; background: transparent; color: var(--dsw-alias-label-secondary, #52606d); font-size: 12px; cursor: pointer; }\n[data-edrv-view] .edrv-rules-tab:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-tab.on { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.14)); color: var(--dsw-alias-label-primary, #1f2933); font-weight: 600; }\n[data-edrv-view] .edrv-rules-new { margin-left: auto; height: 24px; padding: 0 10px; border: 1px solid var(--dsw-alias-border-l2, #cbd2d9); border-radius: 6px; background: var(--dsw-alias-bg-layer-1, #fff); color: var(--dsw-alias-label-primary, #1f2933); font-size: 11px; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-new:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-ws-line { font-size: 11px; color: var(--dsw-alias-label-secondary, #52606d); padding: 0 2px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; flex: 0 0 auto; user-select: none; }\n[data-edrv-view] .edrv-rules-hint { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); padding: 0 2px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-list { flex: 1; min-height: 0; overflow: auto; }\n[data-edrv-view] .edrv-rules-row { display: flex; align-items: center; gap: 4px; padding: 6px 4px; border-bottom: 1px solid var(--dsw-alias-border-l1, #e0e6e8); border-radius: 6px; }\n[data-edrv-view] .edrv-rules-row:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-row.off .edrv-rules-main { opacity: .5; }\n[data-edrv-view] .edrv-rules-main { flex: 1; min-width: 0; cursor: pointer; overflow: hidden; }\n[data-edrv-view] .edrv-rules-line1 { display: flex; align-items: center; gap: 6px; min-width: 0; }\n[data-edrv-view] .edrv-rules-sub { display: flex; align-items: center; gap: 5px; margin-top: 3px; min-width: 0; }\n[data-edrv-view] .edrv-rules-sublabel { font-size: 11px; color: var(--dsw-alias-label-tertiary, #9aa5b1); flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-file { font-weight: 600; font-size: 12px; color: var(--dsw-alias-label-primary, #1f2933); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-rules-path { font-size: 10px; color: var(--dsw-alias-label-tertiary, #9aa5b1); flex: 0 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-rules-type { flex-shrink: 0; height: 15px; padding: 0 5px; border-radius: 999px; font-size: 10px; line-height: 15px; }\n[data-edrv-view] .edrv-rules-type-always { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.15)); color: var(--dsw-alias-state-success-primary, #0b7c46); }\n[data-edrv-view] .edrv-rules-type-auto { background: var(--dsw-alias-interactive-bg-hover-accent, rgba(79,140,255,.16)); color: var(--dsw-alias-link, #3367c9); }\n[data-edrv-view] .edrv-rules-type-manual { background: var(--dsw-alias-bg-layer-2, #f0f4f4); color: var(--dsw-alias-label-secondary, #52606d); }\n[data-edrv-view] .edrv-rules-offtag { font-size: 10px; color: var(--dsw-alias-label-tertiary, #9aa5b1); flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-desc { font-size: 11px; color: var(--dsw-alias-label-secondary, #52606d); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 0 1 auto; }\n[data-edrv-view] .edrv-rules-actions { display: flex; align-items: center; gap: 2px; flex-shrink: 0; margin-left: auto; }\n[data-edrv-view] .edrv-rules-act { min-width: 22px; height: 22px; padding: 0 4px; border: none; border-radius: 5px; background: transparent; font-size: 12px; line-height: 1; cursor: pointer; color: var(--dsw-alias-label-secondary, #52606d); display: inline-flex; align-items: center; justify-content: center; }\n[data-edrv-view] .edrv-rules-act:hover { background: var(--dsw-alias-interactive-bg-hover, rgba(15,157,88,.08)); }\n[data-edrv-view] .edrv-rules-switch { position: relative; width: 30px; height: 16px; border-radius: 999px; border: none; background: var(--dsw-alias-border-l2, #b9c4cc); cursor: pointer; transition: background .15s; flex-shrink: 0; padding: 0; }\n[data-edrv-view] .edrv-rules-switch.on { background: var(--dsw-alias-brand-primary, #7c5cff); }\n[data-edrv-view] .edrv-rules-knob { position: absolute; top: 2px; left: 2px; width: 12px; height: 12px; border-radius: 50%; background: var(--dsw-alias-bg-layer-1, #fff); transition: left .15s; }\n[data-edrv-view] .edrv-rules-switch.on .edrv-rules-knob { left: 16px; }\n[data-edrv-view] .edrv-rules-empty { padding: 10px 4px; font-size: 12px; color: var(--dsw-alias-label-tertiary, #9aa5b1); line-height: 1.6; }\n[data-edrv-view] .edrv-rules-err { padding: 6px 8px; border: 1px solid var(--dsw-alias-state-error-primary, rgba(217,83,79,.4)); border-radius: 6px; background: var(--dsw-alias-interactive-bg-hover-danger, rgba(217,83,79,.12)); color: var(--dsw-alias-state-error-primary, #d9534f); font-size: 11px; word-break: break-all; }\n[data-edrv-view] .edrv-rules-editor { display: flex; flex-direction: column; min-height: 0; flex: 1; gap: 6px; }\n[data-edrv-view] .edrv-rules-editor-head { display: flex; align-items: center; justify-content: space-between; gap: 6px; font-size: 12px; font-weight: 600; color: var(--dsw-alias-label-primary, #1f2933); flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-crumb { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }\n[data-edrv-view] .edrv-rules-editor-ctl { display: flex; align-items: center; gap: 6px; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-ctl-label { font-size: 11px; color: var(--dsw-alias-label-secondary, #52606d); flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-select { height: 24px; padding: 0 4px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 11px; outline: none; cursor: pointer; flex-shrink: 0; }\n[data-edrv-view] .edrv-rules-select:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-rules-desc-input { flex: 1; min-width: 0; }\n[data-edrv-view] .edrv-rules-input { flex: 1; min-width: 0; height: 24px; padding: 0 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 11px; outline: none; font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-rules-input:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-rules-body { flex: 1; min-height: 0; resize: none; padding: 8px; border: 1px solid var(--dsw-alias-border-l2, #555); border-radius: 6px; background: var(--dsw-alias-bg-base, #111); color: var(--dsw-alias-label-primary, #eee); font-size: 12px; line-height: 1.5; outline: none; font-family: var(--ds-font-family-code, ui-monospace, monospace); }\n[data-edrv-view] .edrv-rules-body:focus { border-color: var(--dsw-alias-brand-primary, #4f8cff); }\n[data-edrv-view] .edrv-rules-editor-hint { font-size: 10px; color: var(--dsw-alias-label-tertiary, #9aa5b1); line-height: 1.5; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-editor-foot { display: flex; justify-content: flex-end; flex: 0 0 auto; }\n[data-edrv-view] .edrv-rules-save { height: 24px; padding: 0 14px; border: none; border-radius: 6px; background: var(--dsw-alias-brand-primary, #0f9d58); color: var(--dsw-alias-label-primary-inverted, #fff); font-size: 12px; cursor: pointer; }\n[data-edrv-view] .edrv-rules-save:disabled { opacity: .5; cursor: default; }\n\n\n\n";
|
|
35
36
|
const tagId$1 = "dsh-vscode-mode/editor.css";
|
|
36
37
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$1) + "]") === null) {
|
|
37
38
|
const tag = document.createElement("style");
|
|
@@ -504,11 +505,11 @@ window.__ModuleLoader__.load({
|
|
|
504
505
|
//#endregion
|
|
505
506
|
//#region src/client/monaco/theme.ts
|
|
506
507
|
/**
|
|
507
|
-
* dsh-vscode-mode client — Monaco
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
* 作者 ddj 2026-08-28
|
|
508
|
+
* dsh-vscode-mode client — Monaco 主题:官方令牌跟随 + 现役双套回落。
|
|
509
|
+
* 优先级:官方代码/UI 令牌(--shiki-* / --dsw-alias-*,DSH 0.1.5+ 主题体系,
|
|
510
|
+
* 含第三方皮肤)→ edrv-dark / edrv-light 两套内置配色(旧版 DSH 或令牌缺失)。
|
|
511
|
+
* 明暗判定:body[data-ds-dark-theme](官方)→ 根 data-theme(旧皮肤)→ prefers-color-scheme。
|
|
512
|
+
* 作者 ddj 2026-08-28 / 2026-09-10
|
|
512
513
|
*/
|
|
513
514
|
const EDRV_DARK = "edrv-dark";
|
|
514
515
|
const EDRV_LIGHT = "edrv-light";
|
|
@@ -985,12 +986,14 @@ window.__ModuleLoader__.load({
|
|
|
985
986
|
} catch (error) {}
|
|
986
987
|
}
|
|
987
988
|
/**
|
|
988
|
-
* 探测当前 DSH
|
|
989
|
-
* @author ddj 2026年08月28号
|
|
989
|
+
* 探测当前 DSH 明暗(官方 data-ds-dark-theme → 旧皮肤 data-theme → prefers-color-scheme → 暗)。
|
|
990
|
+
* @author ddj 2026年08月28号 / 2026年09月10号
|
|
990
991
|
* @returns 'dark' | 'light'
|
|
991
992
|
*/
|
|
992
993
|
function detectColorScheme() {
|
|
993
994
|
try {
|
|
995
|
+
const official = document.body?.getAttribute?.("data-ds-dark-theme");
|
|
996
|
+
if (official !== null && official !== void 0 && official !== "false") return "dark";
|
|
994
997
|
const attr = document.documentElement?.getAttribute?.("data-theme") ?? document.body?.getAttribute?.("data-theme");
|
|
995
998
|
const value = String(attr ?? "").toLowerCase();
|
|
996
999
|
if (value.includes("light") || value.includes("catppuccin-latte")) return "light";
|
|
@@ -1018,6 +1021,337 @@ window.__ModuleLoader__.load({
|
|
|
1018
1021
|
monaco.editor.setTheme(themeNameOf());
|
|
1019
1022
|
} catch (error) {}
|
|
1020
1023
|
}
|
|
1024
|
+
/** 官方代码配色令牌 → Monaco 规则 token 前缀(粗粒度;未覆盖的规则保留现役语义分层)。 */
|
|
1025
|
+
const RULE_TOKEN_MAP = [
|
|
1026
|
+
["--shiki-token-comment", ["comment"]],
|
|
1027
|
+
["--shiki-token-keyword", ["keyword"]],
|
|
1028
|
+
["--shiki-token-string", ["string"]],
|
|
1029
|
+
["--shiki-token-string-expression", ["string.escape"]],
|
|
1030
|
+
["--shiki-token-constant", ["number", "constant"]],
|
|
1031
|
+
["--shiki-token-function", [
|
|
1032
|
+
"function",
|
|
1033
|
+
"method",
|
|
1034
|
+
"member"
|
|
1035
|
+
]],
|
|
1036
|
+
["--shiki-token-parameter", ["parameter", "variable.parameter"]],
|
|
1037
|
+
["--shiki-token-punctuation", [
|
|
1038
|
+
"delimiter",
|
|
1039
|
+
"operator",
|
|
1040
|
+
"punctuation"
|
|
1041
|
+
]],
|
|
1042
|
+
["--shiki-token-link", ["annotation", "metatag"]]
|
|
1043
|
+
];
|
|
1044
|
+
/**
|
|
1045
|
+
* 官方 UI 令牌 → Monaco 颜色键(每键给候选令牌,按序取首个可解析值)。
|
|
1046
|
+
* 依据运行态实测:--dsw-alias-* 定义在 body 上;--shiki-background/-foreground 未定义,
|
|
1047
|
+
* 故代码面底色用 markdown-code-block 近似;selection 不覆盖(沿用现役可见选框)。
|
|
1048
|
+
*/
|
|
1049
|
+
const COLOR_TOKEN_MAP = [
|
|
1050
|
+
[["--dsw-alias-markdown-code-block", "--dsw-alias-bg-layer-2"], [
|
|
1051
|
+
"editor.background",
|
|
1052
|
+
"editorGutter.background",
|
|
1053
|
+
"minimap.background"
|
|
1054
|
+
]],
|
|
1055
|
+
[["--dsw-alias-label-primary", "--shiki-foreground"], ["editor.foreground"]],
|
|
1056
|
+
[["--dsw-alias-bg-layer-1", "--dsw-alias-bg-layer-3"], ["editorWidget.background", "editorHoverWidget.background"]],
|
|
1057
|
+
[["--dsw-alias-label-tertiary"], ["editorLineNumber.foreground"]],
|
|
1058
|
+
[["--dsw-alias-label-secondary"], ["editorLineNumber.activeForeground"]],
|
|
1059
|
+
[["--dsw-alias-interactive-bg-hover"], ["editor.lineHighlightBackground", "editor.inactiveSelectionBackground"]]
|
|
1060
|
+
];
|
|
1061
|
+
/** 已应用的官方主题序号(模块级计数,保证主题 id 每次唯一)。 */
|
|
1062
|
+
let officialSeq = 0;
|
|
1063
|
+
/**
|
|
1064
|
+
* 读官方 CSS 变量(先 body 后文档根;未定义/空值/未解析 var() 返回 undefined)。
|
|
1065
|
+
* 依据运行态实测:DSH 的 --dsw-alias-* 定义在 body 上,仅 --shiki-token-* 在根。
|
|
1066
|
+
* @author ddj 2026年09月10号
|
|
1067
|
+
* @param name CSS 变量名(含 -- 前缀)
|
|
1068
|
+
* @returns 计算样式值,或 undefined
|
|
1069
|
+
*/
|
|
1070
|
+
function readCssVar(name) {
|
|
1071
|
+
try {
|
|
1072
|
+
if (typeof window?.getComputedStyle !== "function") return void 0;
|
|
1073
|
+
const hosts = [document?.body, document?.documentElement];
|
|
1074
|
+
for (const host of hosts) {
|
|
1075
|
+
if (!host) continue;
|
|
1076
|
+
const raw = window.getComputedStyle(host).getPropertyValue(name);
|
|
1077
|
+
const value = String(raw ?? "").trim();
|
|
1078
|
+
if (value && !value.startsWith("var(")) return value;
|
|
1079
|
+
}
|
|
1080
|
+
return;
|
|
1081
|
+
} catch (error) {
|
|
1082
|
+
return;
|
|
1083
|
+
}
|
|
1084
|
+
}
|
|
1085
|
+
/**
|
|
1086
|
+
* 数值 → 两位十六进制(0-255 夹取)。
|
|
1087
|
+
* @author ddj 2026年09月10号
|
|
1088
|
+
* @param value 通道值
|
|
1089
|
+
* @returns 两位小写十六进制
|
|
1090
|
+
*/
|
|
1091
|
+
function hex2(value) {
|
|
1092
|
+
const text = Math.max(0, Math.min(255, Math.round(Number(value) || 0))).toString(16);
|
|
1093
|
+
return text.length === 1 ? "0" + text : text;
|
|
1094
|
+
}
|
|
1095
|
+
/**
|
|
1096
|
+
* CSS 颜色归一为 Monaco 可用值(#rgb/#rrggbb/#rrggbbaa 原样,rgb()/hsl() 转 hex,其余 undefined)。
|
|
1097
|
+
* @author ddj 2026年09月10号
|
|
1098
|
+
* @param value CSS 计算样式颜色值
|
|
1099
|
+
* @returns Monaco 颜色字符串,或 undefined(不可识别)
|
|
1100
|
+
*/
|
|
1101
|
+
function toMonacoColor(value) {
|
|
1102
|
+
const text = String(value ?? "").trim().toLowerCase();
|
|
1103
|
+
if (!text || text.startsWith("var(")) return void 0;
|
|
1104
|
+
if (/^#[0-9a-f]{3}$/.test(text)) return "#" + text.slice(1).split("").map((c) => c + c).join("");
|
|
1105
|
+
if (/^#[0-9a-f]{6}$/.test(text) || /^#[0-9a-f]{8}$/.test(text)) return text;
|
|
1106
|
+
return channelColor(text);
|
|
1107
|
+
}
|
|
1108
|
+
/**
|
|
1109
|
+
* rgb()/rgba()/hsl()/hsla() → Monaco 颜色(兼容逗号与空格/斜杠两种参数语法)。
|
|
1110
|
+
* @author ddj 2026年09月10号
|
|
1111
|
+
* @param text 小写颜色文本
|
|
1112
|
+
* @returns Monaco 颜色,或 undefined(不可识别)
|
|
1113
|
+
*/
|
|
1114
|
+
function channelColor(text) {
|
|
1115
|
+
const body = /^(?:rgba?|hsla?)\(([^)]+)\)$/.exec(text)?.[1];
|
|
1116
|
+
if (!body) return void 0;
|
|
1117
|
+
const parts = body.split(/[\s,/]+/).filter(Boolean);
|
|
1118
|
+
if (parts.length < 3) return void 0;
|
|
1119
|
+
let channels;
|
|
1120
|
+
if (text.startsWith("hsl")) {
|
|
1121
|
+
const h = Number(parts[0]);
|
|
1122
|
+
const s = percentOf(parts[1]);
|
|
1123
|
+
const l = percentOf(parts[2]);
|
|
1124
|
+
if (![
|
|
1125
|
+
h,
|
|
1126
|
+
s,
|
|
1127
|
+
l
|
|
1128
|
+
].every(Number.isFinite)) return void 0;
|
|
1129
|
+
channels = hslToRgb(h, s, l);
|
|
1130
|
+
} else channels = parts.slice(0, 3).map(Number);
|
|
1131
|
+
if (channels.some((n) => !Number.isFinite(n))) return void 0;
|
|
1132
|
+
const alpha = parts.length > 3 ? alphaOf(parts[3]) : 1;
|
|
1133
|
+
const tail = Number.isFinite(alpha) && alpha < 1 ? hex2(alpha * 255) : "";
|
|
1134
|
+
return "#" + channels.map(hex2).join("") + tail;
|
|
1135
|
+
}
|
|
1136
|
+
/**
|
|
1137
|
+
* 百分数文本 → 数值('5%' → 5,'0.5' → 0.5)。
|
|
1138
|
+
* @author ddj 2026年09月10号
|
|
1139
|
+
* @param value 参数文本
|
|
1140
|
+
* @returns 数值(非数字为 NaN)
|
|
1141
|
+
*/
|
|
1142
|
+
function percentOf(value) {
|
|
1143
|
+
const text = String(value ?? "");
|
|
1144
|
+
return text.endsWith("%") ? Number(text.slice(0, -1)) : Number(text);
|
|
1145
|
+
}
|
|
1146
|
+
/**
|
|
1147
|
+
* alpha 参数归一('5%' → 0.05,'0.5' → 0.5)。
|
|
1148
|
+
* @author ddj 2026年09月10号
|
|
1149
|
+
* @param value 参数文本
|
|
1150
|
+
* @returns 0-1 的 alpha(非数字为 NaN)
|
|
1151
|
+
*/
|
|
1152
|
+
function alphaOf(value) {
|
|
1153
|
+
const text = String(value ?? "");
|
|
1154
|
+
return text.endsWith("%") ? Number(text.slice(0, -1)) / 100 : Number(text);
|
|
1155
|
+
}
|
|
1156
|
+
/**
|
|
1157
|
+
* HSL → RGB 通道(h 度、s/l 为 0-100 百分数)。
|
|
1158
|
+
* @author ddj 2026年09月10号
|
|
1159
|
+
* @param h 色相(度)
|
|
1160
|
+
* @param s 饱和度(0-100)
|
|
1161
|
+
* @param l 亮度(0-100)
|
|
1162
|
+
* @returns [r, g, b](0-255)
|
|
1163
|
+
*/
|
|
1164
|
+
function hslToRgb(h, s, l) {
|
|
1165
|
+
const hue = (h % 360 + 360) % 360;
|
|
1166
|
+
const sat = Math.max(0, Math.min(100, s)) / 100;
|
|
1167
|
+
const lum = Math.max(0, Math.min(100, l)) / 100;
|
|
1168
|
+
const c = (1 - Math.abs(2 * lum - 1)) * sat;
|
|
1169
|
+
const x = c * (1 - Math.abs(hue / 60 % 2 - 1));
|
|
1170
|
+
const m = lum - c / 2;
|
|
1171
|
+
return [
|
|
1172
|
+
[
|
|
1173
|
+
c,
|
|
1174
|
+
x,
|
|
1175
|
+
0
|
|
1176
|
+
],
|
|
1177
|
+
[
|
|
1178
|
+
x,
|
|
1179
|
+
c,
|
|
1180
|
+
0
|
|
1181
|
+
],
|
|
1182
|
+
[
|
|
1183
|
+
0,
|
|
1184
|
+
c,
|
|
1185
|
+
x
|
|
1186
|
+
],
|
|
1187
|
+
[
|
|
1188
|
+
0,
|
|
1189
|
+
x,
|
|
1190
|
+
c
|
|
1191
|
+
],
|
|
1192
|
+
[
|
|
1193
|
+
x,
|
|
1194
|
+
0,
|
|
1195
|
+
c
|
|
1196
|
+
],
|
|
1197
|
+
[
|
|
1198
|
+
c,
|
|
1199
|
+
0,
|
|
1200
|
+
x
|
|
1201
|
+
]
|
|
1202
|
+
][Math.min(5, Math.floor(hue / 60))].map((v) => (v + m) * 255);
|
|
1203
|
+
}
|
|
1204
|
+
/**
|
|
1205
|
+
* 官方令牌 → Monaco 颜色键覆盖表(候选令牌按序取首个可解析值;全缺则不写入,保持现役回落)。
|
|
1206
|
+
* @author ddj 2026年09月10号
|
|
1207
|
+
* @returns 颜色键 → 颜色值
|
|
1208
|
+
*/
|
|
1209
|
+
function tokenColors() {
|
|
1210
|
+
const out = {};
|
|
1211
|
+
for (const entry of COLOR_TOKEN_MAP) {
|
|
1212
|
+
const color = firstColor(entry[0]);
|
|
1213
|
+
if (color === void 0) continue;
|
|
1214
|
+
for (const key of entry[1]) out[key] = color;
|
|
1215
|
+
}
|
|
1216
|
+
return out;
|
|
1217
|
+
}
|
|
1218
|
+
/**
|
|
1219
|
+
* 候选令牌中首个可解析为 Monaco 颜色的值。
|
|
1220
|
+
* @author ddj 2026年09月10号
|
|
1221
|
+
* @param names CSS 变量名候选(按优先级)
|
|
1222
|
+
* @returns Monaco 颜色,或 undefined(全部缺失/不可解析)
|
|
1223
|
+
*/
|
|
1224
|
+
function firstColor(names) {
|
|
1225
|
+
for (const name of names) {
|
|
1226
|
+
const color = toMonacoColor(readCssVar(name));
|
|
1227
|
+
if (color !== void 0) return color;
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
/**
|
|
1231
|
+
* 官方令牌 → Monaco 规则前缀覆盖表(值去掉 # 前缀,Monaco rules 约定)。
|
|
1232
|
+
* @author ddj 2026年09月10号
|
|
1233
|
+
* @returns token 前缀 → 十六进制色(无 #)
|
|
1234
|
+
*/
|
|
1235
|
+
function tokenRules() {
|
|
1236
|
+
const out = {};
|
|
1237
|
+
for (const entry of RULE_TOKEN_MAP) {
|
|
1238
|
+
const color = toMonacoColor(readCssVar(entry[0]));
|
|
1239
|
+
if (color === void 0) continue;
|
|
1240
|
+
for (const prefix of entry[1]) out[prefix] = color.replace("#", "");
|
|
1241
|
+
}
|
|
1242
|
+
return out;
|
|
1243
|
+
}
|
|
1244
|
+
/**
|
|
1245
|
+
* 现役规则叠加令牌覆盖(前缀命中即换色,未命中保持语义分层)。
|
|
1246
|
+
* @author ddj 2026年09月10号
|
|
1247
|
+
* @param baseRules 现役规则表(edrv-dark / edrv-light)
|
|
1248
|
+
* @param overrides token 前缀 → 颜色
|
|
1249
|
+
* @returns 覆盖后的规则表(无覆盖时原样返回)
|
|
1250
|
+
*/
|
|
1251
|
+
function withOverrides(baseRules, overrides) {
|
|
1252
|
+
const prefixes = Object.keys(overrides);
|
|
1253
|
+
if (!prefixes.length) return baseRules;
|
|
1254
|
+
return baseRules.map((rule) => {
|
|
1255
|
+
const hit = prefixes.find((p) => rule.token === p || rule.token.startsWith(p + "."));
|
|
1256
|
+
return hit === void 0 ? rule : Object.assign({}, rule, { foreground: overrides[hit] });
|
|
1257
|
+
});
|
|
1258
|
+
}
|
|
1259
|
+
/**
|
|
1260
|
+
* 基础规则(token 为空串)前景色跟随官方 editor.foreground。
|
|
1261
|
+
* Monaco 的 '' 规则匹配所有未被更具体规则命中的 token,不改它则内置 #1e1e1e 会盖住
|
|
1262
|
+
* editor.foreground 令牌色(实测 .mtk1 仍为内置值的原因)。
|
|
1263
|
+
* @author ddj 2026年09月10号
|
|
1264
|
+
* @param rules 现役规则表
|
|
1265
|
+
* @param color 已解析的 editor.foreground(含 #,缺省则不覆盖)
|
|
1266
|
+
* @returns 基础规则换色后的规则表
|
|
1267
|
+
*/
|
|
1268
|
+
function withBaseForeground(rules, color) {
|
|
1269
|
+
if (!color) return rules;
|
|
1270
|
+
const foreground = String(color).replace("#", "");
|
|
1271
|
+
return rules.map((rule) => rule.token === "" ? Object.assign({}, rule, { foreground }) : rule);
|
|
1272
|
+
}
|
|
1273
|
+
/**
|
|
1274
|
+
* 构建跟随官方的 Monaco 主题(令牌全缺时 hasTokens=false,调用方回落现役双套)。
|
|
1275
|
+
* @author ddj 2026年09月10号
|
|
1276
|
+
* @param scheme 明暗('light' 之外一律按暗色)
|
|
1277
|
+
* @returns 主题定义(base/rules/colors/hasTokens)
|
|
1278
|
+
*/
|
|
1279
|
+
function officialThemeOf(scheme) {
|
|
1280
|
+
const dark = scheme !== "light";
|
|
1281
|
+
const colors = tokenColors();
|
|
1282
|
+
const rules = tokenRules();
|
|
1283
|
+
const layered = withOverrides(dark ? DARK_RULES : LIGHT_RULES, rules);
|
|
1284
|
+
return {
|
|
1285
|
+
base: dark ? "vs-dark" : "vs",
|
|
1286
|
+
rules: withBaseForeground(layered, colors["editor.foreground"]),
|
|
1287
|
+
colors: Object.assign({}, dark ? DARK_COLORS : LIGHT_COLORS, colors),
|
|
1288
|
+
hasTokens: Object.keys(colors).length > 0 || Object.keys(rules).length > 0
|
|
1289
|
+
};
|
|
1290
|
+
}
|
|
1291
|
+
/**
|
|
1292
|
+
* 应用跟随官方的主题;令牌读不到或定义失败时回落现役双套。
|
|
1293
|
+
* @author ddj 2026年09月10号
|
|
1294
|
+
* @param monaco Monaco 实例
|
|
1295
|
+
* @returns 实际应用的 Monaco 主题 id
|
|
1296
|
+
*/
|
|
1297
|
+
function applyOfficial(monaco) {
|
|
1298
|
+
if (!monaco?.editor?.setTheme || !monaco?.editor?.defineTheme) return themeNameOf();
|
|
1299
|
+
const theme = officialThemeOf(detectColorScheme());
|
|
1300
|
+
if (!theme.hasTokens) {
|
|
1301
|
+
applyTheme(monaco);
|
|
1302
|
+
return themeNameOf();
|
|
1303
|
+
}
|
|
1304
|
+
officialSeq += 1;
|
|
1305
|
+
const id = "edrv-official-" + officialSeq;
|
|
1306
|
+
try {
|
|
1307
|
+
monaco.editor.defineTheme(id, {
|
|
1308
|
+
base: theme.base,
|
|
1309
|
+
inherit: true,
|
|
1310
|
+
rules: theme.rules,
|
|
1311
|
+
colors: theme.colors
|
|
1312
|
+
});
|
|
1313
|
+
monaco.editor.setTheme(id);
|
|
1314
|
+
return id;
|
|
1315
|
+
} catch (error) {
|
|
1316
|
+
applyTheme(monaco);
|
|
1317
|
+
return themeNameOf();
|
|
1318
|
+
}
|
|
1319
|
+
}
|
|
1320
|
+
/**
|
|
1321
|
+
* 观察官方明暗标记变化(body / 根节点的 data-ds-dark-theme 与 data-theme)。
|
|
1322
|
+
* @author ddj 2026年09月10号
|
|
1323
|
+
* @param onChange 标记变化回调
|
|
1324
|
+
* @returns 停止观察函数(非浏览器环境返回空函数)
|
|
1325
|
+
*/
|
|
1326
|
+
function observeScheme(onChange) {
|
|
1327
|
+
try {
|
|
1328
|
+
if (typeof MutationObserver !== "function" || !document?.body) return () => {};
|
|
1329
|
+
const observer = new MutationObserver(() => onChange());
|
|
1330
|
+
const filter = ["data-ds-dark-theme", "data-theme"];
|
|
1331
|
+
observer.observe(document.body, {
|
|
1332
|
+
attributes: true,
|
|
1333
|
+
attributeFilter: filter
|
|
1334
|
+
});
|
|
1335
|
+
if (document.documentElement) observer.observe(document.documentElement, {
|
|
1336
|
+
attributes: true,
|
|
1337
|
+
attributeFilter: filter
|
|
1338
|
+
});
|
|
1339
|
+
return () => observer.disconnect();
|
|
1340
|
+
} catch (error) {
|
|
1341
|
+
return () => {};
|
|
1342
|
+
}
|
|
1343
|
+
}
|
|
1344
|
+
/**
|
|
1345
|
+
* 官方主题快照 → 明暗(ThemeRuntime.getTheme() 快照;字段缺失/未知返回 undefined)。
|
|
1346
|
+
* @author ddj 2026年09月10号
|
|
1347
|
+
* @param snapshot 官方主题快照
|
|
1348
|
+
* @returns 'light' | 'dark' | undefined
|
|
1349
|
+
*/
|
|
1350
|
+
function schemeOfSnapshot(snapshot) {
|
|
1351
|
+
const value = snapshot ?? {};
|
|
1352
|
+
const scheme = value.active?.colorScheme ?? value.colorScheme;
|
|
1353
|
+
return scheme === "light" || scheme === "dark" ? scheme : void 0;
|
|
1354
|
+
}
|
|
1021
1355
|
//#endregion
|
|
1022
1356
|
//#region src/client/monaco/loader.ts
|
|
1023
1357
|
/**
|
|
@@ -1185,7 +1519,7 @@ window.__ModuleLoader__.load({
|
|
|
1185
1519
|
publishStage("ready", MONACO_STAGES.ready.progress, MONACO_STAGES.ready.message);
|
|
1186
1520
|
try {
|
|
1187
1521
|
registerThemes(window.monaco);
|
|
1188
|
-
|
|
1522
|
+
applyOfficial(window.monaco);
|
|
1189
1523
|
} catch (error) {}
|
|
1190
1524
|
resolve(window.monaco);
|
|
1191
1525
|
}, (err) => fail(/* @__PURE__ */ new Error("Monaco 模块加载失败:" + String(err))));
|
|
@@ -2162,7 +2496,9 @@ window.__ModuleLoader__.load({
|
|
|
2162
2496
|
"edrv.toggleSidebar": "Ctrl+B",
|
|
2163
2497
|
"edrv.searchInFiles": "Ctrl+Shift+F",
|
|
2164
2498
|
"edrv.navigateBack": "Alt+ArrowLeft|Ctrl+Alt+-",
|
|
2165
|
-
"edrv.navigateForward": "Alt+ArrowRight|Ctrl+Shift+-"
|
|
2499
|
+
"edrv.navigateForward": "Alt+ArrowRight|Ctrl+Shift+-",
|
|
2500
|
+
"edrv.nextTab": "Ctrl+Alt+ArrowRight|Ctrl+PageDown",
|
|
2501
|
+
"edrv.prevTab": "Ctrl+Alt+ArrowLeft|Ctrl+PageUp"
|
|
2166
2502
|
};
|
|
2167
2503
|
/**
|
|
2168
2504
|
* 返回默认键位的独立副本(调用方修改不污染目录)。
|
|
@@ -2219,6 +2555,14 @@ window.__ModuleLoader__.load({
|
|
|
2219
2555
|
{
|
|
2220
2556
|
id: "edrv.navigateForward",
|
|
2221
2557
|
label: "前进(导航历史)"
|
|
2558
|
+
},
|
|
2559
|
+
{
|
|
2560
|
+
id: "edrv.nextTab",
|
|
2561
|
+
label: "下一个页签"
|
|
2562
|
+
},
|
|
2563
|
+
{
|
|
2564
|
+
id: "edrv.prevTab",
|
|
2565
|
+
label: "上一个页签"
|
|
2222
2566
|
}
|
|
2223
2567
|
];
|
|
2224
2568
|
const MODIFIERS = {
|
|
@@ -2768,6 +3112,20 @@ window.__ModuleLoader__.load({
|
|
|
2768
3112
|
/** 隐藏态拖出面板区的触发阈值(px,拖过即展开并继续实时调宽)。 */
|
|
2769
3113
|
const PULL_OUT_THRESHOLD = 12;
|
|
2770
3114
|
/**
|
|
3115
|
+
* 活动栏图标内容:面板可给官方图标组件(跟随官方主题),也可给文本/emoji(回落)。
|
|
3116
|
+
* @author ddj 2026年09月10号
|
|
3117
|
+
* @param icon 面板定义的 icon 字段(组件或文本)
|
|
3118
|
+
* @returns 图标元素或文本;组件渲染异常返回 null
|
|
3119
|
+
*/
|
|
3120
|
+
function railIconEl(icon) {
|
|
3121
|
+
if (typeof icon !== "function") return icon;
|
|
3122
|
+
try {
|
|
3123
|
+
return react.default.createElement(icon, { size: 16 });
|
|
3124
|
+
} catch (error) {
|
|
3125
|
+
return null;
|
|
3126
|
+
}
|
|
3127
|
+
}
|
|
3128
|
+
/**
|
|
2771
3129
|
* 侧边栏容器。
|
|
2772
3130
|
* @param props.registry 面板注册表(list() 提供面板顺序)
|
|
2773
3131
|
* @param props.ctx 面板共享上下文
|
|
@@ -2856,7 +3214,7 @@ window.__ModuleLoader__.load({
|
|
|
2856
3214
|
onActive(p.id);
|
|
2857
3215
|
if (!visible && typeof onShow === "function") onShow();
|
|
2858
3216
|
}
|
|
2859
|
-
}, react.default.createElement("span", { className: "edrv-rail-icon" }, p.icon), count > 0 ? react.default.createElement("span", { className: "edrv-rail-badge" }, String(count)) : null);
|
|
3217
|
+
}, react.default.createElement("span", { className: "edrv-rail-icon" }, railIconEl(p.icon)), count > 0 ? react.default.createElement("span", { className: "edrv-rail-badge" }, String(count)) : null);
|
|
2860
3218
|
})), react.default.createElement("button", {
|
|
2861
3219
|
className: "edrv-rail-btn",
|
|
2862
3220
|
title: (visible ? "隐藏面板区" : "展开面板区") + " (Ctrl+B)",
|
|
@@ -4658,6 +5016,8 @@ window.__ModuleLoader__.load({
|
|
|
4658
5016
|
const navCursorTimerRef = react.default.useRef(null);
|
|
4659
5017
|
const navBackRef = react.default.useRef(null);
|
|
4660
5018
|
const navForwardRef = react.default.useRef(null);
|
|
5019
|
+
const cycleTabRef = react.default.useRef(null);
|
|
5020
|
+
const tabsHostRef = react.default.useRef(null);
|
|
4661
5021
|
const [navTick, setNavTick] = react.default.useState(0);
|
|
4662
5022
|
const hoverRegionsRef = react.default.useRef([]);
|
|
4663
5023
|
const lineRegionMapRef = react.default.useRef(/* @__PURE__ */ new Map());
|
|
@@ -4670,6 +5030,7 @@ window.__ModuleLoader__.load({
|
|
|
4670
5030
|
const batchBusyRef = react.default.useRef(false);
|
|
4671
5031
|
const menuHandlersRef = react.default.useRef(null);
|
|
4672
5032
|
const doSaveRef = react.default.useRef(null);
|
|
5033
|
+
const onEditRef = react.default.useRef(null);
|
|
4673
5034
|
const saveViewStateRef = react.default.useRef(null);
|
|
4674
5035
|
const diffRendererRef = react.default.useRef(null);
|
|
4675
5036
|
const layoutRef = react.default.useRef(layout);
|
|
@@ -4853,6 +5214,22 @@ window.__ModuleLoader__.load({
|
|
|
4853
5214
|
});
|
|
4854
5215
|
};
|
|
4855
5216
|
/**
|
|
5217
|
+
* 在已打开页签间循环切换(文件分页归编辑器自带页签栏)。
|
|
5218
|
+
* @author ddj 2026年09月10号
|
|
5219
|
+
* @param step 步进(+1 下一个 / -1 上一个)
|
|
5220
|
+
*/
|
|
5221
|
+
const cycleTab = (step) => {
|
|
5222
|
+
if (tabs.length < 2) return;
|
|
5223
|
+
const idx = tabs.findIndex((t) => t.path === active);
|
|
5224
|
+
const next = tabs[(idx + step + tabs.length) % tabs.length];
|
|
5225
|
+
if (!next || next.path === active) return;
|
|
5226
|
+
flushSave();
|
|
5227
|
+
saveViewState(active);
|
|
5228
|
+
recordNav();
|
|
5229
|
+
setActive(next.path);
|
|
5230
|
+
};
|
|
5231
|
+
cycleTabRef.current = cycleTab;
|
|
5232
|
+
/**
|
|
4856
5233
|
* 轮询去重:前后记录内容一致时返回原引用,React 跳过重渲染,
|
|
4857
5234
|
* 阻断 5s 轮询 → memo 链 → diff 重渲染/日志 的空转。
|
|
4858
5235
|
* @author ddj 2026年08月26号
|
|
@@ -5346,6 +5723,27 @@ window.__ModuleLoader__.load({
|
|
|
5346
5723
|
window.addEventListener("keydown", onKey, true);
|
|
5347
5724
|
return () => window.removeEventListener("keydown", onKey, true);
|
|
5348
5725
|
}, []);
|
|
5726
|
+
react.default.useEffect(() => {
|
|
5727
|
+
const onKey = (e) => {
|
|
5728
|
+
const step = matchEvent(e, bindingsOf("edrv.nextTab")) ? 1 : matchEvent(e, bindingsOf("edrv.prevTab")) ? -1 : 0;
|
|
5729
|
+
if (step === 0) return;
|
|
5730
|
+
e.preventDefault();
|
|
5731
|
+
e.stopPropagation();
|
|
5732
|
+
if (cycleTabRef.current) cycleTabRef.current(step);
|
|
5733
|
+
};
|
|
5734
|
+
window.addEventListener("keydown", onKey, true);
|
|
5735
|
+
return () => window.removeEventListener("keydown", onKey, true);
|
|
5736
|
+
}, []);
|
|
5737
|
+
react.default.useEffect(() => {
|
|
5738
|
+
const host = tabsHostRef.current;
|
|
5739
|
+
if (!host) return;
|
|
5740
|
+
const el = host.querySelector?.(".edrv-tab-active");
|
|
5741
|
+
if (!el) return;
|
|
5742
|
+
const left = el.offsetLeft;
|
|
5743
|
+
const right = left + el.offsetWidth;
|
|
5744
|
+
if (left < host.scrollLeft) host.scrollLeft = left;
|
|
5745
|
+
else if (right > host.scrollLeft + host.clientWidth) host.scrollLeft = right - host.clientWidth;
|
|
5746
|
+
}, [active, tabs.length]);
|
|
5349
5747
|
react.default.useEffect(() => {
|
|
5350
5748
|
const onPointer = (e) => {
|
|
5351
5749
|
if (e?.button !== 3 && e?.button !== 4) return;
|
|
@@ -5423,16 +5821,20 @@ window.__ModuleLoader__.load({
|
|
|
5423
5821
|
react.default.useEffect(() => {
|
|
5424
5822
|
if (!monaco) return;
|
|
5425
5823
|
registerThemes(monaco);
|
|
5426
|
-
|
|
5427
|
-
|
|
5428
|
-
|
|
5429
|
-
const
|
|
5430
|
-
if (
|
|
5431
|
-
query.addEventListener("change",
|
|
5432
|
-
|
|
5433
|
-
}
|
|
5434
|
-
|
|
5435
|
-
|
|
5824
|
+
const apply = () => applyOfficial(monaco);
|
|
5825
|
+
apply();
|
|
5826
|
+
window.addEventListener("edrv:theme-change", apply);
|
|
5827
|
+
const query = typeof window.matchMedia === "function" ? window.matchMedia("(prefers-color-scheme: dark)") : null;
|
|
5828
|
+
if (query) {
|
|
5829
|
+
if (typeof query.addEventListener === "function") query.addEventListener("change", apply);
|
|
5830
|
+
else query.addListener(apply);
|
|
5831
|
+
}
|
|
5832
|
+
return () => {
|
|
5833
|
+
window.removeEventListener("edrv:theme-change", apply);
|
|
5834
|
+
if (!query) return;
|
|
5835
|
+
if (typeof query.removeEventListener === "function") query.removeEventListener("change", apply);
|
|
5836
|
+
else query.removeListener(apply);
|
|
5837
|
+
};
|
|
5436
5838
|
}, [monaco]);
|
|
5437
5839
|
monacoRef.current = monaco;
|
|
5438
5840
|
const getModel = (path, text) => {
|
|
@@ -5507,6 +5909,7 @@ window.__ModuleLoader__.load({
|
|
|
5507
5909
|
if (saveTimerRef.current) saveTimerRef.current();
|
|
5508
5910
|
saveTimerRef.current = schedule(() => doSave(true), 700);
|
|
5509
5911
|
};
|
|
5912
|
+
onEditRef.current = onEdit;
|
|
5510
5913
|
react.default.useEffect(() => {
|
|
5511
5914
|
if (!monaco || !editorRef.current || !active || content === null) return;
|
|
5512
5915
|
const ed = editorRef.current;
|
|
@@ -5614,7 +6017,7 @@ window.__ModuleLoader__.load({
|
|
|
5614
6017
|
});
|
|
5615
6018
|
ed.onDidChangeModelContent(() => {
|
|
5616
6019
|
if (!ed.getModel() || programmaticRef.current) return;
|
|
5617
|
-
|
|
6020
|
+
onEditRef.current?.();
|
|
5618
6021
|
});
|
|
5619
6022
|
ed.onDidChangeCursorPosition((e) => {
|
|
5620
6023
|
setCursor("Ln " + e.position.lineNumber + ", Col " + e.position.column);
|
|
@@ -6166,6 +6569,7 @@ window.__ModuleLoader__.load({
|
|
|
6166
6569
|
};
|
|
6167
6570
|
const tabsEl = react.default.createElement("div", {
|
|
6168
6571
|
className: "edrv-tabs",
|
|
6572
|
+
ref: tabsHostRef,
|
|
6169
6573
|
style: {
|
|
6170
6574
|
flex: "1 1 auto",
|
|
6171
6575
|
minWidth: 0
|
|
@@ -6195,7 +6599,10 @@ window.__ModuleLoader__.load({
|
|
|
6195
6599
|
overflow: "hidden",
|
|
6196
6600
|
textOverflow: "ellipsis",
|
|
6197
6601
|
maxWidth: 180
|
|
6198
|
-
} }, t.path.split(/[\\/]/).pop() || t.path), dirtyMap[t.path] ? react.default.createElement("span", {
|
|
6602
|
+
} }, t.path.split(/[\\/]/).pop() || t.path), dirtyMap[t.path] ? react.default.createElement("span", {
|
|
6603
|
+
className: "edrv-tab-star",
|
|
6604
|
+
title: "未保存修改"
|
|
6605
|
+
}, "*") : null, react.default.createElement("span", {
|
|
6199
6606
|
className: "edrv-tab-x",
|
|
6200
6607
|
onClick: (e) => {
|
|
6201
6608
|
e.stopPropagation();
|
|
@@ -7127,6 +7534,17 @@ window.__ModuleLoader__.load({
|
|
|
7127
7534
|
focusDiff: value?.focusDiff === true
|
|
7128
7535
|
};
|
|
7129
7536
|
}
|
|
7537
|
+
/**
|
|
7538
|
+
* 从官方导航参数安全解析行号(缺字段/坏类型/非正数一律视为未指定)。
|
|
7539
|
+
* @author ddj 2026年09月10号
|
|
7540
|
+
* @param params openTab/openResource 传入的 params(正文经 navigation.params 读回)
|
|
7541
|
+
* @returns 正整数行号,或 undefined
|
|
7542
|
+
*/
|
|
7543
|
+
function resolveNavLine(params) {
|
|
7544
|
+
const line = (params ?? {})?.line;
|
|
7545
|
+
if (typeof line !== "number" || !Number.isFinite(line) || line <= 0) return void 0;
|
|
7546
|
+
return Math.floor(line);
|
|
7547
|
+
}
|
|
7130
7548
|
/** 逐段 component 解码(失败返回 null,对齐官方 parseFileAddress 的容错语义)。 */
|
|
7131
7549
|
function decodeSegment(raw) {
|
|
7132
7550
|
if (raw === void 0) return null;
|
|
@@ -7206,6 +7624,27 @@ window.__ModuleLoader__.load({
|
|
|
7206
7624
|
return "dsh-resource://file/session/" + encodeSegment(sessionId) + "/" + relative.split("/").map(encodeSegment).join("/");
|
|
7207
7625
|
}
|
|
7208
7626
|
/**
|
|
7627
|
+
* 把 file 打开请求转发进单一编辑器页签(文件分页由编辑器自带页签栏接管,
|
|
7628
|
+
* 官方侧栏不再按文件分裂出多套编辑器实例)。
|
|
7629
|
+
* @author ddj 2026年09月10号
|
|
7630
|
+
* @param service 官方 sidebarRight 服务(缺失/缺 openTab 返回 false)
|
|
7631
|
+
* @param path 目标文件路径(空值返回 false)
|
|
7632
|
+
* @param line 可选行号(透传给编辑器页签导航参数)
|
|
7633
|
+
* @returns 转发是否成功(openTab 抛错返回 false,由调用方决定重试或兜底)
|
|
7634
|
+
*/
|
|
7635
|
+
function forwardToEditor(service, path, line) {
|
|
7636
|
+
if (!service || typeof service.openTab !== "function" || !path) return false;
|
|
7637
|
+
const params = { openPath: path };
|
|
7638
|
+
if (line !== void 0) params.line = line;
|
|
7639
|
+
try {
|
|
7640
|
+
service.openTab(OFFICIAL_TAB_KIND, { params });
|
|
7641
|
+
return true;
|
|
7642
|
+
} catch (error) {
|
|
7643
|
+
log.warn("file 认领转发进编辑器页签失败(" + String(error) + ")");
|
|
7644
|
+
return false;
|
|
7645
|
+
}
|
|
7646
|
+
}
|
|
7647
|
+
/**
|
|
7209
7648
|
* 注册官方 Tab 正文(keyed slot,key=定义 id;slots.inject 等待 rightbar seat 声明)。
|
|
7210
7649
|
* @author ddj 2026年09月09号
|
|
7211
7650
|
* @param slots slots 服务
|
|
@@ -10084,13 +10523,12 @@ window.__ModuleLoader__.load({
|
|
|
10084
10523
|
//#endregion
|
|
10085
10524
|
//#region src/client/ui/OfficialSideTab.ts
|
|
10086
10525
|
/**
|
|
10087
|
-
* dsh-vscode-mode client — OfficialSideTab:DSH 官方右侧 Sidebar
|
|
10088
|
-
*
|
|
10089
|
-
*
|
|
10090
|
-
*
|
|
10091
|
-
* EditorView 打开流;按会话 key 保证切会话干净重建。
|
|
10526
|
+
* dsh-vscode-mode client — OfficialSideTab:DSH 官方右侧 Sidebar「文件编辑」页签正文包装。
|
|
10527
|
+
* 用途:页类型 Tab(edrvEditor)经 navigation.params(openPath/focusDiff/line)打开;
|
|
10528
|
+
* 兼作 file 认领转发(ClaimRouter)失败时的兜底正文(就地挂编辑器,旧行为)。
|
|
10529
|
+
* 派发既有 edrv:open-editor 事件复用 EditorView 打开流;按会话 key 保证切会话干净重建。
|
|
10092
10530
|
* Tab 正文切换后重挂载时按最新导航恢复打开(对齐 better-sidebar 形态的种子行为)。
|
|
10093
|
-
* 作者 ddj 2026年09月09号
|
|
10531
|
+
* 作者 ddj 2026年09月09号 / 2026年09月10号
|
|
10094
10532
|
*/
|
|
10095
10533
|
/**
|
|
10096
10534
|
* 官方侧边栏 Tab 正文组件(keyed slot sidebar.right.pane.tab 装配)。
|
|
@@ -10143,7 +10581,8 @@ window.__ModuleLoader__.load({
|
|
|
10143
10581
|
const request = resolveNavOpen(navigation?.params);
|
|
10144
10582
|
window.dispatchEvent(new CustomEvent("edrv:open-editor", { detail: {
|
|
10145
10583
|
path: request.path,
|
|
10146
|
-
focusDiff: request.focusDiff
|
|
10584
|
+
focusDiff: request.focusDiff,
|
|
10585
|
+
line: resolveNavLine(navigation?.params)
|
|
10147
10586
|
} }));
|
|
10148
10587
|
});
|
|
10149
10588
|
return react.default.createElement(EditorView, {
|
|
@@ -10159,6 +10598,93 @@ window.__ModuleLoader__.load({
|
|
|
10159
10598
|
});
|
|
10160
10599
|
}
|
|
10161
10600
|
//#endregion
|
|
10601
|
+
//#region src/client/ui/ClaimRouter.ts
|
|
10602
|
+
/**
|
|
10603
|
+
* dsh-vscode-mode client — ClaimRouter:官方 file 认领页签的中转正文。
|
|
10604
|
+
* 官方为每个 `dsh-resource://file/**` 地址开一个认领页签;本组件只做转发:
|
|
10605
|
+
* 解析地址 → 送进单一编辑器页签(文件分页由编辑器自带页签栏接管)→ 关闭本中转页签。
|
|
10606
|
+
* 转发失败(seat 未就绪等瞬时态)按 3 次 ×150ms 重试;仍失败则就地渲染兜底正文
|
|
10607
|
+
* (旧行为:每文件一套编辑器),保证退化路径不白屏。本组件自身不创建 Monaco 实例。
|
|
10608
|
+
* 作者 ddj 2026年09月10号
|
|
10609
|
+
*/
|
|
10610
|
+
/** 转发尝试次数(含首次)与重试间隔。 */
|
|
10611
|
+
const FORWARD_ATTEMPTS = 3;
|
|
10612
|
+
const FORWARD_DELAY_MS = 150;
|
|
10613
|
+
/**
|
|
10614
|
+
* 读 slot 框架注入的 tab 记录(hook 缺失或抛错时返回 undefined)。
|
|
10615
|
+
* @author ddj 2026年09月10号
|
|
10616
|
+
* @param props slot 框架注入的组件 props
|
|
10617
|
+
* @returns tab 记录(含 navigation 与 actions),或 undefined
|
|
10618
|
+
*/
|
|
10619
|
+
function readTab(props) {
|
|
10620
|
+
const useTabInfo = props?.useTabInfo;
|
|
10621
|
+
if (typeof useTabInfo !== "function") return void 0;
|
|
10622
|
+
try {
|
|
10623
|
+
return useTabInfo()?.tab;
|
|
10624
|
+
} catch {
|
|
10625
|
+
return;
|
|
10626
|
+
}
|
|
10627
|
+
}
|
|
10628
|
+
/**
|
|
10629
|
+
* 关闭本中转页签(失败仅告警:目标文件已在编辑器打开,残留页签不阻塞功能)。
|
|
10630
|
+
* @author ddj 2026年09月10号
|
|
10631
|
+
* @param tab slot 框架注入的 tab 记录
|
|
10632
|
+
*/
|
|
10633
|
+
function closeTab(tab) {
|
|
10634
|
+
try {
|
|
10635
|
+
tab?.actions?.close?.();
|
|
10636
|
+
} catch (error) {
|
|
10637
|
+
log.warn("中转页签关闭失败(" + String(error) + ")");
|
|
10638
|
+
}
|
|
10639
|
+
}
|
|
10640
|
+
/**
|
|
10641
|
+
* 组装 file 认领转发正文。
|
|
10642
|
+
* @author ddj 2026年09月10号
|
|
10643
|
+
* @param spec 装配依赖(service 官方导航服务 / schedule 延时调度 / fallback 兜底正文)
|
|
10644
|
+
* @returns 正文组件(注册进 keyed slot sidebar.right.pane.tab)
|
|
10645
|
+
*/
|
|
10646
|
+
function createClaimRouter(spec) {
|
|
10647
|
+
const service = spec?.service;
|
|
10648
|
+
const schedule = spec?.schedule;
|
|
10649
|
+
const fallback = spec?.fallback;
|
|
10650
|
+
/**
|
|
10651
|
+
* 中转正文:转发成功即关闭自身;重试耗尽后渲染兜底正文。
|
|
10652
|
+
* @param props slot 框架注入(useTabInfo)+ 装配依赖
|
|
10653
|
+
* @returns 兜底正文元素,或 null(转发中 / 已转发)
|
|
10654
|
+
*/
|
|
10655
|
+
function ClaimRouter(props) {
|
|
10656
|
+
const tab = readTab(props);
|
|
10657
|
+
const navigation = tab?.navigation;
|
|
10658
|
+
const revision = typeof navigation?.revision === "number" ? navigation.revision : -1;
|
|
10659
|
+
const [failed, setFailed] = react.default.useState(false);
|
|
10660
|
+
const doneRef = react.default.useRef(-1);
|
|
10661
|
+
react.default.useEffect(() => {
|
|
10662
|
+
if (revision === doneRef.current) return;
|
|
10663
|
+
doneRef.current = revision;
|
|
10664
|
+
const parsed = parseOfficialFileAddress(navigation?.address);
|
|
10665
|
+
if (!parsed) {
|
|
10666
|
+
setFailed(true);
|
|
10667
|
+
return;
|
|
10668
|
+
}
|
|
10669
|
+
const line = resolveNavLine(navigation?.params);
|
|
10670
|
+
let left = FORWARD_ATTEMPTS;
|
|
10671
|
+
const attempt = () => {
|
|
10672
|
+
if (forwardToEditor(service, parsed.path, line)) {
|
|
10673
|
+
closeTab(tab);
|
|
10674
|
+
return;
|
|
10675
|
+
}
|
|
10676
|
+
left -= 1;
|
|
10677
|
+
if (left > 0 && typeof schedule === "function") schedule(attempt, FORWARD_DELAY_MS);
|
|
10678
|
+
else setFailed(true);
|
|
10679
|
+
};
|
|
10680
|
+
attempt();
|
|
10681
|
+
}, [revision]);
|
|
10682
|
+
if (!failed || typeof fallback !== "function") return null;
|
|
10683
|
+
return react.default.createElement(fallback, props);
|
|
10684
|
+
}
|
|
10685
|
+
return ClaimRouter;
|
|
10686
|
+
}
|
|
10687
|
+
//#endregion
|
|
10162
10688
|
//#region src/client/sidebar/registry.ts
|
|
10163
10689
|
/** 校验面板定义并写入注册表(缺 id/render 抛 TypeError)。 */
|
|
10164
10690
|
function panelRegister(entries, notify, panel) {
|
|
@@ -10606,8 +11132,8 @@ window.__ModuleLoader__.load({
|
|
|
10606
11132
|
* host 树索引,命中近乎零成本);挂载/切会话从缓存即时恢复展开树;⟳/edrv:refresh
|
|
10607
11133
|
* 保留旧条目强制后台重列(force);每次用户发起加载后预取 ≤4 个子目录(排除重型
|
|
10608
11134
|
* 目录、缓存新鲜跳过、不级联);10s 轻量跟随已展开目录(命中索引,RPC 近零成本)。
|
|
10609
|
-
*
|
|
10610
|
-
* 作者 ddj 2026-08-26 / 2026-08-27 / 2026-08-31
|
|
11135
|
+
* 差异角标/右键菜单/展开状态持久化行为不变;行图标用官方原语(文件夹图标 + 文件类型图标)。
|
|
11136
|
+
* 作者 ddj 2026-08-26 / 2026-08-27 / 2026-08-31 / 2026-09-10
|
|
10611
11137
|
*/
|
|
10612
11138
|
const DIR_CAP = 4e3;
|
|
10613
11139
|
const SAVE_DEBOUNCE_MS = 300;
|
|
@@ -10622,6 +11148,58 @@ window.__ModuleLoader__.load({
|
|
|
10622
11148
|
".pnpm-store"
|
|
10623
11149
|
]);
|
|
10624
11150
|
/**
|
|
11151
|
+
* 目录图标元素(官方 IconFolderOpen16/Close16)。
|
|
11152
|
+
* @author ddj 2026年09月10号
|
|
11153
|
+
* @param isOpen 目录是否展开
|
|
11154
|
+
* @returns 图标元素;原语缺失返回 null
|
|
11155
|
+
*/
|
|
11156
|
+
function dirIconEl(isOpen) {
|
|
11157
|
+
const Icon = isOpen ? _deepseek_ai_dsh_client_ui_primitives.IconFolderOpen16 : _deepseek_ai_dsh_client_ui_primitives.IconFolderClose16;
|
|
11158
|
+
if (typeof Icon !== "function") return null;
|
|
11159
|
+
return react.default.createElement(Icon, {
|
|
11160
|
+
size: 16,
|
|
11161
|
+
className: "edrv-tree-icon"
|
|
11162
|
+
});
|
|
11163
|
+
}
|
|
11164
|
+
/**
|
|
11165
|
+
* 文件图标元素(官方 FileTypeIcon + classifyFileType 分类,未知类型为 other)。
|
|
11166
|
+
* @author ddj 2026年09月10号
|
|
11167
|
+
* @param name 文件名(含扩展名)
|
|
11168
|
+
* @returns 图标元素;原语缺失或分类异常返回 null
|
|
11169
|
+
*/
|
|
11170
|
+
function fileIconEl(name) {
|
|
11171
|
+
if (typeof _deepseek_ai_dsh_client_ui_primitives.FileTypeIcon !== "function" || typeof _deepseek_ai_dsh_client_ui_primitives.classifyFileType !== "function") return null;
|
|
11172
|
+
try {
|
|
11173
|
+
return react.default.createElement(_deepseek_ai_dsh_client_ui_primitives.FileTypeIcon, {
|
|
11174
|
+
kind: (0, _deepseek_ai_dsh_client_ui_primitives.classifyFileType)(String(name ?? "")),
|
|
11175
|
+
size: 16,
|
|
11176
|
+
className: "edrv-tree-icon"
|
|
11177
|
+
});
|
|
11178
|
+
} catch (error) {
|
|
11179
|
+
return null;
|
|
11180
|
+
}
|
|
11181
|
+
}
|
|
11182
|
+
/**
|
|
11183
|
+
* 行图标分派:目录 → 文件夹图标,文件 → 官方类型图标。
|
|
11184
|
+
* @author ddj 2026年09月10号
|
|
11185
|
+
* @param e 目录条目(name/type)
|
|
11186
|
+
* @param isDir 是否目录
|
|
11187
|
+
* @param isOpen 目录是否展开
|
|
11188
|
+
* @returns 图标元素或 null
|
|
11189
|
+
*/
|
|
11190
|
+
function rowIconEl(e, isDir, isOpen) {
|
|
11191
|
+
return isDir ? dirIconEl(isOpen) : fileIconEl(e?.name);
|
|
11192
|
+
}
|
|
11193
|
+
/**
|
|
11194
|
+
* 刷新按钮图标(官方 IconRefreshOutline16;原语缺失回落文本 ⟳)。
|
|
11195
|
+
* @author ddj 2026年09月10号
|
|
11196
|
+
* @returns 图标元素或回落文本
|
|
11197
|
+
*/
|
|
11198
|
+
function refreshIconEl() {
|
|
11199
|
+
if (typeof _deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline16 !== "function") return "⟳";
|
|
11200
|
+
return react.default.createElement(_deepseek_ai_dsh_client_ui_primitives.IconRefreshOutline16, { size: 14 });
|
|
11201
|
+
}
|
|
11202
|
+
/**
|
|
10625
11203
|
* 目录树面板主体(SWR:有缓存先渲染,无缓存才显示加载态;加载总在后台)。
|
|
10626
11204
|
* @param props.ctx 面板共享上下文(sessionId/openFile/activePath/pendingByPath/fileMenuItems/notify)
|
|
10627
11205
|
*/
|
|
@@ -10819,7 +11397,7 @@ window.__ModuleLoader__.load({
|
|
|
10819
11397
|
}
|
|
10820
11398
|
});
|
|
10821
11399
|
}
|
|
10822
|
-
}, react.default.createElement("span", { className: "edrv-tree-chev" }, isDir ? isOpen ? "▾" : "▸" : ""), react.default.createElement("span", { className: "edrv-tree-name" + (dim ? " edrv-tree-dim" : "") },
|
|
11400
|
+
}, react.default.createElement("span", { className: "edrv-tree-chev" }, isDir ? isOpen ? "▾" : "▸" : ""), rowIconEl(e, isDir, isOpen), react.default.createElement("span", { className: "edrv-tree-name" + (dim ? " edrv-tree-dim" : "") }, e.name), pending > 0 ? react.default.createElement("span", { className: "edrv-tree-badge" }, String(pending)) : null);
|
|
10823
11401
|
};
|
|
10824
11402
|
const rowsOf = (rel, depth) => {
|
|
10825
11403
|
const entries = entriesOf(rel);
|
|
@@ -10877,7 +11455,7 @@ window.__ModuleLoader__.load({
|
|
|
10877
11455
|
className: "edrv-side-btn",
|
|
10878
11456
|
title: "刷新目录树",
|
|
10879
11457
|
onClick: refresh
|
|
10880
|
-
},
|
|
11458
|
+
}, refreshIconEl())), react.default.createElement("div", { className: "edrv-tree" }, errorText ? react.default.createElement("div", { className: "edrv-tree-error" }, react.default.createElement("span", null, String(errorText)), react.default.createElement("button", {
|
|
10881
11459
|
className: "edrv-side-btn",
|
|
10882
11460
|
onClick: () => refresh()
|
|
10883
11461
|
}, "重试")) : null, rowsOf("", 0)), menu && menuEntries.length ? react.default.createElement(ContextMenu, {
|
|
@@ -11930,18 +12508,19 @@ window.__ModuleLoader__.load({
|
|
|
11930
12508
|
//#region src/client/sidebar/panels/index.ts
|
|
11931
12509
|
/**
|
|
11932
12510
|
* dsh-vscode-mode client — 侧边栏面板定义(文件管理 + 搜索 + 规则)。
|
|
11933
|
-
*
|
|
12511
|
+
* 活动栏图标用官方 UI 原语(跟随 DSH 主题与皮肤);原语缺失时由 SidebarView 回落文本渲染。
|
|
12512
|
+
* 作者 ddj 2026-08-26 / 2026-09-03 / 2026-09-10
|
|
11934
12513
|
*/
|
|
11935
12514
|
/**
|
|
11936
12515
|
* 构造文件管理面板定义。
|
|
11937
|
-
* @author ddj 2026年08月26号
|
|
11938
|
-
* @returns 面板定义(含活动栏徽标 =
|
|
12516
|
+
* @author ddj 2026年08月26号 / 2026年09月10号
|
|
12517
|
+
* @returns 面板定义(含活动栏徽标 = 差异文件总数;图标 = 官方 IconFolderOpenOutline16)
|
|
11939
12518
|
*/
|
|
11940
12519
|
function createFilePanel() {
|
|
11941
12520
|
return {
|
|
11942
12521
|
id: "explorer",
|
|
11943
12522
|
title: "文件管理",
|
|
11944
|
-
icon:
|
|
12523
|
+
icon: _deepseek_ai_dsh_client_ui_primitives.IconFolderOpenOutline16,
|
|
11945
12524
|
order: 10,
|
|
11946
12525
|
badge: (ctx) => ctx.sum && ctx.sum.totalFiles > 0 ? ctx.sum.totalFiles : null,
|
|
11947
12526
|
render: (ctx) => react.default.createElement(FileExplorer, { ctx })
|
|
@@ -11949,28 +12528,28 @@ window.__ModuleLoader__.load({
|
|
|
11949
12528
|
}
|
|
11950
12529
|
/**
|
|
11951
12530
|
* 构造搜索面板定义。
|
|
11952
|
-
* @author ddj 2026年08月30号
|
|
11953
|
-
* @returns
|
|
12531
|
+
* @author ddj 2026年08月30号 / 2026年09月10号
|
|
12532
|
+
* @returns 面板定义(无徽标;图标 = 官方 IconSearchOutline16)
|
|
11954
12533
|
*/
|
|
11955
12534
|
function createSearchPanel() {
|
|
11956
12535
|
return {
|
|
11957
12536
|
id: "search",
|
|
11958
12537
|
title: "搜索",
|
|
11959
|
-
icon:
|
|
12538
|
+
icon: _deepseek_ai_dsh_client_ui_primitives.IconSearchOutline16,
|
|
11960
12539
|
order: 15,
|
|
11961
12540
|
render: (ctx) => react.default.createElement(SearchPanel, { ctx })
|
|
11962
12541
|
};
|
|
11963
12542
|
}
|
|
11964
12543
|
/**
|
|
11965
12544
|
* 构造规则管理面板定义(Codebuddy 规则形态:用户规则/项目规则双 Tab + 开关)。
|
|
11966
|
-
* @author ddj 2026年09月03号
|
|
11967
|
-
* @returns
|
|
12545
|
+
* @author ddj 2026年09月03号 / 2026年09月10号
|
|
12546
|
+
* @returns 面板定义(无徽标;图标 = 官方 IconListPenOutline16)
|
|
11968
12547
|
*/
|
|
11969
12548
|
function createRulesPanel() {
|
|
11970
12549
|
return {
|
|
11971
12550
|
id: "rules",
|
|
11972
12551
|
title: "规则",
|
|
11973
|
-
icon:
|
|
12552
|
+
icon: _deepseek_ai_dsh_client_ui_primitives.IconListPenOutline16,
|
|
11974
12553
|
order: 20,
|
|
11975
12554
|
render: (ctx) => react.default.createElement(RulesPanel, { ctx })
|
|
11976
12555
|
};
|
|
@@ -12762,14 +13341,14 @@ window.__ModuleLoader__.load({
|
|
|
12762
13341
|
*/
|
|
12763
13342
|
/**
|
|
12764
13343
|
* 构造大纲面板定义。
|
|
12765
|
-
* @author ddj 2026年08月27号
|
|
12766
|
-
* @returns 面板定义(无徽标;活动栏图标
|
|
13344
|
+
* @author ddj 2026年08月27号 / 2026年09月10号
|
|
13345
|
+
* @returns 面板定义(无徽标;活动栏图标 = 官方 IconCodeOutline16)
|
|
12767
13346
|
*/
|
|
12768
13347
|
function createOutlinePanel() {
|
|
12769
13348
|
return {
|
|
12770
13349
|
id: "outline",
|
|
12771
13350
|
title: "大纲",
|
|
12772
|
-
icon:
|
|
13351
|
+
icon: _deepseek_ai_dsh_client_ui_primitives.IconCodeOutline16,
|
|
12773
13352
|
order: 20,
|
|
12774
13353
|
render: (ctx) => react.default.createElement(OutlinePanel, { ctx })
|
|
12775
13354
|
};
|
|
@@ -12950,7 +13529,7 @@ window.__ModuleLoader__.load({
|
|
|
12950
13529
|
{
|
|
12951
13530
|
name: "文件链接官方认领(dsh-resource://file)",
|
|
12952
13531
|
active: claimDisposer !== null,
|
|
12953
|
-
note: claimDisposer !== null ? "
|
|
13532
|
+
note: claimDisposer !== null ? "聊天文件链接转发进单一编辑器页签(文件分页归编辑器自带页签栏)" : "链接走官方查看器或旧版路由(未认领)"
|
|
12954
13533
|
}
|
|
12955
13534
|
];
|
|
12956
13535
|
ctx.provide("fileOpeners", registry);
|
|
@@ -12986,15 +13565,20 @@ window.__ModuleLoader__.load({
|
|
|
12986
13565
|
fileMenuItems,
|
|
12987
13566
|
sessions
|
|
12988
13567
|
}));
|
|
12989
|
-
/** 官方 file 地址认领同步:自动/VSCodeMode
|
|
13568
|
+
/** 官方 file 地址认领同步:自动/VSCodeMode 档认领(转发进单一编辑器页签),其余交官方查看器。 */
|
|
12990
13569
|
const syncFileClaim = () => {
|
|
12991
13570
|
const official = officialService;
|
|
12992
13571
|
const want = official !== void 0 && shouldClaimFiles(selected);
|
|
12993
13572
|
if (want && claimDisposer === null && official) {
|
|
13573
|
+
const renderTab = createClaimRouter({
|
|
13574
|
+
service: official.service,
|
|
13575
|
+
schedule,
|
|
13576
|
+
fallback: officialRenderTab
|
|
13577
|
+
});
|
|
12994
13578
|
const disposer = registerOfficialFileClaim({
|
|
12995
13579
|
tabs: official.tabs,
|
|
12996
13580
|
slots: ctx.slots,
|
|
12997
|
-
renderTab
|
|
13581
|
+
renderTab
|
|
12998
13582
|
});
|
|
12999
13583
|
if (disposer !== null) claimDisposer = ctx.effect(() => disposer, "vscode-mode: official file claim");
|
|
13000
13584
|
return;
|
|
@@ -13065,6 +13649,18 @@ window.__ModuleLoader__.load({
|
|
|
13065
13649
|
}, 2e3);
|
|
13066
13650
|
};
|
|
13067
13651
|
retryRemoteOpen();
|
|
13652
|
+
const themeService = ctx.get("theme");
|
|
13653
|
+
const emitTheme = () => {
|
|
13654
|
+
const snapshot = typeof themeService?.getTheme === "function" ? themeService.getTheme() : void 0;
|
|
13655
|
+
window.dispatchEvent(new CustomEvent("edrv:theme-change", { detail: { scheme: schemeOfSnapshot(snapshot) } }));
|
|
13656
|
+
};
|
|
13657
|
+
ctx.effect(() => {
|
|
13658
|
+
if (!themeService || typeof ctx.on !== "function") return void 0;
|
|
13659
|
+
const disposer = ctx.on("theme/change", emitTheme);
|
|
13660
|
+
return typeof disposer === "function" ? disposer : void 0;
|
|
13661
|
+
}, "vscode-mode: official theme event");
|
|
13662
|
+
ctx.effect(() => observeScheme(emitTheme), "vscode-mode: theme attribute watch");
|
|
13663
|
+
emitTheme();
|
|
13068
13664
|
const registerLegacyTab = () => {
|
|
13069
13665
|
return registerSlotSafely(ctx, {
|
|
13070
13666
|
name: "conversation.view",
|