dsh-ws-recency 0.10.1 → 0.10.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/client.js +62 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -65,7 +65,7 @@ DSH 原生的置顶只把会话顶到**它所属工作区分组的第一行**,
|
|
|
65
65
|
|
|
66
66
|
## 六、Token 消耗统计
|
|
67
67
|
|
|
68
|
-
|
|
68
|
+
会话下方统计条上的「用量分析」,或会话「…」菜单 →「Token 消耗统计」:
|
|
69
69
|
|
|
70
70
|
- **真实账单**(每步记录的 usage):步数、输入(未缓存)、缓存命中、输出、合计;
|
|
71
71
|
- **结构占比**(按内容估算):主 agent 自己(思考 / 回复 / 用户消息 / 系统提示)vs 每个工具,一条占比条 + 图例;
|
|
@@ -110,7 +110,7 @@ dsh plugin --profile <profile> add github:chyxhtc/dsh-ws-recency
|
|
|
110
110
|
或固定版本的预构建包:
|
|
111
111
|
|
|
112
112
|
```powershell
|
|
113
|
-
dsh plugin --profile <profile> add https://github.com/chyxhtc/dsh-ws-recency/releases/download/v0.10.
|
|
113
|
+
dsh plugin --profile <profile> add https://github.com/chyxhtc/dsh-ws-recency/releases/download/v0.10.2/dsh-ws-recency-0.10.2.tgz
|
|
114
114
|
```
|
|
115
115
|
|
|
116
116
|
装完把 `dsh-ws-recency` 加进 `~/.hypers-work/profiles/<profile>/package.json` 的 `dsh.profile.bundles`,重启应用。
|
package/client.js
CHANGED
|
@@ -85,6 +85,7 @@
|
|
|
85
85
|
var pinHidden = new Set();
|
|
86
86
|
var pinHost = null;
|
|
87
87
|
var expandClicks = new Map();
|
|
88
|
+
var composerPill = null;
|
|
88
89
|
var expandedSections = new Set();
|
|
89
90
|
var headerMarked = new WeakSet();
|
|
90
91
|
var disposed = false;
|
|
@@ -104,6 +105,8 @@
|
|
|
104
105
|
".wsr-pin-unpin{flex:none;border:none;background:transparent;color:var(--dsw-alias-label-tertiary);cursor:pointer;font-size:11px;padding:2px 4px;border-radius:4px;visibility:hidden}",
|
|
105
106
|
".wsr-pin-row:hover .wsr-pin-unpin{visibility:visible}",
|
|
106
107
|
".wsr-pin-unpin:hover{color:var(--dsw-alias-label-primary)}",
|
|
108
|
+
".wsr-pill{box-sizing:border-box;border:none;background:0 0;color:var(--dsw-alias-label-tertiary);font:inherit;font-variant-numeric:tabular-nums;line-height:inherit;white-space:nowrap;border-radius:var(--dsw-radius-sm,6px);display:inline-flex;align-items:center;gap:6px;padding:1px 8px;cursor:pointer}",
|
|
109
|
+
".wsr-pill:hover{background:var(--dsw-alias-interactive-bg-hover,rgba(255,255,255,.08));color:var(--dsw-alias-label-secondary,#cfd3d8)}",
|
|
107
110
|
".wsr-modal-backdrop{position:fixed;inset:0;z-index:2000;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.45)}",
|
|
108
111
|
".wsr-modal{width:min(720px,92vw);max-height:84vh;display:flex;flex-direction:column;background:var(--dsw-alias-bg-layer-1,#1f2226);color:var(--dsw-alias-label-primary,#e8e8e8);border:.5px solid var(--dsw-alias-border-l2,rgba(255,255,255,.14));border-radius:10px;box-shadow:0 12px 40px rgba(0,0,0,.45);overflow:hidden}",
|
|
109
112
|
".wsr-modal-head{display:flex;align-items:center;justify-content:space-between;padding:12px 14px;border-bottom:.5px solid var(--dsw-alias-border-l2,rgba(255,255,255,.1))}",
|
|
@@ -181,6 +184,7 @@
|
|
|
181
184
|
"stats.agentDetail": "主 agent 构成:思考 {reasoning} · 回复 {text} · 用户消息 {user} · 系统提示 {system}",
|
|
182
185
|
"stats.diagnose.unmounted": "\n\n(宿主半已加载,但统计路由没挂上——重启应用再试)",
|
|
183
186
|
"stats.diagnose.noHost": "\n\n(宿主半未加载:需要重启应用加载新版本)",
|
|
187
|
+
"composer.analysis": "用量分析",
|
|
184
188
|
"trash.confirm": "\u5220\u9664\u8fd9\u4e2a\u4f1a\u8bdd\uff1f\n\n\u4f1a\u5148\u505c\u6b62\u5b83\u6b63\u5728\u8fdb\u884c\u7684\u5de5\u4f5c\uff0c\u518d\u628a\u65e5\u5fd7\u76ee\u5f55\u79fb\u5165\u56de\u6536\u7ad9\uff08\u4e0d\u662f\u7269\u7406\u5220\u9664\uff0c\u53ef\u4ee5\u624b\u52a8\u6062\u590d\uff09\u3002",
|
|
185
189
|
"trash.failed": "\u5220\u9664\u5931\u8d25\uff1a",
|
|
186
190
|
};
|
|
@@ -221,6 +225,7 @@
|
|
|
221
225
|
"stats.agentDetail": "Agent composition: reasoning {reasoning} \u00b7 reply {text} \u00b7 user messages {user} \u00b7 system prompt {system}",
|
|
222
226
|
"stats.diagnose.unmounted": "\n\n(the host half is loaded but the statistics route did not mount - restart the app and retry)",
|
|
223
227
|
"stats.diagnose.noHost": "\n\n(the host half is not loaded: restart the app to pick up the new version)",
|
|
228
|
+
"composer.analysis": "Usage analysis",
|
|
224
229
|
"trash.confirm": "Delete this session?\n\nIt stops whatever the session is running, then moves the log directory into the trash folder (a move, not an erase: you can restore it by hand).",
|
|
225
230
|
"trash.failed": "Delete failed: ",
|
|
226
231
|
};
|
|
@@ -785,20 +790,72 @@
|
|
|
785
790
|
}
|
|
786
791
|
}
|
|
787
792
|
|
|
793
|
+
/** The session the conversation view is showing, from its own DOM hook. */
|
|
794
|
+
function currentConversationId() {
|
|
795
|
+
if (typeof document === "undefined") return null;
|
|
796
|
+
var element = document.querySelector("[data-conversation-session]");
|
|
797
|
+
if (element === null || typeof element.getAttribute !== "function") return null;
|
|
798
|
+
var id = element.getAttribute("data-conversation-session");
|
|
799
|
+
return typeof id === "string" && id !== "" ? id : null;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
/**
|
|
803
|
+
* Add one pill to the composer's statistics row ("turns / steps / tokens")
|
|
804
|
+
* that opens the same analysis panel as the session menu.
|
|
805
|
+
*
|
|
806
|
+
* The row is host-rendered and re-renders often, so the pill is re-attached
|
|
807
|
+
* on every pass and dropped as soon as the row or the session goes away.
|
|
808
|
+
*/
|
|
809
|
+
function decorateComposerStats() {
|
|
810
|
+
if (typeof document === "undefined") return;
|
|
811
|
+
var existing = document.querySelector("[data-wsr-composer-analysis]");
|
|
812
|
+
var seat = document.querySelector("[data-composer-seat]");
|
|
813
|
+
var anchors = seat === null || typeof seat.querySelectorAll !== "function" ? [] : seat.querySelectorAll("[data-composer-stat]");
|
|
814
|
+
if (anchors.length === 0 || currentConversationId() === null) {
|
|
815
|
+
if (existing !== null) existing.remove();
|
|
816
|
+
composerPill = null;
|
|
817
|
+
return;
|
|
818
|
+
}
|
|
819
|
+
var row = anchors[0].parentElement;
|
|
820
|
+
if (row === null) return;
|
|
821
|
+
if (existing === null) {
|
|
822
|
+
var button = document.createElement("button");
|
|
823
|
+
button.type = "button";
|
|
824
|
+
button.className = "wsr-pill";
|
|
825
|
+
button.setAttribute("data-wsr-composer-analysis", "true");
|
|
826
|
+
button.textContent = t("composer.analysis");
|
|
827
|
+
button.addEventListener("click", function () {
|
|
828
|
+
var id = currentConversationId();
|
|
829
|
+
if (id !== null) openStatsPanel(id);
|
|
830
|
+
});
|
|
831
|
+
composerPill = button;
|
|
832
|
+
} else {
|
|
833
|
+
composerPill = existing;
|
|
834
|
+
}
|
|
835
|
+
if (composerPill.parentElement !== row) row.appendChild(composerPill);
|
|
836
|
+
}
|
|
837
|
+
|
|
788
838
|
function apply() {
|
|
789
839
|
if (disposed) return;
|
|
790
840
|
var sessions = data.sessions;
|
|
791
841
|
var workspaces = data.workspaces;
|
|
792
|
-
if (!ready(sessions) || !ready(workspaces)) return;
|
|
793
|
-
|
|
794
842
|
var settings = settingsOf();
|
|
843
|
+
if (!ready(sessions) || !ready(workspaces)) {
|
|
844
|
+
decorateComposerStats();
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
|
|
795
848
|
var entries = collect();
|
|
796
|
-
if (entries.length === 0)
|
|
849
|
+
if (entries.length === 0) {
|
|
850
|
+
decorateComposerStats();
|
|
851
|
+
return;
|
|
852
|
+
}
|
|
797
853
|
|
|
798
854
|
orderGroups(entries, latestByWorkspace(sessions, workspaces));
|
|
799
855
|
foldRows(entries, settings, sessions, Date.now());
|
|
800
856
|
renderPinned(entries, sessions, workspaces, settings);
|
|
801
857
|
if (settings.colors) decorateRows(entries, sessions, data.statuses, settings);
|
|
858
|
+
decorateComposerStats();
|
|
802
859
|
}
|
|
803
860
|
|
|
804
861
|
function schedule() {
|
|
@@ -1236,6 +1293,8 @@
|
|
|
1236
1293
|
});
|
|
1237
1294
|
pinHidden.clear();
|
|
1238
1295
|
if (pinHost !== null && pinHost.parentElement !== null) pinHost.remove();
|
|
1296
|
+
if (composerPill !== null && typeof composerPill.remove === "function") composerPill.remove();
|
|
1297
|
+
composerPill = null;
|
|
1239
1298
|
pinHost = null;
|
|
1240
1299
|
expandClicks.clear();
|
|
1241
1300
|
roots.forEach(function (root) { root.removeAttribute(ROOT_ATTR); });
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-ws-recency",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.2",
|
|
4
4
|
"description": "Sidebar session management for DeepSeek Harness: workspace groups sorted by latest activity, stale history folded, a global pinned section, follow-up marks, session delete into a recoverable trash, and per-session token statistics split by tool.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "chyxhtc",
|