dsh-dock 0.11.1 → 0.11.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 +16 -9
- package/features/tokenlog/view.jsx +16 -6
- package/package.json +1 -1
- package/src/client.jsx +8 -5
package/README.md
CHANGED
|
@@ -95,7 +95,7 @@ dsh plugin --profile web remove dsh-dock # 卸载
|
|
|
95
95
|
- **⛁ 会话用量**:显示当前会话的 Token 数与估算费用(10 秒自动刷新)
|
|
96
96
|
- **余额**:显示当前选中模型的 Provider 账户余额(跟随模型切换实时更新)
|
|
97
97
|
|
|
98
|
-
|
|
98
|
+
点击芯片直接跳转功能坞对应页(「会话用量」打开后即按当前会话筛选出结果,无需再点查询)。每个功能可在面板页脚或设置页单独设置「会话页显示 / 隐藏」。
|
|
99
99
|
|
|
100
100
|
### 各功能使用
|
|
101
101
|
|
|
@@ -252,7 +252,7 @@ dsh plugin --profile web remove dsh-dock # 卸载
|
|
|
252
252
|
- **⛁ 会话用量**:显示当前会话的 Token 数与估算费用(10 秒自动刷新)
|
|
253
253
|
- **余额**:显示当前选中模型的 Provider 账户余额(跟随模型切换实时更新)
|
|
254
254
|
|
|
255
|
-
|
|
255
|
+
点击芯片直接跳转功能坞对应页(「会话用量」打开后即按当前会话筛选出结果,无需再点查询)。每个功能可在面板页脚或设置页单独设置「会话页显示 / 隐藏」。
|
|
256
256
|
|
|
257
257
|
### 各功能使用
|
|
258
258
|
|
package/client.js
CHANGED
|
@@ -2823,6 +2823,7 @@ function PricingEditor({ onClose, onSaved, embedded }) {
|
|
|
2823
2823
|
}
|
|
2824
2824
|
function TokenLogView(props) {
|
|
2825
2825
|
const navSession = props && props.params && props.params.sessionId ? props.params.sessionId : null;
|
|
2826
|
+
const navAt = props && props.params && props.params.navAt ? props.params.navAt : 0;
|
|
2826
2827
|
const [savedFilters] = (0, import_react2.useState)(loadSavedFilters);
|
|
2827
2828
|
const [fromStr, setFromStr] = (0, import_react2.useState)(() => savedFilters && savedFilters.fromStr || "");
|
|
2828
2829
|
const [toStr, setToStr] = (0, import_react2.useState)(() => savedFilters && savedFilters.toStr || "");
|
|
@@ -2830,7 +2831,7 @@ function TokenLogView(props) {
|
|
|
2830
2831
|
const [model, setModel] = (0, import_react2.useState)(() => savedFilters && savedFilters.model || "");
|
|
2831
2832
|
const [status, setStatus] = (0, import_react2.useState)(() => savedFilters && savedFilters.status || "");
|
|
2832
2833
|
const [effort, setEffort] = (0, import_react2.useState)(() => savedFilters && savedFilters.effort || "");
|
|
2833
|
-
const [sessionId, setSessionId] = (0, import_react2.useState)(() => savedFilters && savedFilters.sessionId || "");
|
|
2834
|
+
const [sessionId, setSessionId] = (0, import_react2.useState)(() => navSession || savedFilters && savedFilters.sessionId || "");
|
|
2834
2835
|
const [dim, setDim] = (0, import_react2.useState)(() => savedFilters && savedFilters.dim || "");
|
|
2835
2836
|
const [sortKey, setSortKey] = (0, import_react2.useState)("time");
|
|
2836
2837
|
const [sortDir, setSortDir] = (0, import_react2.useState)("desc");
|
|
@@ -2859,6 +2860,7 @@ function TokenLogView(props) {
|
|
|
2859
2860
|
if (savedFilters.sessionId) q.sessionId = savedFilters.sessionId;
|
|
2860
2861
|
if (savedFilters.dim) q.dim = savedFilters.dim;
|
|
2861
2862
|
}
|
|
2863
|
+
if (navSession) q.sessionId = navSession;
|
|
2862
2864
|
rpcCall("scan", {}).then(() => cancel ? null : rpcCall("query", q)).then((d) => {
|
|
2863
2865
|
if (cancel) return;
|
|
2864
2866
|
setData(d);
|
|
@@ -2892,8 +2894,10 @@ function TokenLogView(props) {
|
|
|
2892
2894
|
setPage(0);
|
|
2893
2895
|
}).catch((e) => setErr(String(e && e.message || e))).finally(() => setLoading(false));
|
|
2894
2896
|
}, [buildQ]);
|
|
2897
|
+
const navAppliedRef = (0, import_react2.useRef)(navAt);
|
|
2895
2898
|
(0, import_react2.useEffect)(() => {
|
|
2896
|
-
if (!navSession) return;
|
|
2899
|
+
if (!navSession || navAppliedRef.current === navAt) return;
|
|
2900
|
+
navAppliedRef.current = navAt;
|
|
2897
2901
|
setSessionId(navSession);
|
|
2898
2902
|
setLoading(true);
|
|
2899
2903
|
setErr("");
|
|
@@ -2901,7 +2905,7 @@ function TokenLogView(props) {
|
|
|
2901
2905
|
setData(d);
|
|
2902
2906
|
setPage(0);
|
|
2903
2907
|
}).catch((e) => setErr(String(e && e.message || e))).finally(() => setLoading(false));
|
|
2904
|
-
}, [
|
|
2908
|
+
}, [navAt]);
|
|
2905
2909
|
const resetFilters = (0, import_react2.useCallback)(() => {
|
|
2906
2910
|
setFromStr("");
|
|
2907
2911
|
setToStr("");
|
|
@@ -3222,7 +3226,7 @@ function TokenLogChip(props) {
|
|
|
3222
3226
|
className: "dockchip" + (snap.err && !t ? " err" : ""),
|
|
3223
3227
|
title,
|
|
3224
3228
|
"aria-label": "\u4F1A\u8BDD\u7528\u91CF",
|
|
3225
|
-
onClick: () => openPanel("tokenlog", { sessionId: sid }),
|
|
3229
|
+
onClick: () => openPanel("tokenlog", { sessionId: sid, navAt: Date.now() }),
|
|
3226
3230
|
children: [
|
|
3227
3231
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "dockchip-dot", style: { background: "var(--dk-warn)" } }),
|
|
3228
3232
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: label })
|
|
@@ -10879,7 +10883,7 @@ var feature10 = {
|
|
|
10879
10883
|
};
|
|
10880
10884
|
|
|
10881
10885
|
// src/client.jsx
|
|
10882
|
-
var DOCK_VERSION = "0.11.
|
|
10886
|
+
var DOCK_VERSION = "0.11.2";
|
|
10883
10887
|
var BUILTIN_FEATURES = [feature, feature2, feature3, feature4, feature5, feature6, feature7, feature8, feature9, feature10];
|
|
10884
10888
|
var PLANNED_FEATURES = [];
|
|
10885
10889
|
var PLANNED_NOTES = {};
|
|
@@ -11039,11 +11043,14 @@ var SHELL_CSS = [
|
|
|
11039
11043
|
// 注意:旧上限 min(280px,36cqw) 仍偏宽——标准 780px 输入卡下(.row 内容约 762px),
|
|
11040
11044
|
// add 钮(28)+工作区选择器(~214)+chips(280) 已与右侧模型选择器+发送键(~345px)合计超宽,
|
|
11041
11045
|
// 即便 chips 未截断 .row 也会换行把模型选择器/发送键挤到第二行。实测把上限收到 189px
|
|
11042
|
-
// (≈25cqw)并使 chips 内距收紧(padding 2px 6px、gap 2px
|
|
11043
|
-
// 两 chip
|
|
11046
|
+
// (≈25cqw)并使 chips 内距收紧(padding 2px 6px、gap 2px)后,「4~6M 用量 + 余额」
|
|
11047
|
+
// 两 chip 可完整显示且不再换行。v0.11.2:配置单价后费用段「· ¥0.03」让两 chip 合计
|
|
11048
|
+
// 约需 204px,189px 恰好截掉约 2 个数字(费用/余额小数位看不到)——按用户反馈放宽到
|
|
11049
|
+
// 216px(≈28cqw),标准卡下实测完整显示;若再出现把模型选择器挤换行,优先压缩用量
|
|
11050
|
+
// chip 的 ⛁ 前缀换空间,别再收这个上限。超限仍省略号截断,完整值在 title 悬浮提示里。
|
|
11044
11051
|
// 2) 截断:超限部分用省略号截断(完整数值在 title 悬浮提示里),防 chips 凸出输入卡圆角(悬空)。
|
|
11045
|
-
".dockchip-row{display:inline-flex;align-items:center;gap:2px;min-width:0;flex:0 1 auto;overflow:hidden;max-width:
|
|
11046
|
-
"@supports (width:1cqw){.dockchip-row{max-width:min(
|
|
11052
|
+
".dockchip-row{display:inline-flex;align-items:center;gap:2px;min-width:0;flex:0 1 auto;overflow:hidden;max-width:216px;}",
|
|
11053
|
+
"@supports (width:1cqw){.dockchip-row{max-width:min(216px,28cqw);}}",
|
|
11047
11054
|
".dockchip{display:inline-flex;align-items:center;gap:5px;cursor:pointer;border:none;background:transparent;color:var(--dsw-alias-label-tertiary);border-radius:8px;padding:2px 6px;font-family:inherit;font-size:11px;line-height:18px;white-space:nowrap;min-width:0;overflow:hidden;transition:background .15s var(--ds-ease-in-out),color .15s var(--ds-ease-in-out);}",
|
|
11048
11055
|
".dockchip > span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;}",
|
|
11049
11056
|
".dockchip:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);}",
|
|
@@ -531,8 +531,10 @@ function PricingEditor({ onClose, onSaved, embedded }) {
|
|
|
531
531
|
|
|
532
532
|
// ---------- 主视图(嵌入 dock 面板内容区) ----------
|
|
533
533
|
export function TokenLogView(props) {
|
|
534
|
-
// props.params.sessionId(chips
|
|
534
|
+
// props.params.sessionId(chips 点击带入):立即按该会话筛选并查询。
|
|
535
|
+
// navAt:每次 chip 点击的时间戳——面板已打开时再次点击(即便同一会话)也触发重查。
|
|
535
536
|
const navSession = props && props.params && props.params.sessionId ? props.params.sessionId : null;
|
|
537
|
+
const navAt = props && props.params && props.params.navAt ? props.params.navAt : 0;
|
|
536
538
|
// 挂载即视为「打开」:恢复上次暂存的条件(时间不选=显示全部记录); savedFilters 稳定快照, 仅初始化时读取一次
|
|
537
539
|
const [savedFilters] = useState(loadSavedFilters);
|
|
538
540
|
const [fromStr, setFromStr] = useState(() => (savedFilters && savedFilters.fromStr) || "");
|
|
@@ -541,7 +543,8 @@ export function TokenLogView(props) {
|
|
|
541
543
|
const [model, setModel] = useState(() => (savedFilters && savedFilters.model) || "");
|
|
542
544
|
const [status, setStatus] = useState(() => (savedFilters && savedFilters.status) || "");
|
|
543
545
|
const [effort, setEffort] = useState(() => (savedFilters && savedFilters.effort) || "");
|
|
544
|
-
|
|
546
|
+
// 会话入口(chip/深链)带入的 sessionId 优先于暂存条件:下拉框初值即选中该会话
|
|
547
|
+
const [sessionId, setSessionId] = useState(() => navSession || (savedFilters && savedFilters.sessionId) || "");
|
|
545
548
|
const [dim, setDim] = useState(() => (savedFilters && savedFilters.dim) || "");
|
|
546
549
|
const [sortKey, setSortKey] = useState("time");
|
|
547
550
|
const [sortDir, setSortDir] = useState("desc");
|
|
@@ -575,6 +578,9 @@ export function TokenLogView(props) {
|
|
|
575
578
|
if (savedFilters.sessionId) q.sessionId = savedFilters.sessionId;
|
|
576
579
|
if (savedFilters.dim) q.dim = savedFilters.dim;
|
|
577
580
|
}
|
|
581
|
+
// 从会话入口点入时按带入的会话查(优先于暂存条件):打开即出当前会话结果,
|
|
582
|
+
// 不再需要手动点「查询」。只保留这一条初始查询,避免并发的会话查询被本链路覆盖。
|
|
583
|
+
if (navSession) q.sessionId = navSession;
|
|
578
584
|
rpcCall("scan", {})
|
|
579
585
|
.then(() => (cancel ? null : rpcCall("query", q)))
|
|
580
586
|
.then((d) => {
|
|
@@ -609,16 +615,20 @@ export function TokenLogView(props) {
|
|
|
609
615
|
.finally(() => setLoading(false));
|
|
610
616
|
}, [buildQ]);
|
|
611
617
|
|
|
612
|
-
// chips
|
|
618
|
+
// chips 定位:面板已打开时再次从会话入口点击 → 立即按该会话筛选查询。
|
|
619
|
+
// 挂载时的首次带入已并入初始查询(sessionId 初值 + 挂载 effect),以 navAt 判同跳过,
|
|
620
|
+
// 避免打开面板时同一条件跑两遍、且挂载查询链路较慢把会话结果覆盖回全量。
|
|
621
|
+
const navAppliedRef = useRef(navAt);
|
|
613
622
|
useEffect(() => {
|
|
614
|
-
if (!navSession) return;
|
|
623
|
+
if (!navSession || navAppliedRef.current === navAt) return;
|
|
624
|
+
navAppliedRef.current = navAt;
|
|
615
625
|
setSessionId(navSession);
|
|
616
626
|
setLoading(true); setErr("");
|
|
617
627
|
rpcCall("query", Object.assign({}, buildQ(true), { sessionId: navSession }))
|
|
618
628
|
.then((d) => { setData(d); setPage(0); })
|
|
619
629
|
.catch((e) => setErr(String((e && e.message) || e)))
|
|
620
630
|
.finally(() => setLoading(false));
|
|
621
|
-
}, [
|
|
631
|
+
}, [navAt]);
|
|
622
632
|
|
|
623
633
|
// 重置: 清空所有筛选(时间不选=显示全部记录), 并立即查询
|
|
624
634
|
const resetFilters = useCallback(() => { setFromStr(""); setToStr("");
|
|
@@ -902,7 +912,7 @@ export function TokenLogChip(props) {
|
|
|
902
912
|
: (snap.err ? snap.err + "\n" : "") + "点击在功能坞查看用量记录";
|
|
903
913
|
return (
|
|
904
914
|
<button type="button" className={"dockchip" + (snap.err && !t ? " err" : "")} title={title} aria-label="会话用量"
|
|
905
|
-
onClick={() => openPanel("tokenlog", { sessionId: sid })}>
|
|
915
|
+
onClick={() => openPanel("tokenlog", { sessionId: sid, navAt: Date.now() })}>
|
|
906
916
|
<span className="dockchip-dot" style={{ background: "var(--dk-warn)" }} />
|
|
907
917
|
<span>{label}</span>
|
|
908
918
|
</button>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dsh-dock",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.2",
|
|
4
4
|
"description": "DeepSeek Harness 功能坞插件(dsh-dock):模块化功能中枢——每个功能一个 features/ 模块(可单独提取成包发布,又可经 dockBridge 装回面板)。含用量记录(LLM 调用记账/费用统计,支持各模型自定义单价与多段分时价)、模型设置、图片理解代理、模型余额、任务动画(19 种运行动画 + 桌面伙伴 3D 场景)、任务通知(完成/异常/需确认通知、提示音、系统通知、钉钉/飞书推送)、运行状态(进行中任务与最近完成一览);侧栏入口 + 可拖拽弹窗(最大化/最小化/缩放)。",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
package/src/client.jsx
CHANGED
|
@@ -30,7 +30,7 @@ import { feature as fGames } from "../features/games/view.jsx";
|
|
|
30
30
|
import { feature as fMobileRelay } from "../features/mobile-relay/view.jsx";
|
|
31
31
|
|
|
32
32
|
const name = "dsh-dock";
|
|
33
|
-
const DOCK_VERSION = "0.11.
|
|
33
|
+
const DOCK_VERSION = "0.11.2";
|
|
34
34
|
|
|
35
35
|
// ---- 内置功能注册表:新功能 = features/<id>/ 加模块 + 这里 import 一行 ----
|
|
36
36
|
const BUILTIN_FEATURES = [fTokenlog, fModelconfig, fHeartbeat, fTheme, fBalance, fAnimation, fNotify, fRunState, fGames, fMobileRelay];
|
|
@@ -206,11 +206,14 @@ const SHELL_CSS = [
|
|
|
206
206
|
// 注意:旧上限 min(280px,36cqw) 仍偏宽——标准 780px 输入卡下(.row 内容约 762px),
|
|
207
207
|
// add 钮(28)+工作区选择器(~214)+chips(280) 已与右侧模型选择器+发送键(~345px)合计超宽,
|
|
208
208
|
// 即便 chips 未截断 .row 也会换行把模型选择器/发送键挤到第二行。实测把上限收到 189px
|
|
209
|
-
// (≈25cqw)并使 chips 内距收紧(padding 2px 6px、gap 2px
|
|
210
|
-
// 两 chip
|
|
209
|
+
// (≈25cqw)并使 chips 内距收紧(padding 2px 6px、gap 2px)后,「4~6M 用量 + 余额」
|
|
210
|
+
// 两 chip 可完整显示且不再换行。v0.11.2:配置单价后费用段「· ¥0.03」让两 chip 合计
|
|
211
|
+
// 约需 204px,189px 恰好截掉约 2 个数字(费用/余额小数位看不到)——按用户反馈放宽到
|
|
212
|
+
// 216px(≈28cqw),标准卡下实测完整显示;若再出现把模型选择器挤换行,优先压缩用量
|
|
213
|
+
// chip 的 ⛁ 前缀换空间,别再收这个上限。超限仍省略号截断,完整值在 title 悬浮提示里。
|
|
211
214
|
// 2) 截断:超限部分用省略号截断(完整数值在 title 悬浮提示里),防 chips 凸出输入卡圆角(悬空)。
|
|
212
|
-
".dockchip-row{display:inline-flex;align-items:center;gap:2px;min-width:0;flex:0 1 auto;overflow:hidden;max-width:
|
|
213
|
-
"@supports (width:1cqw){.dockchip-row{max-width:min(
|
|
215
|
+
".dockchip-row{display:inline-flex;align-items:center;gap:2px;min-width:0;flex:0 1 auto;overflow:hidden;max-width:216px;}",
|
|
216
|
+
"@supports (width:1cqw){.dockchip-row{max-width:min(216px,28cqw);}}",
|
|
214
217
|
".dockchip{display:inline-flex;align-items:center;gap:5px;cursor:pointer;border:none;background:transparent;color:var(--dsw-alias-label-tertiary);border-radius:8px;padding:2px 6px;font-family:inherit;font-size:11px;line-height:18px;white-space:nowrap;min-width:0;overflow:hidden;transition:background .15s var(--ds-ease-in-out),color .15s var(--ds-ease-in-out);}",
|
|
215
218
|
".dockchip > span{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;min-width:0;}",
|
|
216
219
|
".dockchip:hover{background:var(--dsw-alias-interactive-bg-hover);color:var(--dsw-alias-label-primary);}",
|