dsh-sessions-manager 3.7.6 → 3.7.7

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 CHANGED
@@ -314,6 +314,61 @@ function filterShapeFromSaved(item) {
314
314
  if (tag === "" && f.tag !== "") degraded.push("tag");
315
315
  return { view, workspace, sort, tag, degraded };
316
316
  }
317
+ function remainingRows(visibleTotal, renderedVisible) {
318
+ if (visibleTotal == null || visibleTotal === "") return null;
319
+ const total = Number(visibleTotal);
320
+ if (!Number.isFinite(total)) return null;
321
+ const shown = Number(renderedVisible);
322
+ const shownCount = Number.isFinite(shown) ? Math.max(0, Math.floor(shown)) : 0;
323
+ return Math.max(0, Math.max(0, Math.floor(total)) - shownCount);
324
+ }
325
+ function countRenderedVisible(rows, visibleIds) {
326
+ if (!Array.isArray(rows) || !visibleIds || typeof visibleIds.has !== "function") return 0;
327
+ let n = 0;
328
+ for (const row of rows) {
329
+ if (!row || row.pluginHidden) continue;
330
+ if (row.id && visibleIds.has(row.id)) n++;
331
+ }
332
+ return n;
333
+ }
334
+ function aliveSessionCount(sessions, hiddenIds) {
335
+ if (!Array.isArray(sessions) || !sessions.length) return null;
336
+ let alive = 0;
337
+ let seen = 0;
338
+ for (const node of sessions) {
339
+ if (!node || node.id == null) continue;
340
+ const id = String(node.id);
341
+ if (!id) continue;
342
+ seen++;
343
+ if (node.blank) continue;
344
+ if (hiddenIds && typeof hiddenIds.has === "function" && hiddenIds.has(id)) continue;
345
+ alive++;
346
+ }
347
+ return seen === 0 ? null : alive;
348
+ }
349
+ function overflowPlan(text, more) {
350
+ const raw = typeof text === "string" ? text : "";
351
+ const unknown = more == null || !Number.isFinite(Number(more));
352
+ const remaining = unknown ? 0 : Math.max(0, Math.floor(Number(more)));
353
+ const m = raw.match(/(\d[\d,]*)/);
354
+ const base = m ? Number(m[1].replace(/,/g, "")) : null;
355
+ if (base === null || unknown) {
356
+ return { text: raw, hide: false, base, more: unknown ? null : remaining, changed: false };
357
+ }
358
+ if (remaining === 0) {
359
+ return { text: raw, hide: base > 0, base, more: 0, changed: false };
360
+ }
361
+ if (remaining === base) {
362
+ return { text: raw, hide: false, base, more: remaining, changed: false };
363
+ }
364
+ return {
365
+ text: raw.slice(0, m.index) + String(remaining) + raw.slice(m.index + m[1].length),
366
+ hide: false,
367
+ base,
368
+ more: remaining,
369
+ changed: true
370
+ };
371
+ }
317
372
 
318
373
  // src/client/index.jsx
319
374
  var import_jsx_runtime = require("react/jsx-runtime");
@@ -3013,6 +3068,22 @@ function dsmTeardownSidebarAug() {
3013
3068
  } catch (e) {
3014
3069
  }
3015
3070
  }
