dsh-claude-style 0.6.1 → 0.6.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +20 -0
- package/lib/client.js +182 -58
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,26 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `dsh-claude-style` are documented here, newest first.
|
|
4
4
|
|
|
5
|
+
## [0.6.4] - 2026-09-24
|
|
6
|
+
|
|
7
|
+
[中文](#cn-0.6.4) | [English](#en-0.6.4)
|
|
8
|
+
|
|
9
|
+
<h3 id="cn-0.6.4">问题修复</h3>
|
|
10
|
+
|
|
11
|
+
- 修复 **刚启动、账号抽屉还没展开过时,页脚里的插件条目一直留在账户行旁边**:隐藏页脚条目与把条目镜像进抽屉原本挤在同一次调用里,而抽屉没打开时这次调用会提前返回,于是宿主重新渲染出来的插件图标继续画在侧栏底部、紧挨账户行,直到抽屉被展开过一次才被标记隐藏——这正是该现象只在首次启动后出现的原因。现在隐藏条目每次同步都跑,只有镜像需要抽屉容器。
|
|
12
|
+
- 修复 **底栏统计弹层偶尔只剩一段(只显示会话统计,或只显示 Token 用量)**:皮肤按标签文字区分宿主的两颗药丸,读取窗口又只有 300 毫秒,而宿主的两个面板按它自己的提交节奏挂载,晚到一步就丢掉那一段。现在按面板自身的标记判定类型,等待拉长到 800 毫秒、读失败时重试一次;药丸按钮每一步都从 DOM 重新取,窗口内还会再按一次——宿主重渲染换掉节点时,按旧节点等于没按;首次只读到一段时安排一次补读把缺的那段补上,卡片只增不减,已经打开的卡片不会被一次失败的读取改小。会话本身没有计时数据时宿主也不渲染计时面板,此时只有 Token 用量是正确的。
|
|
13
|
+
- 修复 **0.1.7-rc.2 里工作区会话行的状态圈消失**:新宿主把会话行的前导座位交给槽位出口渲染,座位里因此始终有一个 `div[data-slot]` 包裹层(`display: contents`),座位不再是空元素,画在 `:empty` 上的圆圈就不再出现。圆圈现在也挂在空的槽位出口上;座位里带运行状态点时仍由状态点自己绘制。
|
|
14
|
+
- 修复 **账户抽屉收起时它的行与图标停在账户行上方**:自建抽屉的内容要在收起状态下预先对账(镜像行只在收起时同步、展开时冻结),所以收起时面板连同齿轮图标一直挂在账户行正上方,此前只用透明度隐藏,内容仍留在绘制与命中树里。收起状态改用 `visibility` 隐藏(保留布局,关闭的淡出照常),展开时恢复可见。
|
|
15
|
+
|
|
16
|
+
<h3 id="en-0.6.4">Bug Fixes</h3>
|
|
17
|
+
|
|
18
|
+
- Fix **the footer's plugin entries staying beside the account row after a fresh start until the drawer has been opened once**: hiding the entries and mirroring them into the drawer shared one call that returned early while no drawer was up, so the plugin icons the host re-rendered stayed painted at the sidebar's bottom next to the account row until the drawer had been opened once — which is why the symptom only appeared after a fresh start. The hiding now runs on every sync; only the mirroring needs the drawer's container.
|
|
19
|
+
- Fix **the stats card occasionally showing only one section (session statistics alone, or Token usage alone)**: the skin told the host's two pills apart by their label text and read with a 300 ms window, while the host mounts its panels on its own commit — one late panel lost that section. The read now identifies each panel by its own marker, waits up to 800 ms and retries once; it re-resolves the pill from the DOM at every step and presses the live node again while the window lasts, because a press on a node the host has since re-rendered goes nowhere; and a card that did come up short schedules one late re-read that fills the missing section in, so the card only ever grows and a failed read never shrinks a card already on screen. A session with no timing data renders no timing panel in the host either, where Token usage alone is correct.
|
|
20
|
+
- Fix **the workspace session rows' status circle disappearing on 0.1.7-rc.2**: the newer host renders the row's leading seat through a slot outlet, so the seat always carries a `div[data-slot]` anchor (`display: contents`) and is never empty — the circle drawn on `:empty` stopped appearing. The circle now hangs on the empty outlet anchor as well; a seat carrying the running status dot still keeps the dot's own paint.
|
|
21
|
+
- Fix **the account drawer's rows and icons parked above the account row while it is closed**: the self-built drawer's content is reconciled while closed by design (the mirror sync only runs then and freezes while open), so the panel and its gear icon sit right above the account row; opacity alone left that content in the paint and hit-test tree. The closed state now hides it with `visibility` (layout kept, closing fade intact) and the open state restores it.
|
|
22
|
+
|
|
23
|
+
**Full Changelog**: [v0.6.1...v0.6.4](https://github.com/Nwflower/dsh-claude-style/compare/v0.6.1...v0.6.4)
|
|
24
|
+
|
|
5
25
|
## [0.6.1] - 2026-09-24
|
|
6
26
|
|
|
7
27
|
[中文](#cn-0.6.1) | [English](#en-0.6.1)
|
package/lib/client.js
CHANGED
|
@@ -2920,7 +2920,12 @@ window.__ModuleLoader__.load({
|
|
|
2920
2920
|
"body[data-dsh-claude-style] [class*=\"projectRow\"][aria-expanded=\"false\"] [class*=\"chevron\"]::after {",
|
|
2921
2921
|
" transform: rotate(-90deg);",
|
|
2922
2922
|
"}",
|
|
2923
|
-
"/* Session status circle indicator (matching Claude style)
|
|
2923
|
+
"/* Session status circle indicator (matching Claude style). The host's newer",
|
|
2924
|
+
" sidebar renders the leading seat through a slot outlet, whose anchor",
|
|
2925
|
+
" (`div[data-slot]`, display:contents) is a child of the seat even when nothing",
|
|
2926
|
+
" is registered — an idle row's seat is therefore no longer :empty, so the",
|
|
2927
|
+
" circle hangs on the empty anchor as well. A seat carrying status dots or",
|
|
2928
|
+
" another plugin's content keeps its own paint and gets no circle. */",
|
|
2924
2929
|
"body[data-dsh-claude-style] [class*=\"sessionRow\"] [class*=\"slot\"] {",
|
|
2925
2930
|
" width: 14px !important;",
|
|
2926
2931
|
" height: 16px !important;",
|
|
@@ -2928,7 +2933,8 @@ window.__ModuleLoader__.load({
|
|
|
2928
2933
|
" align-items: center !important;",
|
|
2929
2934
|
" justify-content: center !important;",
|
|
2930
2935
|
"}",
|
|
2931
|
-
"body[data-dsh-claude-style] [class*=\"sessionRow\"] [class*=\"slot\"]:empty::after
|
|
2936
|
+
"body[data-dsh-claude-style] [class*=\"sessionRow\"] [class*=\"slot\"]:empty::after,",
|
|
2937
|
+
"body[data-dsh-claude-style] [class*=\"sessionRow\"] [class*=\"slot\"] > [data-slot]:empty::after {",
|
|
2932
2938
|
" content: \"\";",
|
|
2933
2939
|
" display: inline-block;",
|
|
2934
2940
|
" width: 5px;",
|
|
@@ -3255,15 +3261,24 @@ window.__ModuleLoader__.load({
|
|
|
3255
3261
|
" flex-direction: column !important;",
|
|
3256
3262
|
" gap: 6px !important;",
|
|
3257
3263
|
" opacity: 0 !important;",
|
|
3264
|
+
" /* The drawer's rows are built and reconciled while it is closed (the mirror",
|
|
3265
|
+
" sync only runs then), so the panel sits right above the account row with",
|
|
3266
|
+
" its icons in it. opacity alone leaves that content in the paint and",
|
|
3267
|
+
" hit-test tree; visibility takes it out of both, and the delayed transition",
|
|
3268
|
+
" keeps the closing fade. Layout is untouched, so the closed drawer's box is",
|
|
3269
|
+
" still measurable. */",
|
|
3270
|
+
" visibility: hidden !important;",
|
|
3258
3271
|
" pointer-events: none !important;",
|
|
3259
3272
|
" transform: translateY(6px) scale(0.98) !important;",
|
|
3260
3273
|
" transform-origin: bottom left !important;",
|
|
3261
|
-
" transition: opacity 0.15s ease, transform 0.15s ease !important;",
|
|
3274
|
+
" transition: opacity 0.15s ease, transform 0.15s ease, visibility 0s linear 0.15s !important;",
|
|
3262
3275
|
"}",
|
|
3263
3276
|
"body[data-dsh-claude-style] .dsh-claude-account-popover[data-open=\"true\"] {",
|
|
3264
3277
|
" opacity: 1 !important;",
|
|
3278
|
+
" visibility: visible !important;",
|
|
3265
3279
|
" pointer-events: auto !important;",
|
|
3266
3280
|
" transform: translateY(0) scale(1) !important;",
|
|
3281
|
+
" transition: opacity 0.15s ease, transform 0.15s ease, visibility 0s !important;",
|
|
3267
3282
|
"}",
|
|
3268
3283
|
"body[data-dsh-claude-style][data-ds-dark-theme] .dsh-claude-account-popover {",
|
|
3269
3284
|
" background: #1e1e1d !important;",
|
|
@@ -6731,49 +6746,114 @@ window.__ModuleLoader__.load({
|
|
|
6731
6746
|
return rows
|
|
6732
6747
|
}
|
|
6733
6748
|
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
|
|
6737
|
-
|
|
6738
|
-
|
|
6749
|
+
/** How long one pill's panel may take to mount (the host commits on its own schedule). */
|
|
6750
|
+
var STATS_PANEL_POLL_MS = 25
|
|
6751
|
+
var STATS_PANEL_ATTEMPTS = 32
|
|
6752
|
+
/** When a click is repeated inside that window, and how often. */
|
|
6753
|
+
var STATS_PANEL_REPRESS_AT = 12
|
|
6754
|
+
var STATS_PANEL_REPRESS_MAX = 2
|
|
6755
|
+
/** How often a read that could not open a panel is retried, and after what delay. */
|
|
6756
|
+
var STATS_READ_RETRIES = 1
|
|
6757
|
+
var STATS_RETRY_MS = 120
|
|
6758
|
+
/** How long after a short card the one late re-read runs. */
|
|
6759
|
+
var STATS_FILL_MS = 700
|
|
6760
|
+
|
|
6761
|
+
/** The stats panel that is open right now, with the kind its own marker names. */
|
|
6762
|
+
function openStatsPanel() {
|
|
6763
|
+
var details = document.querySelector('[data-session-stats-details]')
|
|
6764
|
+
if (details !== null) {
|
|
6765
|
+
var detailsDialog = details.closest('[role="dialog"]')
|
|
6766
|
+
if (detailsDialog !== null) return { kind: 'details', panel: detailsDialog }
|
|
6739
6767
|
}
|
|
6768
|
+
var usage = document.querySelector('[data-session-stats-usage]')
|
|
6769
|
+
if (usage !== null) {
|
|
6770
|
+
var usageDialog = usage.closest('[role="dialog"]')
|
|
6771
|
+
if (usageDialog !== null) return { kind: 'usage', panel: usageDialog }
|
|
6772
|
+
}
|
|
6773
|
+
return null
|
|
6740
6774
|
}
|
|
6741
6775
|
|
|
6742
|
-
|
|
6743
|
-
|
|
6744
|
-
|
|
6776
|
+
/** The row's pill buttons as they are right now (the host replaces them on re-render). */
|
|
6777
|
+
function statsPillAt(index) {
|
|
6778
|
+
var root = statsRoot()
|
|
6779
|
+
if (root === null) return null
|
|
6780
|
+
var buttons = root.querySelectorAll('button')
|
|
6781
|
+
return index < buttons.length ? buttons[index] : null
|
|
6782
|
+
}
|
|
6783
|
+
|
|
6784
|
+
/**
|
|
6785
|
+
* Open one pill, read whichever stats panel it shows, and close it again.
|
|
6786
|
+
*
|
|
6787
|
+
* The read is kind-agnostic on purpose: which panel appears is the host's
|
|
6788
|
+
* own answer, so a pill is never mislabelled by its label text (the timing
|
|
6789
|
+
* pill's label carries a tok/s reading as well, and the timing pill is a
|
|
6790
|
+
* plain span — no trigger at all — while the session has no timing yet).
|
|
6791
|
+
* The panel counts only while that pill reports itself expanded, so a
|
|
6792
|
+
* sibling's panel that has not unmounted yet is never read as this one's.
|
|
6793
|
+
* The pill is re-resolved from the DOM at every step and pressed again
|
|
6794
|
+
* while the window lasts: the host re-renders the row on its own schedule,
|
|
6795
|
+
* and a click on a node it has since replaced goes nowhere. `null` means
|
|
6796
|
+
* the row has no such pill; a pill that shows no panel inside the window
|
|
6797
|
+
* reports a failure, which is not an absent section.
|
|
6798
|
+
*/
|
|
6799
|
+
function readStatsPill(index, done) {
|
|
6800
|
+
var presses = 0
|
|
6801
|
+
function press() {
|
|
6802
|
+
var pill = statsPillAt(index)
|
|
6803
|
+
if (pill === null) return false
|
|
6804
|
+
if (pill.getAttribute('aria-expanded') !== 'true') pill.click()
|
|
6805
|
+
return true
|
|
6806
|
+
}
|
|
6807
|
+
if (!press()) { done(null); return }
|
|
6745
6808
|
var attempts = 0
|
|
6746
6809
|
function read() {
|
|
6747
|
-
var
|
|
6748
|
-
if (
|
|
6810
|
+
var pill = statsPillAt(index)
|
|
6811
|
+
if (pill === null) { done({ failed: true, rows: [] }); return }
|
|
6812
|
+
var open = pill.getAttribute('aria-expanded') === 'true' ? openStatsPanel() : null
|
|
6813
|
+
if (open === null && attempts < STATS_PANEL_ATTEMPTS) {
|
|
6749
6814
|
attempts += 1
|
|
6750
|
-
|
|
6815
|
+
if (attempts === STATS_PANEL_REPRESS_AT && presses < STATS_PANEL_REPRESS_MAX) {
|
|
6816
|
+
presses += 1
|
|
6817
|
+
press()
|
|
6818
|
+
}
|
|
6819
|
+
setTimeout(read, STATS_PANEL_POLL_MS)
|
|
6751
6820
|
return
|
|
6752
6821
|
}
|
|
6753
|
-
|
|
6754
|
-
if (
|
|
6755
|
-
done(
|
|
6822
|
+
if (pill.getAttribute('aria-expanded') === 'true') pill.click()
|
|
6823
|
+
if (open === null) { done({ failed: true, rows: [] }); return }
|
|
6824
|
+
done({ kind: open.kind, title: open.panel.getAttribute('aria-label') || '', rows: statsRowsFrom(open.panel) })
|
|
6756
6825
|
}
|
|
6757
|
-
setTimeout(read,
|
|
6826
|
+
setTimeout(read, STATS_PANEL_POLL_MS)
|
|
6758
6827
|
}
|
|
6759
6828
|
|
|
6829
|
+
/**
|
|
6830
|
+
* Read both of the host's pills.
|
|
6831
|
+
*
|
|
6832
|
+
* `done(sections, incomplete)`: the sections in the host's own order
|
|
6833
|
+
* (session statistics, then token usage), and `incomplete` true when a
|
|
6834
|
+
* pill the row carries could not be read — the caller must not mistake
|
|
6835
|
+
* that for a section the host does not have.
|
|
6836
|
+
*/
|
|
6760
6837
|
function collectStatsData(done) {
|
|
6761
|
-
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
var usageBtn = null
|
|
6766
|
-
for (var i = 0; i < buttons.length; i++) {
|
|
6767
|
-
var aria = buttons[i].getAttribute('aria-label') || ''
|
|
6768
|
-
if (/轮|步|turns?|steps?/i.test(aria)) timeBtn = buttons[i]
|
|
6769
|
-
else usageBtn = buttons[i]
|
|
6770
|
-
}
|
|
6771
|
-
withStatsPanel(timeBtn, '[role="dialog"]:has([data-session-stats-details])', function (timeData) {
|
|
6772
|
-
withStatsPanel(usageBtn, '[role="dialog"]:has([data-session-stats-usage])', function (usageData) {
|
|
6838
|
+
if (statsRoot() === null) { done([], false); return }
|
|
6839
|
+
readStatsPill(0, function (first) {
|
|
6840
|
+
readStatsPill(1, function (second) {
|
|
6841
|
+
var reads = [first, second]
|
|
6773
6842
|
var sections = []
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6843
|
+
var incomplete = false
|
|
6844
|
+
for (var i = 0; i < reads.length; i++) {
|
|
6845
|
+
var read = reads[i]
|
|
6846
|
+
if (read === null) continue
|
|
6847
|
+
if (read.failed === true || read.rows.length === 0) {
|
|
6848
|
+
incomplete = true
|
|
6849
|
+
continue
|
|
6850
|
+
}
|
|
6851
|
+
sections.push(read)
|
|
6852
|
+
}
|
|
6853
|
+
sections.sort(function (a, b) {
|
|
6854
|
+
return (a.kind === 'details' ? 0 : 1) - (b.kind === 'details' ? 0 : 1)
|
|
6855
|
+
})
|
|
6856
|
+
done(sections, incomplete)
|
|
6777
6857
|
})
|
|
6778
6858
|
})
|
|
6779
6859
|
}
|
|
@@ -6841,12 +6921,34 @@ window.__ModuleLoader__.load({
|
|
|
6841
6921
|
pop.innerHTML = html
|
|
6842
6922
|
}
|
|
6843
6923
|
|
|
6844
|
-
/**
|
|
6924
|
+
/** Whether the card is up, so a failed re-read can leave its content alone. */
|
|
6925
|
+
function isStatsPopoverOpen() {
|
|
6926
|
+
return statsPopover !== null && statsPopover.getAttribute('data-open') === 'true'
|
|
6927
|
+
}
|
|
6845
6928
|
|
|
6846
|
-
|
|
6929
|
+
/** How many sections the card currently shows. */
|
|
6930
|
+
var renderedSections = 0
|
|
6847
6931
|
|
|
6848
|
-
|
|
6932
|
+
/** Place the card above the stats row, clamped to the viewport. */
|
|
6933
|
+
function placeStatsPopover(anchor) {
|
|
6934
|
+
var pop = ensureStatsPopover()
|
|
6935
|
+
var live = statsRoot() || anchor
|
|
6936
|
+
if (live === null) return
|
|
6937
|
+
var rect = live.getBoundingClientRect()
|
|
6938
|
+
var width = pop.offsetWidth
|
|
6939
|
+
var height = pop.offsetHeight
|
|
6940
|
+
var left = Math.max(8, Math.min(rect.left + rect.width / 2 - width / 2, window.innerWidth - width - 8))
|
|
6941
|
+
var top = Math.max(8, rect.top - height - 8)
|
|
6942
|
+
pop.style.left = left + 'px'
|
|
6943
|
+
pop.style.top = top + 'px'
|
|
6944
|
+
}
|
|
6849
6945
|
|
|
6946
|
+
function showStatsSections(anchor, sections) {
|
|
6947
|
+
renderStatsPopover(sections)
|
|
6948
|
+
renderedSections = sections.length
|
|
6949
|
+
ensureStatsPopover().setAttribute('data-open', 'true')
|
|
6950
|
+
placeStatsPopover(anchor)
|
|
6951
|
+
}
|
|
6850
6952
|
|
|
6851
6953
|
function showStatsPopover(anchor) {
|
|
6852
6954
|
// The card reads the host's two dialogs, which only the detailed row
|
|
@@ -6858,29 +6960,40 @@ window.__ModuleLoader__.load({
|
|
|
6858
6960
|
clearTimeout(statsHideTimer)
|
|
6859
6961
|
statsHideTimer = null
|
|
6860
6962
|
}
|
|
6861
|
-
|
|
6963
|
+
readStatsCard(anchor, 0)
|
|
6964
|
+
}
|
|
6965
|
+
|
|
6966
|
+
/**
|
|
6967
|
+
* Collect the host's panels and render the card.
|
|
6968
|
+
*
|
|
6969
|
+
* A read that could not open one of the panels is retried, and one that
|
|
6970
|
+
* still comes back short while the card is already up leaves the card as
|
|
6971
|
+
* it is: the host's panels mount on its own commit, so a read that lost
|
|
6972
|
+
* the race must never read as a section the host does not have — that was
|
|
6973
|
+
* the 'click and it drops to Token usage only' card. A card that did come
|
|
6974
|
+
* up short schedules one late re-read, which fills it in and never
|
|
6975
|
+
* shrinks it.
|
|
6976
|
+
*/
|
|
6977
|
+
function readStatsCard(anchor, attempt) {
|
|
6978
|
+
collectStatsData(function (sections, incomplete) {
|
|
6862
6979
|
if (sections.length === 0) return
|
|
6863
|
-
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
var fresh = Date.now() - statsSectionsAt < 180000
|
|
6867
|
-
if (statsSections !== null && fresh && sections.length < statsSections.length) {
|
|
6868
|
-
sections = statsSections
|
|
6869
|
-
} else {
|
|
6870
|
-
statsSections = sections
|
|
6871
|
-
statsSectionsAt = Date.now()
|
|
6980
|
+
if (incomplete && attempt < STATS_READ_RETRIES) {
|
|
6981
|
+
setTimeout(function () { readStatsCard(anchor, attempt + 1) }, STATS_RETRY_MS)
|
|
6982
|
+
return
|
|
6872
6983
|
}
|
|
6873
|
-
|
|
6874
|
-
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
|
|
6879
|
-
|
|
6880
|
-
|
|
6881
|
-
|
|
6882
|
-
|
|
6883
|
-
|
|
6984
|
+
if (incomplete && isStatsPopoverOpen()) return
|
|
6985
|
+
showStatsSections(anchor, sections)
|
|
6986
|
+
if (incomplete) setTimeout(function () { fillStatsCard(anchor) }, STATS_FILL_MS)
|
|
6987
|
+
})
|
|
6988
|
+
}
|
|
6989
|
+
|
|
6990
|
+
/** One late re-read for a card that came up short; it only ever adds. */
|
|
6991
|
+
function fillStatsCard(anchor) {
|
|
6992
|
+
collectStatsData(function (sections, incomplete) {
|
|
6993
|
+
if (incomplete || sections.length === 0) return
|
|
6994
|
+
if (!isStatsPopoverOpen()) return
|
|
6995
|
+
if (sections.length <= renderedSections) return
|
|
6996
|
+
showStatsSections(anchor, sections)
|
|
6884
6997
|
})
|
|
6885
6998
|
}
|
|
6886
6999
|
|
|
@@ -11056,6 +11169,12 @@ window.__ModuleLoader__.load({
|
|
|
11056
11169
|
var footerEntries = syncFooterActionVisibility(footerActions)
|
|
11057
11170
|
var body = options.body()
|
|
11058
11171
|
|
|
11172
|
+
// A closed host drawer has no container to mirror into, but the entries
|
|
11173
|
+
// above are hidden in place all the same: the host re-renders them, and a
|
|
11174
|
+
// pass that skips this leaves their icons painted in the sidebar until the
|
|
11175
|
+
// drawer is opened once.
|
|
11176
|
+
if (body === null) return
|
|
11177
|
+
|
|
11059
11178
|
// While the popover is open, its mirrors must stay completely static:
|
|
11060
11179
|
// a content rewrite, reorder, or embedded-clone replacement under the
|
|
11061
11180
|
// pointer cancels the browser's :hover state and can swallow the click
|
|
@@ -11746,10 +11865,15 @@ window.__ModuleLoader__.load({
|
|
|
11746
11865
|
syncAccountRowBox(entryRow, footArea)
|
|
11747
11866
|
if (hostTrigger !== null) bindHostRowHover(hostTrigger)
|
|
11748
11867
|
|
|
11868
|
+
// The host's footer entries are hidden in place on every pass, drawer or
|
|
11869
|
+
// no drawer: the host re-renders them, and a pass that skipped this left
|
|
11870
|
+
// their icons painted beside the account row until the drawer had been
|
|
11871
|
+
// opened once. Only the mirroring needs a container to write into.
|
|
11872
|
+
mirror.sync(footArea)
|
|
11873
|
+
|
|
11749
11874
|
var root = surface.mode() === 'host' ? surface.container() : accountPopover
|
|
11750
11875
|
if (root === null) return
|
|
11751
11876
|
rows.syncHeader(root, hostTrigger)
|
|
11752
|
-
mirror.sync(footArea)
|
|
11753
11877
|
// The rail toggle (and any reflow) moves the anchor without a window
|
|
11754
11878
|
// resize or a page scroll, so an open drawer re-resolves its position at
|
|
11755
11879
|
// the end of its own pass.
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-claude-style",
|
|
3
3
|
"description": "Claude Code Desktop theme for DeepSeek Harness (dsh) web GUI — visual & interaction overhaul",
|
|
4
|
-
"version": "0.6.
|
|
4
|
+
"version": "0.6.4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"icon": "lib/claude-mark.svg",
|