dsh-llm-codebuddy-power 1.2.0 → 1.3.0
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 +4 -5
- package/README.zh.md +4 -5
- package/lib/cli-login.js +110 -107
- package/lib/client.js +127 -144
- package/lib/index.js +121 -104
- package/lib/types/auth-service.d.ts +11 -12
- package/lib/types/cli/login.d.ts +1 -2
- package/lib/types/client/AccountSwitcher.d.ts +1 -2
- package/lib/types/client/CodeBuddySection.d.ts +3 -5
- package/lib/types/client/TurnCreditPill.d.ts +5 -4
- package/lib/types/client/index.d.ts +1 -1
- package/lib/types/client/locales.d.ts +5 -3
- package/lib/types/client/store.d.ts +3 -5
- package/lib/types/client/wire.d.ts +2 -2
- package/lib/types/constants.d.ts +7 -0
- package/lib/types/index.d.ts +1 -1
- package/lib/types/session-store.d.ts +1 -1
- package/lib/types/session.d.ts +57 -27
- package/lib/types/storage.d.ts +4 -11
- package/lib/types/usage.d.ts +4 -2
- package/package.json +15 -15
package/lib/client.js
CHANGED
|
@@ -20,7 +20,7 @@ window.__ModuleLoader__.load({
|
|
|
20
20
|
};
|
|
21
21
|
//#endregion
|
|
22
22
|
//#region \0dsh-css:D:\data\code\deepseek-harness\packages\my\dsh-llm-codebuddy-power\src\client\CodeBuddySection.module.css.mjs
|
|
23
|
-
const css$4 = ".-h11cq_section{flex-direction:column;gap:12px;padding:8px 0;display:flex}.-h11cq_title{color:var(--dsw-alias-label-primary);margin:0;font-size:18px;font-weight:600}.-h11cq_desc{color:var(--dsw-alias-label-secondary);margin:0;font-size:14px;line-height:22px}.-h11cq_muted{color:var(--dsw-alias-label-secondary);margin:0;font-size:14px}.-h11cq_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:14px}.-h11cq_accountHeader{border-bottom:1px solid var(--dsw-alias-border-l2);flex-wrap:wrap;justify-content:flex-start;align-items:center;gap:8px;padding-bottom:8px;display:flex}.-h11cq_splitButton{align-items:center;display:inline-flex}.-h11cq_splitMain{box-shadow:inset -1px 0 0 var(--dsw-alias-border-l3);border-right-width:0;border-top-right-radius:0;border-bottom-right-radius:0}.-h11cq_splitActionAnchor{display:inline-flex}.-h11cq_splitAction{border-top-left-radius:0;border-bottom-left-radius:0;padding:0 10px}.-h11cq_splitMain:focus-visible,.-h11cq_splitAction:focus-visible{outline-offset:-2px}.-h11cq_badges{flex-wrap:wrap;gap:8px;display:flex}.-h11cq_badge{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:16px;align-items:center;gap:6px;max-width:100%;min-height:32px;padding:0 4px 0 0;display:flex}.-
|
|
23
|
+
const css$4 = ".-h11cq_section{flex-direction:column;gap:12px;padding:8px 0;display:flex}.-h11cq_title{color:var(--dsw-alias-label-primary);margin:0;font-size:18px;font-weight:600}.-h11cq_desc{color:var(--dsw-alias-label-secondary);margin:0;font-size:14px;line-height:22px}.-h11cq_muted{color:var(--dsw-alias-label-secondary);margin:0;font-size:14px}.-h11cq_error{color:var(--dsw-alias-state-error-primary);margin:0;font-size:14px}.-h11cq_accountHeader{border-bottom:1px solid var(--dsw-alias-border-l2);flex-wrap:wrap;justify-content:flex-start;align-items:center;gap:8px;padding-bottom:8px;display:flex}.-h11cq_splitButton{align-items:center;display:inline-flex}.-h11cq_splitMain{box-shadow:inset -1px 0 0 var(--dsw-alias-border-l3);border-right-width:0;border-top-right-radius:0;border-bottom-right-radius:0}.-h11cq_splitActionAnchor{display:inline-flex}.-h11cq_splitAction{border-top-left-radius:0;border-bottom-left-radius:0;padding:0 10px}.-h11cq_splitMain:focus-visible,.-h11cq_splitAction:focus-visible{outline-offset:-2px}.-h11cq_badges{flex-wrap:wrap;gap:8px;display:flex}.-h11cq_badge{box-sizing:border-box;border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);border-radius:16px;align-items:center;gap:6px;max-width:100%;min-height:32px;padding:0 4px 0 0;display:flex}.-h11cq_badgeInfo{align-self:stretch;align-items:center;min-width:0;padding-left:12px;display:flex}.-h11cq_badgeDragging{opacity:.4}.-h11cq_badgeDropBefore,.-h11cq_badgeDropAfter{position:relative}.-h11cq_badgeDropBefore:before,.-h11cq_badgeDropAfter:after{content:\"\";z-index:1;background:var(--dsw-alias-brand-primary);pointer-events:none;border-radius:1px;width:2px;position:absolute;top:0;bottom:0}.-h11cq_badgeDropBefore:before{left:-5px}.-h11cq_badgeDropAfter:after{right:-5px}.-h11cq_badgeInfoText{color:var(--dsw-alias-label-primary);text-overflow:ellipsis;white-space:nowrap;max-width:180px;font-size:13px;line-height:20px;overflow:hidden}.-h11cq_badge:not(:has(.-h11cq_badgeCheck)) .-h11cq_badgeInfo{padding-right:8px}.-h11cq_badgeActionAnchor{flex:none;display:inline-flex}.-h11cq_badgeAction{width:24px;height:24px;color:var(--dsw-alias-label-secondary);cursor:pointer;background:0 0;border:0;border-radius:12px;justify-content:center;align-items:center;padding:0;display:inline-flex}.-h11cq_badgeAction:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover-danger);color:var(--dsw-alias-state-error-primary)}.-h11cq_badgeAction:disabled{cursor:default;opacity:.4}.-h11cq_badgeAction:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}.-h11cq_badgeCheck{border:1px solid var(--dsw-alias-border-l3);width:20px;height:20px;color:var(--dsw-alias-label-primary-foreground);cursor:pointer;background:0 0;border-radius:6px;flex:none;justify-content:center;align-items:center;padding:0;display:inline-flex}.-h11cq_badgeCheckOn{border-color:var(--dsw-alias-brand-primary);background:var(--dsw-alias-brand-primary)}.-h11cq_badgeCheck:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.-h11cq_divider{background:var(--dsw-alias-border-l2);height:1px}.-h11cq_prefRow{border-bottom:1px solid var(--dsw-alias-border-l2);align-items:center;gap:8px;padding:8px 0;display:flex}.-h11cq_prefRowText{flex-direction:column;flex:1;gap:4px;min-width:0;padding-right:48px;display:flex}.-h11cq_prefTitle{color:var(--dsw-alias-label-primary);font-size:14px;font-weight:400;line-height:22px}.-h11cq_prefDesc{color:var(--dsw-alias-label-secondary);font-size:12px;font-weight:400;line-height:18px}.-h11cq_switch{box-sizing:border-box;background:var(--dsw-alias-border-l3);cursor:pointer;border:0;border-radius:10px;flex:none;width:36px;height:20px;padding:2px;position:relative}.-h11cq_switchOn{background:var(--dsw-alias-brand-primary)}.-h11cq_switch:disabled{cursor:default;opacity:.5}.-h11cq_switch:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}.-h11cq_thumb{corner-shape:round;background:var(--dsw-alias-label-primary-foreground);border-radius:50%;width:16px;height:16px;transition:transform .12s;display:block}.-h11cq_switchOn .-h11cq_thumb{transform:translate(16px)}.-h11cq_prefInput{width:120px}";
|
|
24
24
|
const tagId$4 = "dsh-llm-codebuddy-power/CodeBuddySection.module.css";
|
|
25
25
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$4) + "]") === null) {
|
|
26
26
|
const tag = document.createElement("style");
|
|
@@ -36,7 +36,6 @@ window.__ModuleLoader__.load({
|
|
|
36
36
|
"badgeActionAnchor": "-h11cq_badgeActionAnchor",
|
|
37
37
|
"badgeCheck": "-h11cq_badgeCheck",
|
|
38
38
|
"badgeCheckOn": "-h11cq_badgeCheckOn",
|
|
39
|
-
"badgeDefaultTag": "-h11cq_badgeDefaultTag",
|
|
40
39
|
"badgeDragging": "-h11cq_badgeDragging",
|
|
41
40
|
"badgeDropAfter": "-h11cq_badgeDropAfter",
|
|
42
41
|
"badgeDropBefore": "-h11cq_badgeDropBefore",
|
|
@@ -68,7 +67,7 @@ window.__ModuleLoader__.load({
|
|
|
68
67
|
* CodeBuddy 设置分区:多账号登录页。
|
|
69
68
|
*
|
|
70
69
|
* 展示全部已登录账号(每个账号一个徽章),在此发起浏览器登录以**追加**账号、
|
|
71
|
-
*
|
|
70
|
+
* 退出单个或选中的多个账号、拖拽排序;下方是两种登录状态下都渲染的
|
|
72
71
|
* 界面偏好行。退出是破坏性操作(会删除磁盘上的凭据),因此单个与批量都先弹确认框。
|
|
73
72
|
* 弹窗可见性由 shell 拥有,故此处不需要关闭控件。
|
|
74
73
|
*/
|
|
@@ -77,7 +76,7 @@ window.__ModuleLoader__.load({
|
|
|
77
76
|
/** 客户端等待登录完成的时长(毫秒),与宿主的 `LOGIN_TIMEOUT_MS` 对齐。 */
|
|
78
77
|
const POLL_DEADLINE_MS = 600 * 1e3;
|
|
79
78
|
/** 复制成功后图标保持对勾的时长(毫秒)。 */
|
|
80
|
-
const COPIED_FEEDBACK_MS = 1e3;
|
|
79
|
+
const COPIED_FEEDBACK_MS$1 = 1e3;
|
|
81
80
|
/**
|
|
82
81
|
* 解码 CodeBuddy 的 `departmentFullName`,它是 base64 编码的 UTF-8。
|
|
83
82
|
* 不是合法 base64 时回退为原始值。
|
|
@@ -121,24 +120,21 @@ window.__ModuleLoader__.load({
|
|
|
121
120
|
return e.clientX < rect.left + rect.width / 2 ? "before" : "after";
|
|
122
121
|
}
|
|
123
122
|
/**
|
|
124
|
-
* 一个账号徽章:整块信息区(昵称及其内边距)
|
|
123
|
+
* 一个账号徽章:整块信息区(昵称及其内边距)悬停看明细。
|
|
125
124
|
*
|
|
126
125
|
* 提示挂在整块信息区而不是只挂在昵称文字上:昵称常常很短,能触发提示的只有那几个
|
|
127
126
|
* 字;把锚点扩到这块区域的整个高度与左侧留白,徽章上除功能按钮外的地方都能唤起它。
|
|
128
127
|
* 不用"Tooltip 包住整个徽章、按钮上禁用"的写法 —— `Tooltip` 的 `disabled` 会直接
|
|
129
128
|
* 清空它的悬停/聚焦状态,从昵称移到按钮再移回来时提示不会再出现。
|
|
130
129
|
*
|
|
131
|
-
*
|
|
132
|
-
* "这是哪个账号、它是不是默认的"。唯一可点的例外是那个「默认」标记 —— 它标出默认
|
|
133
|
-
* 账号,自己也就是取消默认的入口。
|
|
130
|
+
* 徽章本身不承担任何管理动作:退出与排序都在顶部操作区,徽章只回答"这是哪个账号"。
|
|
134
131
|
*/
|
|
135
132
|
function AccountBadge(props) {
|
|
136
|
-
const { account,
|
|
133
|
+
const { account, multiSelect, checked, t, onToggleChecked, drag } = props;
|
|
137
134
|
const dragging = drag?.dragging ? ` ${CodeBuddySection_module_css_default.badgeDragging}` : "";
|
|
138
135
|
const marker = drag?.marker === "before" ? ` ${CodeBuddySection_module_css_default.badgeDropBefore}` : drag?.marker === "after" ? ` ${CodeBuddySection_module_css_default.badgeDropAfter}` : "";
|
|
139
136
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
140
137
|
className: `${CodeBuddySection_module_css_default.badge}${dragging}${marker}`,
|
|
141
|
-
"data-default": isDefault ? "" : void 0,
|
|
142
138
|
draggable: drag !== void 0,
|
|
143
139
|
onDragStart: drag === void 0 ? void 0 : (e) => {
|
|
144
140
|
e.dataTransfer.effectAllowed = "move";
|
|
@@ -155,43 +151,27 @@ window.__ModuleLoader__.load({
|
|
|
155
151
|
e.preventDefault();
|
|
156
152
|
drag.drop(badgeHalf(e));
|
|
157
153
|
},
|
|
158
|
-
children: [
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
154
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
155
|
+
label: accountDetail(account, t),
|
|
156
|
+
side: "top",
|
|
157
|
+
delayMs: 300,
|
|
158
|
+
maxWidth: 320,
|
|
159
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
160
|
+
className: CodeBuddySection_module_css_default.badgeInfo,
|
|
164
161
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
165
|
-
className: CodeBuddySection_module_css_default.
|
|
166
|
-
children:
|
|
167
|
-
className: CodeBuddySection_module_css_default.badgeInfoText,
|
|
168
|
-
children: account.nickname
|
|
169
|
-
})
|
|
162
|
+
className: CodeBuddySection_module_css_default.badgeInfoText,
|
|
163
|
+
children: account.nickname
|
|
170
164
|
})
|
|
171
|
-
}),
|
|
172
|
-
isDefault && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
173
|
-
label: t("clearDefault"),
|
|
174
|
-
side: "top",
|
|
175
|
-
delayMs: 300,
|
|
176
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
177
|
-
type: "button",
|
|
178
|
-
className: CodeBuddySection_module_css_default.badgeDefaultTag,
|
|
179
|
-
"aria-pressed": true,
|
|
180
|
-
"aria-label": `${t("clearDefault")}: ${account.nickname}`,
|
|
181
|
-
onClick: onClearDefault,
|
|
182
|
-
children: t("defaultTag")
|
|
183
|
-
})
|
|
184
|
-
}),
|
|
185
|
-
multiSelect && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
186
|
-
type: "button",
|
|
187
|
-
role: "checkbox",
|
|
188
|
-
"aria-checked": checked,
|
|
189
|
-
"aria-label": `${t("selectAccount")}: ${account.nickname}`,
|
|
190
|
-
className: `${CodeBuddySection_module_css_default.badgeCheck} ${checked ? CodeBuddySection_module_css_default.badgeCheckOn : ""}`,
|
|
191
|
-
onClick: onToggleChecked,
|
|
192
|
-
children: checked && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutlineRegular, { size: 14 })
|
|
193
165
|
})
|
|
194
|
-
|
|
166
|
+
}), multiSelect && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
167
|
+
type: "button",
|
|
168
|
+
role: "checkbox",
|
|
169
|
+
"aria-checked": checked,
|
|
170
|
+
"aria-label": `${t("selectAccount")}: ${account.nickname}`,
|
|
171
|
+
className: `${CodeBuddySection_module_css_default.badgeCheck} ${checked ? CodeBuddySection_module_css_default.badgeCheckOn : ""}`,
|
|
172
|
+
onClick: onToggleChecked,
|
|
173
|
+
children: checked && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.IconCheckOutlineRegular, { size: 14 })
|
|
174
|
+
})]
|
|
195
175
|
});
|
|
196
176
|
}
|
|
197
177
|
/**
|
|
@@ -200,11 +180,10 @@ window.__ModuleLoader__.load({
|
|
|
200
180
|
* @returns 分区的元素树。
|
|
201
181
|
*/
|
|
202
182
|
function CodeBuddySection(props) {
|
|
203
|
-
const { t, useStore, usePrefs, refreshAccounts, startLogin, resumeLogin, copyLoginLink, cancelLogin, pollLogin, logoutAccounts, reorderAccounts,
|
|
183
|
+
const { t, useStore, usePrefs, refreshAccounts, startLogin, resumeLogin, copyLoginLink, cancelLogin, pollLogin, logoutAccounts, reorderAccounts, setPref, actions } = props;
|
|
204
184
|
const phase = useStore((s) => s.phase);
|
|
205
185
|
const error = useStore((s) => s.error);
|
|
206
186
|
const accounts = useStore((s) => s.accounts);
|
|
207
|
-
const defaultUid = useStore((s) => s.defaultUid);
|
|
208
187
|
const loginState = useStore((s) => s.loginState);
|
|
209
188
|
const prefs = usePrefs((value) => value);
|
|
210
189
|
const [dangerText, setDangerText] = (0, react.useState)(() => String(prefs.dangerPct));
|
|
@@ -301,13 +280,9 @@ window.__ModuleLoader__.load({
|
|
|
301
280
|
copiedTimer.current = window.setTimeout(() => {
|
|
302
281
|
copiedTimer.current = void 0;
|
|
303
282
|
setCopied(false);
|
|
304
|
-
}, COPIED_FEEDBACK_MS);
|
|
283
|
+
}, COPIED_FEEDBACK_MS$1);
|
|
305
284
|
});
|
|
306
285
|
}, [copied, copyLoginLink]);
|
|
307
|
-
const [defaultMenuOpen, setDefaultMenuOpen] = (0, react.useState)(false);
|
|
308
|
-
const onClearDefault = (0, react.useCallback)(() => {
|
|
309
|
-
setDefault(null);
|
|
310
|
-
}, [setDefault]);
|
|
311
286
|
const onToggleChecked = (0, react.useCallback)((uid) => {
|
|
312
287
|
setChecked((current) => current.includes(uid) ? current.filter((item) => item !== uid) : [...current, uid]);
|
|
313
288
|
}, []);
|
|
@@ -351,10 +326,6 @@ window.__ModuleLoader__.load({
|
|
|
351
326
|
})
|
|
352
327
|
});
|
|
353
328
|
const pendingCount = pendingLogout?.length ?? 0;
|
|
354
|
-
const defaultItems = accounts.map((account) => ({
|
|
355
|
-
id: account.uid,
|
|
356
|
-
label: account.nickname
|
|
357
|
-
}));
|
|
358
329
|
if (props.view === "summary") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(react_jsx_runtime.Fragment, { children: t("intro") });
|
|
359
330
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
360
331
|
className: CodeBuddySection_module_css_default.section,
|
|
@@ -400,31 +371,6 @@ window.__ModuleLoader__.load({
|
|
|
400
371
|
})
|
|
401
372
|
})]
|
|
402
373
|
}),
|
|
403
|
-
accounts.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Menu, {
|
|
404
|
-
open: defaultMenuOpen,
|
|
405
|
-
portal: true,
|
|
406
|
-
align: "start",
|
|
407
|
-
selectedId: defaultUid ?? void 0,
|
|
408
|
-
items: defaultItems,
|
|
409
|
-
onClose: () => {
|
|
410
|
-
setDefaultMenuOpen(false);
|
|
411
|
-
},
|
|
412
|
-
onSelect: (uid) => {
|
|
413
|
-
setDefaultMenuOpen(false);
|
|
414
|
-
if (uid === defaultUid) return;
|
|
415
|
-
setDefault(uid);
|
|
416
|
-
},
|
|
417
|
-
anchor: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
418
|
-
variant: "outline",
|
|
419
|
-
size: "md",
|
|
420
|
-
"aria-haspopup": "menu",
|
|
421
|
-
"aria-expanded": defaultMenuOpen,
|
|
422
|
-
onClick: () => {
|
|
423
|
-
setDefaultMenuOpen((current) => !current);
|
|
424
|
-
},
|
|
425
|
-
children: t("chooseDefault")
|
|
426
|
-
})
|
|
427
|
-
}),
|
|
428
374
|
accounts.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
429
375
|
variant: "outline",
|
|
430
376
|
size: "md",
|
|
@@ -462,11 +408,9 @@ window.__ModuleLoader__.load({
|
|
|
462
408
|
className: CodeBuddySection_module_css_default.badges,
|
|
463
409
|
children: accounts.map((account) => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(AccountBadge, {
|
|
464
410
|
account,
|
|
465
|
-
isDefault: account.uid === defaultUid,
|
|
466
411
|
multiSelect,
|
|
467
412
|
checked: checked.includes(account.uid),
|
|
468
413
|
t,
|
|
469
|
-
onClearDefault,
|
|
470
414
|
onToggleChecked: () => {
|
|
471
415
|
onToggleChecked(account.uid);
|
|
472
416
|
},
|
|
@@ -528,6 +472,9 @@ window.__ModuleLoader__.load({
|
|
|
528
472
|
* 三行界面偏好,单独抽出以便与账号区解耦 —— 它们与登录状态无关。两个布尔行是
|
|
529
473
|
* 开关按钮(role="switch")而非下拉框:开关一次点击即可翻转,与文件浏览器的
|
|
530
474
|
* 显示隐藏开关一致。
|
|
475
|
+
*
|
|
476
|
+
* 两个用量项相邻:余量告警百分比只对圆环的填充色起作用,把它隔在画图工具之后会让
|
|
477
|
+
* "圆环显示不显示"与"圆环几时变红"分成两处去找。
|
|
531
478
|
*/
|
|
532
479
|
function UsagePrefRows(props) {
|
|
533
480
|
const { t, prefs, dangerText, setDangerText, setPref } = props;
|
|
@@ -555,29 +502,6 @@ window.__ModuleLoader__.load({
|
|
|
555
502
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: CodeBuddySection_module_css_default.thumb })
|
|
556
503
|
})]
|
|
557
504
|
}),
|
|
558
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
559
|
-
className: CodeBuddySection_module_css_default.prefRow,
|
|
560
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
561
|
-
className: CodeBuddySection_module_css_default.prefRowText,
|
|
562
|
-
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
563
|
-
className: CodeBuddySection_module_css_default.prefTitle,
|
|
564
|
-
children: t("drawToolMinimal")
|
|
565
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
566
|
-
className: CodeBuddySection_module_css_default.prefDesc,
|
|
567
|
-
children: t("drawToolMinimalDesc")
|
|
568
|
-
})]
|
|
569
|
-
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
570
|
-
type: "button",
|
|
571
|
-
role: "switch",
|
|
572
|
-
"aria-checked": prefs.drawToolInMinimal,
|
|
573
|
-
"aria-label": t("drawToolMinimal"),
|
|
574
|
-
className: `${CodeBuddySection_module_css_default.switch} ${prefs.drawToolInMinimal ? CodeBuddySection_module_css_default.switchOn : ""}`,
|
|
575
|
-
onClick: () => {
|
|
576
|
-
setPref("drawToolInMinimal", !prefs.drawToolInMinimal);
|
|
577
|
-
},
|
|
578
|
-
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: CodeBuddySection_module_css_default.thumb })
|
|
579
|
-
})]
|
|
580
|
-
}),
|
|
581
505
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
582
506
|
className: CodeBuddySection_module_css_default.prefRow,
|
|
583
507
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -608,12 +532,35 @@ window.__ModuleLoader__.load({
|
|
|
608
532
|
setPref("dangerPct", next);
|
|
609
533
|
}
|
|
610
534
|
})]
|
|
535
|
+
}),
|
|
536
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
537
|
+
className: CodeBuddySection_module_css_default.prefRow,
|
|
538
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
539
|
+
className: CodeBuddySection_module_css_default.prefRowText,
|
|
540
|
+
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
541
|
+
className: CodeBuddySection_module_css_default.prefTitle,
|
|
542
|
+
children: t("drawToolMinimal")
|
|
543
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
544
|
+
className: CodeBuddySection_module_css_default.prefDesc,
|
|
545
|
+
children: t("drawToolMinimalDesc")
|
|
546
|
+
})]
|
|
547
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
548
|
+
type: "button",
|
|
549
|
+
role: "switch",
|
|
550
|
+
"aria-checked": prefs.drawToolInMinimal,
|
|
551
|
+
"aria-label": t("drawToolMinimal"),
|
|
552
|
+
className: `${CodeBuddySection_module_css_default.switch} ${prefs.drawToolInMinimal ? CodeBuddySection_module_css_default.switchOn : ""}`,
|
|
553
|
+
onClick: () => {
|
|
554
|
+
setPref("drawToolInMinimal", !prefs.drawToolInMinimal);
|
|
555
|
+
},
|
|
556
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: CodeBuddySection_module_css_default.thumb })
|
|
557
|
+
})]
|
|
611
558
|
})
|
|
612
559
|
] });
|
|
613
560
|
}
|
|
614
561
|
//#endregion
|
|
615
562
|
//#region \0dsh-css:D:\data\code\deepseek-harness\packages\my\dsh-llm-codebuddy-power\src\client\AccountSwitcher.module.css.mjs
|
|
616
|
-
const css$3 = "._7gEqNa_root{flex:none;align-items:center;gap:4px;display:inline-flex}._7gEqNa_ringAnchor{align-items:center;display:inline-flex}._7gEqNa_trigger{box-sizing:border-box;min-width:calc(28px + var(--dsh-content-font-delta,0px));height:calc(28px + var(--dsh-content-font-delta,0px));max-width:96px;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;cursor:pointer;background:0 0;border:0;border-radius:6px;justify-content:center;align-items:center;padding:0 6px;font-size:12px;line-height:1;display:inline-flex;overflow:hidden}._7gEqNa_trigger:hover{background:var(--dsw-alias-interactive-bg-hover)}._7gEqNa_trigger:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}
|
|
563
|
+
const css$3 = "._7gEqNa_root{flex:none;align-items:center;gap:4px;display:inline-flex}._7gEqNa_ringAnchor{align-items:center;display:inline-flex}._7gEqNa_trigger{box-sizing:border-box;min-width:calc(28px + var(--dsh-content-font-delta,0px));height:calc(28px + var(--dsh-content-font-delta,0px));max-width:96px;color:var(--dsw-alias-label-secondary);white-space:nowrap;text-overflow:ellipsis;cursor:pointer;background:0 0;border:0;border-radius:6px;justify-content:center;align-items:center;padding:0 6px;font-size:12px;line-height:1;display:inline-flex;overflow:hidden}._7gEqNa_trigger:hover{background:var(--dsw-alias-interactive-bg-hover)}._7gEqNa_trigger:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:1px}";
|
|
617
564
|
const tagId$3 = "dsh-llm-codebuddy-power/AccountSwitcher.module.css";
|
|
618
565
|
if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId$3) + "]") === null) {
|
|
619
566
|
const tag = document.createElement("style");
|
|
@@ -623,7 +570,6 @@ window.__ModuleLoader__.load({
|
|
|
623
570
|
document.head.appendChild(tag);
|
|
624
571
|
}
|
|
625
572
|
var AccountSwitcher_module_css_default = {
|
|
626
|
-
"menuDefault": "_7gEqNa_menuDefault",
|
|
627
573
|
"ringAnchor": "_7gEqNa_ringAnchor",
|
|
628
574
|
"root": "_7gEqNa_root",
|
|
629
575
|
"trigger": "_7gEqNa_trigger"
|
|
@@ -752,7 +698,6 @@ window.__ModuleLoader__.load({
|
|
|
752
698
|
function AccountSwitcher(props) {
|
|
753
699
|
const { t, usePrefs, fetchAccounts, fetchSessionAccount, activate, fetchUsage } = props;
|
|
754
700
|
const [accounts, setAccounts] = (0, react.useState)([]);
|
|
755
|
-
const [defaultUid, setDefaultUid] = (0, react.useState)(null);
|
|
756
701
|
const prefs = usePrefs((value) => value);
|
|
757
702
|
/** 该会话此刻生效的账号 uid;未读到时为 null。 */
|
|
758
703
|
const [activeUid, setActiveUid] = (0, react.useState)(null);
|
|
@@ -775,7 +720,6 @@ window.__ModuleLoader__.load({
|
|
|
775
720
|
fetchAccounts().then((value) => {
|
|
776
721
|
if (stopped || value === null) return;
|
|
777
722
|
setAccounts(value.accounts);
|
|
778
|
-
setDefaultUid(value.defaultUid);
|
|
779
723
|
});
|
|
780
724
|
fetchSessionAccount().then((uid) => {
|
|
781
725
|
if (!stopped) setActiveUid(uid);
|
|
@@ -799,7 +743,7 @@ window.__ModuleLoader__.load({
|
|
|
799
743
|
prefs.showUsage
|
|
800
744
|
]);
|
|
801
745
|
if (accounts.length === 0) return null;
|
|
802
|
-
const active = accounts.find((account) => account.uid === activeUid) ?? accounts
|
|
746
|
+
const active = accounts.find((account) => account.uid === activeUid) ?? accounts[0];
|
|
803
747
|
if (active === void 0) return null;
|
|
804
748
|
const label = `${t("switchAccount")}: ${active.nickname}`;
|
|
805
749
|
const limit = (usage?.main?.limit ?? 0) + (usage?.gift?.limit ?? 0);
|
|
@@ -813,10 +757,7 @@ window.__ModuleLoader__.load({
|
|
|
813
757
|
}, pct, t) : null;
|
|
814
758
|
const items = accounts.map((account) => ({
|
|
815
759
|
id: account.uid,
|
|
816
|
-
label: account.
|
|
817
|
-
className: AccountSwitcher_module_css_default.menuDefault,
|
|
818
|
-
children: t("defaultTag")
|
|
819
|
-
})] }) : account.nickname
|
|
760
|
+
label: account.nickname
|
|
820
761
|
}));
|
|
821
762
|
const size = RING_SIZE;
|
|
822
763
|
const stroke = RING_STROKE;
|
|
@@ -889,7 +830,6 @@ window.__ModuleLoader__.load({
|
|
|
889
830
|
fetchAccounts().then((value) => {
|
|
890
831
|
if (value === null) return;
|
|
891
832
|
setAccounts(value.accounts);
|
|
892
|
-
setDefaultUid(value.defaultUid);
|
|
893
833
|
});
|
|
894
834
|
return;
|
|
895
835
|
}
|
|
@@ -2356,12 +2296,17 @@ window.__ModuleLoader__.load({
|
|
|
2356
2296
|
* 则渲染,无记录(非 CodeBuddy 轮)渲染为空。与官方 `TurnUsagePanel` 同构:
|
|
2357
2297
|
* 图标 + 文字标签,点击无详情面板(仅展示一条合计)。
|
|
2358
2298
|
*
|
|
2359
|
-
*
|
|
2360
|
-
* `recordCredit`),不是悬停时现查 ——
|
|
2361
|
-
*
|
|
2299
|
+
* 悬停提示附上本轮用过的账号与本轮请求 id:两者都在扣分那一刻随记录写入(见 host 的
|
|
2300
|
+
* `recordCredit`),不是悬停时现查 —— 一轮里用户可以切换账号,而请求 id 每轮重铸,
|
|
2301
|
+
* 现查会把整轮说成最后那个账号、或报出当前轮的 id。有 id 时点击 pill 复制它的完整值,
|
|
2302
|
+
* 因为显示在提示里的那个值就是用户要拿去对账的东西。
|
|
2362
2303
|
*
|
|
2363
2304
|
* @module dsh-llm-codebuddy-power/client/TurnCreditPill
|
|
2364
2305
|
*/
|
|
2306
|
+
/** 复制成功后 pill 文字保持「已复制」的时长(毫秒),与配置页的复制反馈一致。 */
|
|
2307
|
+
const COPIED_FEEDBACK_MS = 1e3;
|
|
2308
|
+
/** 提示里显示的请求 id 前几位;完整值由点击复制,不必全写在提示里。 */
|
|
2309
|
+
const TURN_REQUEST_ID_DISPLAY_CHARS = 6;
|
|
2365
2310
|
const pillStyle = {
|
|
2366
2311
|
display: "inline-flex",
|
|
2367
2312
|
alignItems: "center",
|
|
@@ -2376,13 +2321,29 @@ window.__ModuleLoader__.load({
|
|
|
2376
2321
|
whiteSpace: "nowrap"
|
|
2377
2322
|
};
|
|
2378
2323
|
/**
|
|
2324
|
+
* 可点击时在 pill 样式上补上按钮语义:指针与键盘反馈,并让字族跟随环境。
|
|
2325
|
+
*
|
|
2326
|
+
* 只覆盖 `fontFamily` 而不是 `font` 简写:后者会把 `pillStyle` 的 `fontSize` 一并重置为
|
|
2327
|
+
* 继承值,同一个 pill 在可点击与不可点击两种形态下就会是两个字号。
|
|
2328
|
+
*/
|
|
2329
|
+
const copyableStyle = {
|
|
2330
|
+
...pillStyle,
|
|
2331
|
+
fontFamily: "inherit",
|
|
2332
|
+
cursor: "pointer"
|
|
2333
|
+
};
|
|
2334
|
+
/**
|
|
2379
2335
|
* 每轮积分 pill。messageId 反查轮号后查该轮记录;无记录渲染为空(未用
|
|
2380
2336
|
* CodeBuddy 模型即一轮 0 分也渲染,有记录即证明用了 CodeBuddy)。只显示
|
|
2381
|
-
* 积分,模型由 dsh
|
|
2337
|
+
* 积分,模型由 dsh 用量自带;悬停给出本轮用过的账号与本轮请求 id。
|
|
2382
2338
|
*/
|
|
2383
2339
|
function TurnCreditPill(props) {
|
|
2384
2340
|
const { messageId, useChat, sessionId, creditOf, t } = props;
|
|
2385
2341
|
const [record, setRecord] = (0, react.useState)(void 0);
|
|
2342
|
+
const [copied, setCopied] = (0, react.useState)(false);
|
|
2343
|
+
const copiedTimer = (0, react.useRef)(void 0);
|
|
2344
|
+
(0, react.useEffect)(() => () => {
|
|
2345
|
+
if (copiedTimer.current !== void 0) window.clearTimeout(copiedTimer.current);
|
|
2346
|
+
}, []);
|
|
2386
2347
|
const nodes = useChat((snapshot) => snapshot.legacy.nodes);
|
|
2387
2348
|
const turn = (0, react.useMemo)(() => {
|
|
2388
2349
|
for (const node of nodes) {
|
|
@@ -2411,21 +2372,50 @@ window.__ModuleLoader__.load({
|
|
|
2411
2372
|
turn
|
|
2412
2373
|
]);
|
|
2413
2374
|
if (record === void 0) return null;
|
|
2375
|
+
const requestId = record.requestId;
|
|
2414
2376
|
const creditText = (Math.round(record.credit * 100) / 100).toLocaleString(void 0, {
|
|
2415
2377
|
maximumFractionDigits: 2,
|
|
2416
2378
|
useGrouping: false
|
|
2417
2379
|
});
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
|
|
2421
|
-
|
|
2422
|
-
|
|
2380
|
+
const tipLines = [t("turnCreditTip"), ...record.accounts.map((account) => t("turnCreditAccount", {
|
|
2381
|
+
nickname: account.nickname,
|
|
2382
|
+
uid: account.uidPrefix
|
|
2383
|
+
}))];
|
|
2384
|
+
if (requestId !== void 0) {
|
|
2385
|
+
tipLines.push(t("turnCreditRequestId", { requestId: requestId.slice(0, TURN_REQUEST_ID_DISPLAY_CHARS) }));
|
|
2386
|
+
tipLines.push(copied ? t("turnCreditCopiedTip") : t("turnCreditCopyTip"));
|
|
2387
|
+
}
|
|
2388
|
+
const tip = tipLines.join("\n");
|
|
2389
|
+
const onCopy = () => {
|
|
2390
|
+
if (requestId === void 0 || copied) return;
|
|
2391
|
+
(0, _deepseek_ai_dsh_client_ui_primitives.writeClipboard)(requestId).then((ok) => {
|
|
2392
|
+
if (!ok) return;
|
|
2393
|
+
setCopied(true);
|
|
2394
|
+
copiedTimer.current = window.setTimeout(() => {
|
|
2395
|
+
copiedTimer.current = void 0;
|
|
2396
|
+
setCopied(false);
|
|
2397
|
+
}, COPIED_FEEDBACK_MS);
|
|
2398
|
+
});
|
|
2399
|
+
};
|
|
2400
|
+
if (requestId === void 0) return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
2401
|
+
label: tip,
|
|
2423
2402
|
side: "bottom",
|
|
2424
2403
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
2425
2404
|
style: pillStyle,
|
|
2426
2405
|
children: t("turnCredit", { credit: creditText })
|
|
2427
2406
|
})
|
|
2428
2407
|
});
|
|
2408
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tooltip, {
|
|
2409
|
+
label: tip,
|
|
2410
|
+
side: "bottom",
|
|
2411
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
2412
|
+
type: "button",
|
|
2413
|
+
style: copyableStyle,
|
|
2414
|
+
"aria-label": t("turnCreditCopy"),
|
|
2415
|
+
onClick: onCopy,
|
|
2416
|
+
children: copied ? t("turnCreditCopied") : t("turnCredit", { credit: creditText })
|
|
2417
|
+
})
|
|
2418
|
+
});
|
|
2429
2419
|
}
|
|
2430
2420
|
//#endregion
|
|
2431
2421
|
//#region src/client/locales.ts
|
|
@@ -2454,9 +2444,6 @@ window.__ModuleLoader__.load({
|
|
|
2454
2444
|
logoutSelectedDesc: "Signing out removes the stored credentials; the {count} selected accounts must sign in again to be used.",
|
|
2455
2445
|
logoutConfirm: "Sign out",
|
|
2456
2446
|
cancel: "Cancel",
|
|
2457
|
-
chooseDefault: "Choose default",
|
|
2458
|
-
clearDefault: "Remove default",
|
|
2459
|
-
defaultTag: "Default",
|
|
2460
2447
|
nickname: "Nickname",
|
|
2461
2448
|
uid: "UID",
|
|
2462
2449
|
loginExpires: "Sign-in expires",
|
|
@@ -2486,6 +2473,11 @@ window.__ModuleLoader__.load({
|
|
|
2486
2473
|
turnCredit: "{credit} credits",
|
|
2487
2474
|
turnCreditTip: "CodeBuddy credits spent this turn",
|
|
2488
2475
|
turnCreditAccount: "Account: {nickname} ({uid}…)",
|
|
2476
|
+
turnCreditRequestId: "Request ID: {requestId}…",
|
|
2477
|
+
turnCreditCopy: "Copy this turn’s request ID",
|
|
2478
|
+
turnCreditCopyTip: "Click to copy this turn’s request ID",
|
|
2479
|
+
turnCreditCopied: "Copied",
|
|
2480
|
+
turnCreditCopiedTip: "Request ID copied",
|
|
2489
2481
|
modelPanelTrigger: "CodeBuddy models",
|
|
2490
2482
|
modelPanelTitle: "CodeBuddy models",
|
|
2491
2483
|
modelPanelEmpty: "No CodeBuddy models available.",
|
|
@@ -2530,9 +2522,6 @@ window.__ModuleLoader__.load({
|
|
|
2530
2522
|
logoutSelectedDesc: "退出会删除已存凭据,选中的 {count} 个账号需要重新登录才能继续使用。",
|
|
2531
2523
|
logoutConfirm: "退出",
|
|
2532
2524
|
cancel: "取消",
|
|
2533
|
-
chooseDefault: "选择默认",
|
|
2534
|
-
clearDefault: "取消默认",
|
|
2535
|
-
defaultTag: "默认",
|
|
2536
2525
|
nickname: "昵称",
|
|
2537
2526
|
uid: "UID",
|
|
2538
2527
|
loginExpires: "登录到期",
|
|
@@ -2562,6 +2551,11 @@ window.__ModuleLoader__.load({
|
|
|
2562
2551
|
turnCredit: "{credit} 分",
|
|
2563
2552
|
turnCreditTip: "本轮消耗的 CodeBuddy 积分",
|
|
2564
2553
|
turnCreditAccount: "账号:{nickname}({uid}…)",
|
|
2554
|
+
turnCreditRequestId: "请求 ID:{requestId}…",
|
|
2555
|
+
turnCreditCopy: "复制本轮请求 ID",
|
|
2556
|
+
turnCreditCopyTip: "点击复制本轮请求 ID",
|
|
2557
|
+
turnCreditCopied: "已复制",
|
|
2558
|
+
turnCreditCopiedTip: "请求 ID 已复制",
|
|
2565
2559
|
modelPanelTrigger: "CodeBuddy 模型",
|
|
2566
2560
|
modelPanelTitle: "CodeBuddy 模型",
|
|
2567
2561
|
modelPanelEmpty: "暂无可用 CodeBuddy 模型。",
|
|
@@ -2587,8 +2581,8 @@ window.__ModuleLoader__.load({
|
|
|
2587
2581
|
/**
|
|
2588
2582
|
* CodeBuddy 页面 store:配置页共享的账号快照。
|
|
2589
2583
|
*
|
|
2590
|
-
*
|
|
2591
|
-
*
|
|
2584
|
+
* 客户端插件在配置页条目下挂载本句柄,因此在该页完成的登录、退出或排序
|
|
2585
|
+
* 无需跨组件接线即可到达同一页面的各个徽章。
|
|
2592
2586
|
*
|
|
2593
2587
|
* **界面偏好不在这里**:它们是插件自己的 volatile 配置字段(见 `../prefs.ts`),
|
|
2594
2588
|
* 由 `./index.ts` 经 `ctx.configForms.get()` 读取,并以一个派生的活快照经
|
|
@@ -2607,7 +2601,6 @@ window.__ModuleLoader__.load({
|
|
|
2607
2601
|
phase: "loading",
|
|
2608
2602
|
error: null,
|
|
2609
2603
|
accounts: [],
|
|
2610
|
-
defaultUid: null,
|
|
2611
2604
|
loginState: null
|
|
2612
2605
|
}),
|
|
2613
2606
|
actions: {
|
|
@@ -2619,7 +2612,6 @@ window.__ModuleLoader__.load({
|
|
|
2619
2612
|
draft.phase = "idle";
|
|
2620
2613
|
draft.error = null;
|
|
2621
2614
|
draft.accounts = result.accounts;
|
|
2622
|
-
draft.defaultUid = result.defaultUid ?? null;
|
|
2623
2615
|
},
|
|
2624
2616
|
fail: (draft, message) => {
|
|
2625
2617
|
draft.phase = "error";
|
|
@@ -2801,11 +2793,6 @@ window.__ModuleLoader__.load({
|
|
|
2801
2793
|
if (result.ok) await refreshAccounts(actions);
|
|
2802
2794
|
else actions.fail(`${result.error.code}: ${result.error.message}`);
|
|
2803
2795
|
};
|
|
2804
|
-
const setDefault = async (uid) => {
|
|
2805
|
-
const result = await authCall(rpc, "setDefault", { uid: uid ?? "" });
|
|
2806
|
-
if (result.ok) await refreshAccounts(actions);
|
|
2807
|
-
else actions.fail(`${result.error.code}: ${result.error.message}`);
|
|
2808
|
-
};
|
|
2809
2796
|
return {
|
|
2810
2797
|
hooks: { prefs: prefsStore },
|
|
2811
2798
|
refreshAccounts: () => refreshAccounts(actions),
|
|
@@ -2822,7 +2809,6 @@ window.__ModuleLoader__.load({
|
|
|
2822
2809
|
pollLogin,
|
|
2823
2810
|
logoutAccounts,
|
|
2824
2811
|
reorderAccounts,
|
|
2825
|
-
setDefault,
|
|
2826
2812
|
setPref
|
|
2827
2813
|
};
|
|
2828
2814
|
};
|
|
@@ -2845,10 +2831,7 @@ window.__ModuleLoader__.load({
|
|
|
2845
2831
|
fetchAccounts: async () => {
|
|
2846
2832
|
const result = await authCall(rpc, "accounts");
|
|
2847
2833
|
if (!result.ok) return null;
|
|
2848
|
-
return {
|
|
2849
|
-
accounts: result.value.accounts,
|
|
2850
|
-
defaultUid: result.value.defaultUid ?? null
|
|
2851
|
-
};
|
|
2834
|
+
return { accounts: result.value.accounts };
|
|
2852
2835
|
},
|
|
2853
2836
|
fetchSessionAccount: async () => {
|
|
2854
2837
|
const result = await authCall(rpc, "sessionAccount", { sessionId });
|