3071
+ try {
3072
+ document.querySelectorAll("[data-dsm-hidden]").forEach((row) => {
3073
+ row.style.display = "";
3074
+ row.removeAttribute("data-dsm-hidden");
3075
+ });
3076
+ document.querySelectorAll("[data-dsm-overflow-hidden], [data-dsm-overflow-base]").forEach((btn) => {
3077
+ const base = btn.getAttribute("data-dsm-overflow-base");
3078
+ if (base != null && btn.textContent !== base) btn.textContent = base;
3079
+ btn.style.display = "";
3080
+ btn.removeAttribute("data-dsm-overflow-hidden");
3081
+ btn.removeAttribute("data-dsm-overflow-base");
3082
+ btn.removeAttribute("data-dsm-overflow-write");
3083
+ btn.removeAttribute("data-dsm-overflow-ver");
3084
+ });
3085
+ } catch (e) {
3086
+ }
3016
3087
  try {
3017
3088
  document.querySelectorAll("[data-dsm-group-hidden]").forEach((owner) => {
3018
3089
  owner.style.display = owner.dataset.dsmPrevDisplay || "";
@@ -3054,13 +3125,25 @@ function createSidebarAdapter() {
3054
3125
  }
3055
3126
  return out;
3056
3127
  };
3128
+ const recognizeGroupQuiet = (row) => {
3129
+ if (disabled || !row || typeof row !== "object") return null;
3130
+ let f = findFiber(row);
3131
+ let guard = 0;
3132
+ while (f && guard++ < 300) {
3133
+ const props = f.memoizedProps;
3134
+ if (props && props.group && typeof props.group === "object") return props.group;
3135
+ f = f.return;
3136
+ }
3137
+ return null;
3138
+ };
3057
3139
  return {
3058
3140
  version: SIDEBAR_ADAPTER_VERSION,
3059
3141
  get disabled() {
3060
3142
  return disabled;
3061
3143
  },
3062
3144
  findFiber,
3063
- recognize
3145
+ recognize,
3146
+ recognizeGroupQuiet
3064
3147
  };
3065
3148
  }
3066
3149
  var sidebarAdapter = createSidebarAdapter();
@@ -3337,6 +3420,21 @@ function installSidebarSessionMenuAug() {
3337
3420
  function installSidebarStatusDots() {
3338
3421
  if (typeof document === "undefined") return;
3339
3422
  const DOT = "data-dsm-dot";
3423
+ const DSM_HIDDEN_ATTR = "data-dsm-hidden";
3424
+ const GROUP_UNIT_ATTR = "data-dsm-group-hidden";
3425
+ const DSM_OVERFLOW_BASE = "data-dsm-overflow-base";
3426
+ const DSM_OVERFLOW_WRITE = "data-dsm-overflow-write";
3427
+ const DSM_OVERFLOW_VER = "data-dsm-overflow-ver";
3428
+ const DSM_OVERFLOW_HIDDEN = "data-dsm-overflow-hidden";
3429
+ let overflowDebugged = false;
3430
+ const debugOverflowOnce = (msg) => {
3431
+ if (overflowDebugged) return;
3432
+ overflowDebugged = true;
3433
+ try {
3434
+ console.debug("[dsh-sessions-manager] \u5C55\u5F00\u8BA1\u6570\uFF1A" + msg);
3435
+ } catch (e) {
3436
+ }
3437
+ };
3340
3438
  if (!document.querySelector("style[data-dsm=aug]")) {
3341
3439
  const s = document.createElement("style");
3342
3440
  s.dataset.dsm = "aug";
@@ -3367,36 +3465,200 @@ function installSidebarStatusDots() {
3367
3465
  };
3368
3466
  const manualUnread = dsmLoadManual();
3369
3467
  const titleBaselines = /* @__PURE__ */ new WeakMap();
3370
- function dsmSyncEmptyGroups() {
3371
- let groups = null;
3468
+ const setGroupHidden = (scope, hidden) => {
3469
+ if (hidden) {
3470
+ if (!scope.hasAttribute(GROUP_UNIT_ATTR)) {
3471
+ scope.dataset.dsmPrevDisplay = scope.style.display || "";
3472
+ scope.setAttribute(GROUP_UNIT_ATTR, "");
3473
+ }
3474
+ if (scope.style.display !== "none") scope.style.display = "none";
3475
+ return;
3476
+ }
3477
+ if (!scope.hasAttribute(GROUP_UNIT_ATTR)) return;
3478
+ const prev = scope.dataset.dsmPrevDisplay || "";
3479
+ if (scope.style.display !== prev) scope.style.display = prev;
3480
+ scope.removeAttribute(GROUP_UNIT_ATTR);
3481
+ delete scope.dataset.dsmPrevDisplay;
3482
+ };
3483
+ const isShownWithin = (el, stopAt) => {
3484
+ let node = el;
3485
+ while (node && node !== stopAt) {
3486
+ if (node.style && node.style.display === "none") return false;
3487
+ if (node.hasAttribute && (node.hasAttribute(GROUP_UNIT_ATTR) || node.hasAttribute(DSM_HIDDEN_ATTR))) return false;
3488
+ node = node.parentElement;
3489
+ }
3490
+ return true;
3491
+ };
3492
+ function dsmSyncEmptyGroups(purgedNow) {
3493
+ let rows = null;
3372
3494
  try {
3373
- groups = document.querySelectorAll('[role="group"]');
3495
+ rows = document.querySelectorAll('[role="treeitem"][data-row-key^="workspace:"]');
3374
3496
  } catch (e) {
3375
3497
  return;
3376
3498
  }
3377
- if (!groups || !groups.length) return;
3378
- groups.forEach((g) => {
3379
- const items = g.querySelectorAll('[role="treeitem"]');
3380
- if (!items.length) return;
3381
- let visible = 0;
3382
- items.forEach((it) => {
3383
- if (it.style.display !== "none") visible++;
3384
- });
3385
- const owner = g.closest('[role="treeitem"]') || g;
3386
- if (visible === 0) {
3387
- if (!owner.hasAttribute("data-dsm-group-hidden")) {
3388
- owner.dataset.dsmPrevDisplay = owner.style.display || "";
3389
- owner.setAttribute("data-dsm-group-hidden", "");
3499
+ if (!rows || !rows.length) return;
3500
+ const purged = purgedNow instanceof Set ? purgedNow : /* @__PURE__ */ new Set();
3501
+ let hiddenIds = null;
3502
+ const hiddenIdSet = () => {
3503
+ if (hiddenIds) return hiddenIds;
3504
+ hiddenIds = /* @__PURE__ */ new Set();
3505
+ if (dsmTrashIds) for (const id of dsmTrashIds) hiddenIds.add(id);
3506
+ for (const id of purged) hiddenIds.add(id);
3507
+ for (const [id, info] of dsmLineage.entries()) if (info && info.empty) hiddenIds.add(id);
3508
+ return hiddenIds;
3509
+ };
3510
+ rows.forEach((row) => {
3511
+ try {
3512
+ const scope = row.parentElement;
3513
+ if (!scope || scope === document.body) return;
3514
+ if (typeof scope.getAttribute !== "function" || scope.getAttribute("role")) return;
3515
+ let rendered = 0;
3516
+ for (const el of scope.children) {
3517
+ if (el === row || !el.getAttribute) continue;
3518
+ if (el.getAttribute("role") !== "treeitem") continue;
3519
+ if (!(el.getAttribute("data-row-key") || "").startsWith("session:")) continue;
3520
+ if (el.hasAttribute(DSM_HIDDEN_ATTR)) continue;
3521
+ rendered++;
3522
+ }
3523
+ if (rendered > 0) {
3524
+ setGroupHidden(scope, false);
3525
+ return;
3526
+ }
3527
+ for (const nested of scope.querySelectorAll('[data-row-key^="workspace:"]')) {
3528
+ if (nested === row) continue;
3529
+ if (!isShownWithin(nested, scope)) continue;
3530
+ setGroupHidden(scope, false);
3531
+ return;
3390
3532
  }
3391
- if (owner.style.display !== "none") owner.style.display = "none";
3392
- } else if (owner.hasAttribute("data-dsm-group-hidden")) {
3393
- const prev = owner.dataset.dsmPrevDisplay || "";
3394
- if (owner.style.display !== prev) owner.style.display = prev;
3395
- owner.removeAttribute("data-dsm-group-hidden");
3396
- delete owner.dataset.dsmPrevDisplay;
3533
+ const group = sidebarAdapter.recognizeGroupQuiet(row);
3534
+ const sessions = group && Array.isArray(group.sessions) ? group.sessions : null;
3535
+ setGroupHidden(scope, aliveSessionCount(sessions, hiddenIdSet()) === 0);
3536
+ } catch (e) {
3397
3537
  }
3398
3538
  });
3399
3539
  }
3540
+ const OVERFLOW_SIGS = /* @__PURE__ */ new WeakMap();
3541
+ const overflowSignature = (scope, btn, purgedNow) => {
3542
+ let n = 0;
3543
+ let firstKey = "";
3544
+ let lastKey = "";
3545
+ for (const el of scope.children) {
3546
+ if (el === btn || !el.getAttribute) continue;
3547
+ const k = el.getAttribute("data-row-key") || "";
3548
+ if (!k.startsWith("session:")) continue;
3549
+ if (el.hasAttribute(DSM_HIDDEN_ATTR)) continue;
3550
+ n++;
3551
+ if (!firstKey) firstKey = k;
3552
+ lastKey = k;
3553
+ }
3554
+ return n + "|" + firstKey + "|" + lastKey + "|" + (btn.textContent || "") + "|" + (btn.style.display || "") + "|" + (dsmTrashIds ? dsmTrashIds.size : -1) + "|" + purgedNow.size + "|" + dsmLineage.size;
3555
+ };
3556
+ function dsmSyncOverflowLabels(purgedNow) {
3557
+ let buttons = null;
3558
+ try {
3559
+ buttons = document.querySelectorAll('[data-row-key^="overflow:"]');
3560
+ } catch (e) {
3561
+ return;
3562
+ }
3563
+ if (!buttons || !buttons.length) return;
3564
+ try {
3565
+ buttons.forEach((btn) => {
3566
+ const scope = btn.parentElement;
3567
+ if (!scope || !scope.children) return;
3568
+ const sig = overflowSignature(scope, btn, purgedNow);
3569
+ if (OVERFLOW_SIGS.get(btn) === sig) return;
3570
+ const key = (btn.getAttribute("data-row-key") || "").slice("overflow:".length);
3571
+ let wsRow = null;
3572
+ for (const el of scope.children) {
3573
+ if (el.getAttribute && el.getAttribute("data-row-key") === "workspace:" + key) {
3574
+ wsRow = el;
3575
+ break;
3576
+ }
3577
+ }
3578
+ const group = wsRow ? sidebarAdapter.recognizeGroupQuiet(wsRow) : null;
3579
+ const nodes = group && Array.isArray(group.sessions) ? group.sessions : null;
3580
+ if (!nodes) {
3581
+ restoreOverflowButton(btn);
3582
+ OVERFLOW_SIGS.set(btn, overflowSignature(scope, btn, purgedNow));
3583
+ return;
3584
+ }
3585
+ const ids = /* @__PURE__ */ new Set();
3586
+ for (const node of nodes) {
3587
+ if (!node || node.blank) continue;
3588
+ const id = node.id != null ? String(node.id) : "";
3589
+ if (!id) continue;
3590
+ if (dsmTrashIds && dsmTrashIds.has(id) || purgedNow.has(id)) continue;
3591
+ const li = dsmLineage.get(id);
3592
+ if (li && li.empty) continue;
3593
+ ids.add(id);
3594
+ }
3595
+ const rendered = [];
3596
+ for (const el of scope.children) {
3597
+ if (el === btn || !el.getAttribute) continue;
3598
+ if (el.getAttribute("role") !== "treeitem") continue;
3599
+ const k = el.getAttribute("data-row-key") || "";
3600
+ if (!k.startsWith("session:")) continue;
3601
+ rendered.push({ id: k.slice("session:".length), pluginHidden: el.hasAttribute(DSM_HIDDEN_ATTR) });
3602
+ }
3603
+ if (!nodes.length || !ids.size && rendered.length) {
3604
+ restoreOverflowButton(btn);
3605
+ OVERFLOW_SIGS.set(btn, overflowSignature(scope, btn, purgedNow));
3606
+ return;
3607
+ }
3608
+ const renderedVisible = countRenderedVisible(rendered, ids);
3609
+ const more = remainingRows(ids.size, renderedVisible);
3610
+ applyOverflowPlan(btn, more, "\u53EF\u89C1 " + ids.size + " / \u5DF2\u6E32\u67D3 " + renderedVisible);
3611
+ OVERFLOW_SIGS.set(btn, overflowSignature(scope, btn, purgedNow));
3612
+ });
3613
+ } catch (e) {
3614
+ try {
3615
+ console.debug("[dsh-sessions-manager] \u5C55\u5F00\u8BA1\u6570\u6821\u51C6\u8DF3\u8FC7\uFF1A" + (e && e.message));
3616
+ } catch (e2) {
3617
+ }
3618
+ }
3619
+ }
3620
+ function applyOverflowPlan(btn, more, detail) {
3621
+ const raw = btn.textContent || "";
3622
+ const ver = String(SIDEBAR_ADAPTER_VERSION);
3623
+ const fresh = btn.getAttribute(DSM_OVERFLOW_VER) === ver;
3624
+ const last = fresh ? btn.getAttribute(DSM_OVERFLOW_WRITE) : null;
3625
+ let baseline = fresh ? btn.getAttribute(DSM_OVERFLOW_BASE) : null;
3626
+ if (baseline == null || raw !== last) baseline = raw;
3627
+ btn.setAttribute(DSM_OVERFLOW_BASE, baseline);
3628
+ btn.setAttribute(DSM_OVERFLOW_VER, ver);
3629
+ const bm = baseline.match(/(\d[\d,]*)/);
3630
+ const upstream = bm ? Number(bm[1].replace(/,/g, "")) : null;
3631
+ if (more != null && upstream != null && upstream > 0 && more > upstream) {
3632
+ more = upstream;
3633
+ debugOverflowOnce((detail || "") + "\uFF0C\u8D85\u8FC7\u4E0A\u6E38\u8BA1\u6570 " + upstream + "\uFF0C\u5DF2\u6309\u4E0A\u6E38\u8BA1\u6570\u6536\u655B");
3634
+ }
3635
+ const plan = overflowPlan(baseline, more);
3636
+ if (plan.hide) {
3637
+ if (btn.style.display !== "none") btn.style.display = "none";
3638
+ if (!btn.hasAttribute(DSM_OVERFLOW_HIDDEN)) btn.setAttribute(DSM_OVERFLOW_HIDDEN, "");
3639
+ btn.setAttribute(DSM_OVERFLOW_WRITE, baseline);
3640
+ return;
3641
+ }
3642
+ if (btn.hasAttribute(DSM_OVERFLOW_HIDDEN)) {
3643
+ btn.style.display = "";
3644
+ btn.removeAttribute(DSM_OVERFLOW_HIDDEN);
3645
+ }
3646
+ if (plan.changed) {
3647
+ if (btn.textContent !== plan.text) btn.textContent = plan.text;
3648
+ btn.setAttribute(DSM_OVERFLOW_WRITE, plan.text);
3649
+ } else {
3650
+ if (btn.textContent !== baseline) btn.textContent = baseline;
3651
+ btn.setAttribute(DSM_OVERFLOW_WRITE, baseline);
3652
+ }
3653
+ }
3654
+ function restoreOverflowButton(btn) {
3655
+ const verbatim = btn.getAttribute(DSM_OVERFLOW_BASE);
3656
+ if (verbatim != null && btn.textContent !== verbatim) btn.textContent = verbatim;
3657
+ if (btn.hasAttribute(DSM_OVERFLOW_HIDDEN)) {
3658
+ btn.style.display = "";
3659
+ btn.removeAttribute(DSM_OVERFLOW_HIDDEN);
3660
+ }
3661
+ }
3400
3662
  const paint = () => {
3401
3663
  if (sidebarAdapter.disabled) return;
3402
3664
  const activeId = activeRowId();
@@ -3427,6 +3689,7 @@ function installSidebarStatusDots() {
3427
3689
  const purged = purgedNow;
3428
3690
  if (dsmTrashIds && dsmTrashIds.has(id) || purged.has(id)) {
3429
3691
  if (row.style.display !== "none") row.style.display = "none";
3692
+ if (row.getAttribute(DSM_HIDDEN_ATTR) !== "trash") row.setAttribute(DSM_HIDDEN_ATTR, "trash");
3430
3693
  const d = row.querySelector("[" + DOT + "]");
3431
3694
  if (d) d.remove();
3432
3695
  dsmDropSubList(row, id);
@@ -3449,12 +3712,14 @@ function installSidebarStatusDots() {
3449
3712
  }
3450
3713
  if (hideLineage) {
3451
3714
  if (row.style.display !== "none") row.style.display = "none";
3715
+ if (row.getAttribute(DSM_HIDDEN_ATTR) !== "empty") row.setAttribute(DSM_HIDDEN_ATTR, "empty");
3452
3716
  const d = row.querySelector("[" + DOT + "]");
3453
3717
  if (d) d.remove();
3454
3718
  dsmDropSubList(row, id);
3455
3719
  return;
3456
3720
  }
3457
3721
  if (row.style.display === "none") row.style.display = "";
3722
+ if (row.hasAttribute(DSM_HIDDEN_ATTR)) row.removeAttribute(DSM_HIDDEN_ATTR);
3458
3723
  if (!isEmpty && li && li.parentSession && li.origin !== "subagent") {
3459
3724
  const parentTitle = dsmAuthoritativeTitles.get(li.parentSession);
3460
3725
  const tip = parentTitle ? "\u5206\u652F\u4E8E\uFF1A" + parentTitle : "\u5206\u652F\u4F1A\u8BDD\uFF08\u70B9\u51FB\u67E5\u770B\u6765\u6E90\u4F1A\u8BDD\uFF09";
@@ -3581,7 +3846,8 @@ function installSidebarStatusDots() {
3581
3846
  }
3582
3847
  dot.style.background = color;
3583
3848
  });
3584
- dsmSyncEmptyGroups();
3849
+ dsmSyncEmptyGroups(purgedNow);
3850
+ dsmSyncOverflowLabels(purgedNow);
3585
3851
  };
3586
3852
  dsmRepaintDots = paint;
3587
3853
  const paintToast = (msg, kind) => {