dsh-codearts 0.0.0-stage → 0.2.1

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.
@@ -0,0 +1,789 @@
1
+ window.__ModuleLoader__.load({
2
+ id: "dsh-codearts",
3
+ factory(require) {
4
+ var module = { exports: {} };
5
+ var exports = module.exports;
6
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
7
+ let react = require("react");
8
+ let _deepseek_ai_dsh_client_ui_primitives = require("@deepseek-ai/dsh-client-ui-primitives");
9
+ let react_jsx_runtime = require("react/jsx-runtime");
10
+ //#region \0dsh-css:F:\centos\dsh-codearts\src\client\CodeArtsPluginCard.module.css.mjs
11
+ const css = ".DZPfya_card{border:.5px solid var(--dsw-alias-settings-card-stroke);border-radius:var(--dsw-radius-lg);background:var(--dsw-alias-settings-card-fill);max-width:720px}.DZPfya_header{align-items:flex-start;gap:12px;padding:14px 16px;display:flex}.DZPfya_headText{flex-direction:column;flex:1;gap:6px;min-width:0;display:flex}.DZPfya_name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:22px}.DZPfya_desc{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:20px}.DZPfya_statusLine{color:var(--dsw-alias-label-primary);align-items:center;gap:6px;font-size:14px;font-weight:500;line-height:22px;display:inline-flex}.DZPfya_meta{color:var(--dsw-alias-label-tertiary);font-variant-numeric:tabular-nums;font-size:12px;line-height:18px}.DZPfya_body{border-top:.5px solid var(--dsw-alias-border-l2);margin:0 16px;padding:4px 0 16px}.DZPfya_section{margin-top:16px}.DZPfya_sectionHead{justify-content:space-between;align-items:baseline;gap:12px;display:flex}.DZPfya_sectionLabel{color:var(--dsw-alias-label-tertiary);font-size:11px;font-weight:500}.DZPfya_count{color:var(--dsw-alias-label-secondary);font-variant-numeric:tabular-nums;flex:none;font-size:12px}.DZPfya_hint{color:var(--dsw-alias-label-secondary);margin:8px 0 0;font-size:13px;line-height:20px}.DZPfya_error{color:var(--dsw-alias-state-error-primary);margin:10px 0 0;font-size:13px;line-height:20px}.DZPfya_actions{flex-wrap:wrap;align-items:center;gap:8px;margin-top:12px;display:flex}.DZPfya_danger{color:var(--dsw-alias-state-error-primary)}.DZPfya_link{appearance:none;color:var(--dsw-alias-brand-text);font:inherit;text-align:left;word-break:break-all;cursor:pointer;background:0 0;border:none;padding:0;font-size:12px}.DZPfya_link:hover{text-decoration:underline}.DZPfya_choices{flex-direction:column;gap:2px;margin-top:8px;display:flex}.DZPfya_choiceRow{border-radius:var(--dsw-radius-sm);align-items:center;gap:8px;margin:0 -6px;padding:5px 6px;display:flex}.DZPfya_choiceRow:hover{background:var(--dsw-alias-interactive-bg-hover)}.DZPfya_check{flex:1;min-width:0}.DZPfya_check>span{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.DZPfya_manual{border:.5px solid var(--dsw-alias-border-l3);border-radius:var(--dsw-radius-md);margin-top:12px;padding:0 12px}.DZPfya_manual[open]{padding-bottom:12px}.DZPfya_manualSummary{color:var(--dsw-alias-label-secondary);cursor:pointer;align-items:center;gap:6px;padding:9px 0;font-size:13px;list-style:none;display:flex}.DZPfya_manualSummary::-webkit-details-marker{display:none}.DZPfya_field{flex-direction:column;gap:5px;margin-top:10px;display:flex}.DZPfya_fieldLabel{color:var(--dsw-alias-label-tertiary);font-size:12px}.DZPfya_area{box-sizing:border-box;resize:vertical;border:.5px solid var(--dsw-alias-border-l4);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1);width:100%;color:var(--dsw-alias-label-primary);padding:6px 8px;font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:13px;line-height:20px}.DZPfya_area::placeholder{color:var(--dsw-alias-label-dimmed)}.DZPfya_area:focus{border-color:var(--dsw-alias-state-business-primary);outline:none}";
12
+ const tagId = "dsh-codearts/CodeArtsPluginCard.module.css";
13
+ if (typeof document !== "undefined" && document.querySelector("style[data-plugin-css=" + JSON.stringify(tagId) + "]") === null) {
14
+ const tag = document.createElement("style");
15
+ tag.dataset.plugin = "dsh-codearts";
16
+ tag.dataset.pluginCss = tagId;
17
+ tag.textContent = css;
18
+ document.head.appendChild(tag);
19
+ }
20
+ var CodeArtsPluginCard_module_css_default = {
21
+ "body": "DZPfya_body",
22
+ "name": "DZPfya_name",
23
+ "manual": "DZPfya_manual",
24
+ "manualSummary": "DZPfya_manualSummary",
25
+ "statusLine": "DZPfya_statusLine",
26
+ "actions": "DZPfya_actions",
27
+ "sectionLabel": "DZPfya_sectionLabel",
28
+ "field": "DZPfya_field",
29
+ "count": "DZPfya_count",
30
+ "danger": "DZPfya_danger",
31
+ "area": "DZPfya_area",
32
+ "error": "DZPfya_error",
33
+ "hint": "DZPfya_hint",
34
+ "desc": "DZPfya_desc",
35
+ "meta": "DZPfya_meta",
36
+ "choiceRow": "DZPfya_choiceRow",
37
+ "choices": "DZPfya_choices",
38
+ "sectionHead": "DZPfya_sectionHead",
39
+ "fieldLabel": "DZPfya_fieldLabel",
40
+ "card": "DZPfya_card",
41
+ "link": "DZPfya_link",
42
+ "header": "DZPfya_header",
43
+ "headText": "DZPfya_headText",
44
+ "section": "DZPfya_section",
45
+ "check": "DZPfya_check"
46
+ };
47
+ //#endregion
48
+ //#region src/client/CodeArtsPluginCard.tsx
49
+ function formatStored(ts) {
50
+ if (ts === void 0 || !Number.isFinite(ts)) return "";
51
+ try {
52
+ return new Date(ts).toLocaleString();
53
+ } catch {
54
+ return String(ts);
55
+ }
56
+ }
57
+ /** 上游给的 name 自带「 (免费)」尾巴,已经用 Tag 表达了就别重复一遍。 */
58
+ const TRAILING_FREE = /\s*[((]\s*免费\s*[))]\s*$/;
59
+ function modelName(choice) {
60
+ return choice.free === true ? choice.name.replace(TRAILING_FREE, "") : choice.name;
61
+ }
62
+ /** 官方用量明细页(CodeArts 没有额度接口,只能给链接)。 */
63
+ const OFFICIAL_USAGE_URL = "https://codearts.huaweicloud.com/portal/settings/personal-usage";
64
+ /** token 数按人类习惯缩写:12345 -> 12.3k。 */
65
+ function formatTokens(value) {
66
+ if (!Number.isFinite(value)) return "0";
67
+ if (value >= 1e6) return `${(value / 1e6).toFixed(1)}M`;
68
+ if (value >= 1e3) return `${(value / 1e3).toFixed(1)}k`;
69
+ return String(Math.round(value));
70
+ }
71
+ function formatCount(value) {
72
+ return Number.isFinite(value) ? String(Math.round(value)) : "0";
73
+ }
74
+ /**
75
+ * 用量区块。
76
+ *
77
+ * 只展示**本机经插件发出**的请求:上游没有额度/积分接口(README 与 codearts2api
78
+ * 都是这个结论),所以这里明确写出这一点并给出官方明细页链接,别让用户误以为
79
+ * 这是账号总额度。会话槽位是真事实 —— 每账号 3 个并发会话、被占时要等约 52 秒
80
+ * 才释放,这也正是「打断后重新提问要等」的原因。
81
+ */
82
+ function UsageSection({ usage, t }) {
83
+ const total = usage.today.requests;
84
+ const stateLabel = {
85
+ ok: t("usageStateOk"),
86
+ capped: t("usageStateCapped"),
87
+ cooling: t("usageStateCooling"),
88
+ disabled: t("usageStateDisabled")
89
+ };
90
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
91
+ className: CodeArtsPluginCard_module_css_default.section,
92
+ children: [
93
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
94
+ className: CodeArtsPluginCard_module_css_default.sectionHead,
95
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
96
+ className: CodeArtsPluginCard_module_css_default.sectionLabel,
97
+ children: t("usageTitle")
98
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
99
+ className: CodeArtsPluginCard_module_css_default.count,
100
+ children: t("usageRequests", { n: formatCount(total) })
101
+ })]
102
+ }),
103
+ total === 0 ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
104
+ className: CodeArtsPluginCard_module_css_default.hint,
105
+ children: t("usageEmpty")
106
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
107
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
108
+ className: CodeArtsPluginCard_module_css_default.choiceRow,
109
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
110
+ className: CodeArtsPluginCard_module_css_default.name,
111
+ children: t("usageToday")
112
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
113
+ className: CodeArtsPluginCard_module_css_default.meta,
114
+ children: t("usageTokens", {
115
+ prompt: formatTokens(usage.today.promptTokens),
116
+ completion: formatTokens(usage.today.completionTokens)
117
+ })
118
+ })]
119
+ }),
120
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
121
+ className: CodeArtsPluginCard_module_css_default.choiceRow,
122
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
123
+ className: CodeArtsPluginCard_module_css_default.name,
124
+ children: t("usageAllTime", { days: formatCount(usage.days) })
125
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
126
+ className: CodeArtsPluginCard_module_css_default.meta,
127
+ children: [
128
+ t("usageRequests", { n: formatCount(usage.allTime.requests) }),
129
+ " · ",
130
+ t("usageTokens", {
131
+ prompt: formatTokens(usage.allTime.promptTokens),
132
+ completion: formatTokens(usage.allTime.completionTokens)
133
+ })
134
+ ]
135
+ })]
136
+ }),
137
+ usage.byModelToday.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
138
+ className: CodeArtsPluginCard_module_css_default.hint,
139
+ children: t("usageByModel")
140
+ }), usage.byModelToday.slice(0, 5).map((entry) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
141
+ className: CodeArtsPluginCard_module_css_default.choiceRow,
142
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
143
+ className: CodeArtsPluginCard_module_css_default.name,
144
+ children: entry.id
145
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
146
+ className: CodeArtsPluginCard_module_css_default.meta,
147
+ children: [
148
+ t("usageRequests", { n: formatCount(entry.totals.requests) }),
149
+ " · ",
150
+ t("usageTokens", {
151
+ prompt: formatTokens(entry.totals.promptTokens),
152
+ completion: formatTokens(entry.totals.completionTokens)
153
+ })
154
+ ]
155
+ })]
156
+ }, entry.id))] })
157
+ ] }),
158
+ usage.slots.length > 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
159
+ className: CodeArtsPluginCard_module_css_default.hint,
160
+ children: t("usageSlots")
161
+ }), usage.slots.map((slot) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
162
+ className: CodeArtsPluginCard_module_css_default.choiceRow,
163
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
164
+ className: CodeArtsPluginCard_module_css_default.name,
165
+ children: `${slot.active}/${slot.max}`
166
+ }), slot.state === "ok" ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, {
167
+ tone: "success",
168
+ children: stateLabel.ok
169
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, { children: stateLabel[slot.state] })]
170
+ }, slot.id))] }),
171
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
172
+ className: CodeArtsPluginCard_module_css_default.hint,
173
+ children: [
174
+ t("usageNoQuota"),
175
+ " ",
176
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
177
+ className: CodeArtsPluginCard_module_css_default.link,
178
+ href: OFFICIAL_USAGE_URL,
179
+ target: "_blank",
180
+ rel: "noreferrer",
181
+ children: OFFICIAL_USAGE_URL
182
+ })
183
+ ]
184
+ })
185
+ ]
186
+ });
187
+ }
188
+ function CodeArtsPluginCard({ t }) {
189
+ const [status, setStatus] = (0, react.useState)(null);
190
+ const [token, setToken] = (0, react.useState)("");
191
+ const [label, setLabel] = (0, react.useState)("");
192
+ const [busy, setBusy] = (0, react.useState)(false);
193
+ const [msg, setMsg] = (0, react.useState)(null);
194
+ const [loginUrl, setLoginUrl] = (0, react.useState)(null);
195
+ const [loginPending, setLoginPending] = (0, react.useState)(false);
196
+ const [selection, setSelection] = (0, react.useState)(null);
197
+ const [draft, setDraft] = (0, react.useState)([]);
198
+ const [savingModels, setSavingModels] = (0, react.useState)(false);
199
+ const [savedModels, setSavedModels] = (0, react.useState)(false);
200
+ const [modelError, setModelError] = (0, react.useState)(null);
201
+ async function refresh() {
202
+ try {
203
+ const data = await (await fetch("/api/codearts/status", { headers: { Accept: "application/json" } })).json();
204
+ setStatus(data);
205
+ } catch {
206
+ setStatus({
207
+ status: "signed-out",
208
+ models: [],
209
+ accounts: []
210
+ });
211
+ }
212
+ }
213
+ async function refreshSelection() {
214
+ try {
215
+ const data = await (await fetch("/api/codearts/enabled-models", { headers: { Accept: "application/json" } })).json();
216
+ setSelection(data.selection);
217
+ setDraft(data.selection.choices.filter((c) => c.enabled).map((c) => c.id));
218
+ setSavedModels(true);
219
+ } catch {
220
+ setSelection(null);
221
+ }
222
+ }
223
+ (0, react.useEffect)(() => {
224
+ refresh();
225
+ }, []);
226
+ (0, react.useEffect)(() => {
227
+ refreshSelection();
228
+ }, []);
229
+ (0, react.useEffect)(() => {
230
+ if (status?.status === "signed-in") refreshSelection();
231
+ }, [status?.status]);
232
+ async function saveToken(e) {
233
+ e.preventDefault();
234
+ setBusy(true);
235
+ setMsg(null);
236
+ try {
237
+ const res = await fetch("/api/codearts/token", {
238
+ method: "POST",
239
+ headers: { "Content-Type": "application/json" },
240
+ body: JSON.stringify({
241
+ token: token.trim(),
242
+ label: label.trim() || void 0
243
+ })
244
+ });
245
+ if (!res.ok) {
246
+ const data = await res.json().catch(() => ({}));
247
+ setMsg(data.error ?? `HTTP ${res.status}`);
248
+ } else {
249
+ setToken("");
250
+ setLabel("");
251
+ await refresh();
252
+ }
253
+ } catch (err) {
254
+ setMsg(err instanceof Error ? err.message : String(err));
255
+ } finally {
256
+ setBusy(false);
257
+ }
258
+ }
259
+ async function clearToken() {
260
+ setBusy(true);
261
+ try {
262
+ await fetch("/api/codearts/token", { method: "DELETE" });
263
+ await refresh();
264
+ } finally {
265
+ setBusy(false);
266
+ }
267
+ }
268
+ async function removeAccount(id) {
269
+ setBusy(true);
270
+ try {
271
+ await fetch(`/api/codearts/accounts?id=${encodeURIComponent(id)}`, { method: "DELETE" });
272
+ await refresh();
273
+ } finally {
274
+ setBusy(false);
275
+ }
276
+ }
277
+ const all = selection?.choices.length ?? 0;
278
+ const wire = draft.length === all ? [] : draft;
279
+ const savedIds = selection?.choices.filter((c) => c.enabled).map((c) => c.id) ?? [];
280
+ const dirty = savedIds.length !== draft.length || savedIds.some((id) => !draft.includes(id));
281
+ function setModel(id, on) {
282
+ setSavedModels(false);
283
+ setModelError(null);
284
+ setDraft((current) => on ? [...current, id] : current.filter((e) => e !== id));
285
+ }
286
+ async function saveModels() {
287
+ setSavingModels(true);
288
+ setModelError(null);
289
+ try {
290
+ const res = await fetch("/api/codearts/enabled-models", {
291
+ method: "POST",
292
+ headers: {
293
+ "Content-Type": "application/json",
294
+ Accept: "application/json"
295
+ },
296
+ body: JSON.stringify({ enabledModels: wire })
297
+ });
298
+ if (!res.ok) {
299
+ const data = await res.json().catch(() => ({}));
300
+ throw new Error(data.error ?? `HTTP ${res.status}`);
301
+ }
302
+ const data = await res.json();
303
+ setSelection(data.selection);
304
+ setDraft(data.selection.choices.filter((c) => c.enabled).map((c) => c.id));
305
+ setSavedModels(true);
306
+ } catch (err) {
307
+ setModelError(err instanceof Error ? err.message : String(err));
308
+ } finally {
309
+ setSavingModels(false);
310
+ }
311
+ }
312
+ async function startOAuthLogin() {
313
+ setBusy(true);
314
+ setMsg(null);
315
+ setLoginPending(true);
316
+ try {
317
+ const res = await fetch("/api/codearts/login", { method: "POST" });
318
+ const data = await res.json().catch(() => ({}));
319
+ if (!res.ok || typeof data.url !== "string") {
320
+ setMsg(data.error ?? `HTTP ${res.status}`);
321
+ setLoginPending(false);
322
+ return;
323
+ }
324
+ setLoginUrl(data.url);
325
+ if (typeof window !== "undefined") window.open(data.url, "_blank");
326
+ const poll = async () => {
327
+ const st = await (await fetch(`/api/codearts/login/status?url=${encodeURIComponent(data.url)}`, { headers: { Accept: "application/json" } })).json().catch(() => ({ status: "pending" }));
328
+ if (st.status === "done") {
329
+ setLoginUrl(null);
330
+ setLoginPending(false);
331
+ await refresh();
332
+ return;
333
+ }
334
+ if (st.status === "error") {
335
+ setLoginUrl(null);
336
+ setLoginPending(false);
337
+ setMsg(t("loginFailed"));
338
+ return;
339
+ }
340
+ if (st.status === "idle") {
341
+ setLoginUrl(null);
342
+ setLoginPending(false);
343
+ await refresh();
344
+ return;
345
+ }
346
+ setTimeout(() => void poll(), 1500);
347
+ };
348
+ poll();
349
+ } catch (err) {
350
+ setMsg(err instanceof Error ? err.message : String(err));
351
+ setLoginPending(false);
352
+ } finally {
353
+ setBusy(false);
354
+ }
355
+ }
356
+ const signedIn = status?.status === "signed-in";
357
+ const expired = status?.status === "expired";
358
+ const accounts = status?.accounts ?? [];
359
+ const accountName = (account) => account.label?.trim() || account.userName?.trim() || account.id;
360
+ /**
361
+ * 每个账号的「获取时间 + 过期状态」。同一账号重复登录可能留下多条记录(上游不给
362
+ * 稳定身份时的妥协),把时间摆出来用户才能一眼认出哪条是旧的、放心删。
363
+ */
364
+ const accountMeta = (account) => {
365
+ const parts = [];
366
+ const stored = formatStored(account.storedAt);
367
+ if (stored !== "") parts.push(t("accountStored", { time: stored }));
368
+ const exp = typeof account.expiration === "string" ? Date.parse(account.expiration) : NaN;
369
+ if (Number.isFinite(exp)) parts.push(exp <= Date.now() ? t("accountExpired", { time: formatStored(exp) }) : t("accountExpires", { time: formatStored(exp) }));
370
+ return parts.join(" · ");
371
+ };
372
+ const dotState = signedIn ? "done" : expired ? "warning" : "idle";
373
+ const statusText = signedIn ? t("statusSignedIn") : expired ? t("statusExpired") : t("statusSignedOut");
374
+ const storedTime = formatStored(status?.storedAt);
375
+ const storedLabel = status?.label?.trim() ?? "";
376
+ const meta = !signedIn || storedTime === "" ? "" : storedLabel === "" ? t("storedMetaNoLabel", { time: storedTime }) : t("storedMeta", {
377
+ label: storedLabel,
378
+ time: storedTime
379
+ });
380
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
381
+ className: CodeArtsPluginCard_module_css_default.card,
382
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
383
+ className: CodeArtsPluginCard_module_css_default.header,
384
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
385
+ className: CodeArtsPluginCard_module_css_default.headText,
386
+ children: [
387
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
388
+ className: CodeArtsPluginCard_module_css_default.name,
389
+ children: t("cardTitle")
390
+ }),
391
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("span", {
392
+ className: CodeArtsPluginCard_module_css_default.statusLine,
393
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.StateDot, { state: dotState }), statusText]
394
+ }),
395
+ meta !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
396
+ className: CodeArtsPluginCard_module_css_default.meta,
397
+ children: meta
398
+ }),
399
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
400
+ className: CodeArtsPluginCard_module_css_default.desc,
401
+ children: signedIn ? t("descSignedIn") : t("descSignedOut")
402
+ })
403
+ ]
404
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
405
+ variant: "outline",
406
+ size: "sm",
407
+ disabled: busy,
408
+ onClick: () => void refresh(),
409
+ children: t("refresh")
410
+ })]
411
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
412
+ className: CodeArtsPluginCard_module_css_default.body,
413
+ children: [
414
+ signedIn ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
415
+ className: CodeArtsPluginCard_module_css_default.section,
416
+ children: [
417
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
418
+ className: CodeArtsPluginCard_module_css_default.sectionHead,
419
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
420
+ className: CodeArtsPluginCard_module_css_default.sectionLabel,
421
+ children: t("accountsTitle")
422
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
423
+ className: CodeArtsPluginCard_module_css_default.count,
424
+ children: accounts.length
425
+ })]
426
+ }),
427
+ accounts.length > 1 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
428
+ className: CodeArtsPluginCard_module_css_default.hint,
429
+ children: t("accountsRotateHint")
430
+ }),
431
+ accounts.map((account) => {
432
+ const meta = accountMeta(account);
433
+ return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
434
+ className: CodeArtsPluginCard_module_css_default.choiceRow,
435
+ children: [
436
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
437
+ className: CodeArtsPluginCard_module_css_default.name,
438
+ children: accountName(account)
439
+ }),
440
+ meta !== "" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
441
+ className: CodeArtsPluginCard_module_css_default.meta,
442
+ children: meta
443
+ }),
444
+ account.stale && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, { children: t("accountNeedsSignIn") }),
445
+ !account.signable && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, { children: t("accountNoKey") }),
446
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
447
+ variant: "outline",
448
+ size: "sm",
449
+ className: CodeArtsPluginCard_module_css_default.danger,
450
+ disabled: busy,
451
+ onClick: () => void removeAccount(account.id),
452
+ children: t("accountRemove")
453
+ })
454
+ ]
455
+ }, account.id);
456
+ }),
457
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
458
+ className: CodeArtsPluginCard_module_css_default.actions,
459
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
460
+ variant: "primary",
461
+ size: "sm",
462
+ disabled: busy || loginPending,
463
+ onClick: () => void startOAuthLogin(),
464
+ children: loginPending ? t("signingIn") : t("addAccount")
465
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
466
+ variant: "outline",
467
+ size: "sm",
468
+ className: CodeArtsPluginCard_module_css_default.danger,
469
+ disabled: busy,
470
+ onClick: () => void clearToken(),
471
+ children: t("clearToken")
472
+ })]
473
+ }),
474
+ loginUrl !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
475
+ className: CodeArtsPluginCard_module_css_default.hint,
476
+ children: [
477
+ t("openManually"),
478
+ " ",
479
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
480
+ className: CodeArtsPluginCard_module_css_default.link,
481
+ href: loginUrl,
482
+ target: "_blank",
483
+ rel: "noreferrer",
484
+ children: loginUrl
485
+ })
486
+ ]
487
+ })
488
+ ]
489
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
490
+ className: CodeArtsPluginCard_module_css_default.section,
491
+ children: [
492
+ expired && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
493
+ className: CodeArtsPluginCard_module_css_default.hint,
494
+ children: t("expiredHint")
495
+ }),
496
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
497
+ className: CodeArtsPluginCard_module_css_default.actions,
498
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
499
+ variant: "primary",
500
+ disabled: busy || loginPending,
501
+ onClick: () => void startOAuthLogin(),
502
+ children: loginPending ? t("signingIn") : t("signIn")
503
+ })
504
+ }),
505
+ loginUrl !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("p", {
506
+ className: CodeArtsPluginCard_module_css_default.hint,
507
+ children: [
508
+ t("openManually"),
509
+ " ",
510
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("a", {
511
+ className: CodeArtsPluginCard_module_css_default.link,
512
+ href: loginUrl,
513
+ target: "_blank",
514
+ rel: "noreferrer",
515
+ children: loginUrl
516
+ })
517
+ ]
518
+ }),
519
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("details", {
520
+ className: CodeArtsPluginCard_module_css_default.manual,
521
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("summary", {
522
+ className: CodeArtsPluginCard_module_css_default.manualSummary,
523
+ children: t("manualToken")
524
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("form", {
525
+ onSubmit: (e) => void saveToken(e),
526
+ children: [
527
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
528
+ className: CodeArtsPluginCard_module_css_default.field,
529
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
530
+ className: CodeArtsPluginCard_module_css_default.fieldLabel,
531
+ htmlFor: "codearts-token",
532
+ children: t("tokenLabel")
533
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
534
+ id: "codearts-token",
535
+ className: CodeArtsPluginCard_module_css_default.area,
536
+ value: token,
537
+ onChange: (e) => setToken(e.target.value),
538
+ placeholder: t("tokenPlaceholder"),
539
+ rows: 4
540
+ })]
541
+ }),
542
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
543
+ className: CodeArtsPluginCard_module_css_default.field,
544
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("label", {
545
+ className: CodeArtsPluginCard_module_css_default.fieldLabel,
546
+ htmlFor: "codearts-label",
547
+ children: t("labelLabel")
548
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Input, {
549
+ id: "codearts-label",
550
+ value: label,
551
+ onChange: (e) => setLabel(e.target.value),
552
+ placeholder: t("labelPlaceholder")
553
+ })]
554
+ }),
555
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
556
+ className: CodeArtsPluginCard_module_css_default.actions,
557
+ children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
558
+ variant: "primary",
559
+ size: "sm",
560
+ type: "submit",
561
+ disabled: busy || token.trim() === "",
562
+ children: t("saveToken")
563
+ })
564
+ })
565
+ ]
566
+ })]
567
+ })
568
+ ]
569
+ }),
570
+ msg !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
571
+ className: CodeArtsPluginCard_module_css_default.error,
572
+ children: msg
573
+ }),
574
+ selection ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
575
+ className: CodeArtsPluginCard_module_css_default.section,
576
+ children: [
577
+ /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
578
+ className: CodeArtsPluginCard_module_css_default.sectionHead,
579
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
580
+ className: CodeArtsPluginCard_module_css_default.sectionLabel,
581
+ children: t("modelsTitle")
582
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
583
+ className: CodeArtsPluginCard_module_css_default.count,
584
+ children: t("selectedCount", {
585
+ n: draft.length,
586
+ total: all
587
+ })
588
+ })]
589
+ }),
590
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
591
+ className: CodeArtsPluginCard_module_css_default.hint,
592
+ children: selection.restricted ? t("optionalModelsHint") : t("optionalModelsAllHint")
593
+ }),
594
+ /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
595
+ className: CodeArtsPluginCard_module_css_default.choices,
596
+ children: selection.choices.map((choice) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
597
+ className: CodeArtsPluginCard_module_css_default.choiceRow,
598
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Checkbox, {
599
+ className: CodeArtsPluginCard_module_css_default.check,
600
+ checked: draft.includes(choice.id),
601
+ disabled: !selection.writable || savingModels,
602
+ onChange: (on) => setModel(choice.id, on),
603
+ label: modelName(choice)
604
+ }), choice.free === true && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Tag, {
605
+ tone: "success",
606
+ children: t("free")
607
+ })]
608
+ }, choice.id))
609
+ }),
610
+ selection.writable && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
611
+ className: CodeArtsPluginCard_module_css_default.actions,
612
+ children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
613
+ variant: "outline",
614
+ size: "sm",
615
+ disabled: draft.length === all,
616
+ onClick: () => {
617
+ setSavedModels(false);
618
+ setModelError(null);
619
+ setDraft(selection.choices.map((c) => c.id));
620
+ },
621
+ children: t("selectAll")
622
+ }), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
623
+ variant: "primary",
624
+ size: "sm",
625
+ disabled: !dirty || savingModels,
626
+ onClick: () => void saveModels(),
627
+ children: savingModels ? t("saving") : savedModels && !dirty ? t("saved") : t("saveModels")
628
+ })]
629
+ }),
630
+ modelError !== null && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
631
+ className: CodeArtsPluginCard_module_css_default.error,
632
+ children: modelError
633
+ })
634
+ ]
635
+ }) : /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
636
+ className: CodeArtsPluginCard_module_css_default.hint,
637
+ children: t("modelsLoading")
638
+ }),
639
+ status?.usage !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageSection, {
640
+ usage: status.usage,
641
+ t
642
+ })
643
+ ]
644
+ })]
645
+ });
646
+ }
647
+ //#endregion
648
+ //#region src/client/locales.ts
649
+ const zh = {
650
+ tabLabel: "CodeArts",
651
+ cardTitle: "DSH CodeArts Connect",
652
+ statusSignedIn: "已登录",
653
+ statusSignedOut: "未登录",
654
+ statusExpired: "凭证已过期",
655
+ descSignedIn: "凭证已就绪,勾选的模型会出现在模型选择器里。",
656
+ descSignedOut: "用华为云账号登录,或手动粘贴一个 CodeArts cloud_dragon_token。",
657
+ storedMeta: "{label} · 存于 {time}",
658
+ storedMetaNoLabel: "存于 {time}",
659
+ refresh: "刷新",
660
+ clearToken: "清除凭证",
661
+ tokenLabel: "cloud_dragon_token",
662
+ tokenPlaceholder: "粘贴从 CodeArts 网页/桌面端拿到的 token……",
663
+ labelLabel: "备注(可选)",
664
+ labelPlaceholder: "例如账号昵称,便于区分",
665
+ saveToken: "保存 token",
666
+ expiredHint: "凭证已过期,请重新登录以继续使用;已勾选的模型设置会保留。",
667
+ accountsTitle: "账号",
668
+ accountRemove: "删除",
669
+ addAccount: "添加账号",
670
+ accountsRotateHint: "已存多个账号:请求会自动轮转,某个账号忙时改用下一个,不用干等。",
671
+ accountNeedsSignIn: "需重新登录",
672
+ accountNoKey: "无 AK/SK",
673
+ accountStored: "获取于 {time}",
674
+ accountExpires: "{time} 过期",
675
+ accountExpired: "已于 {time} 过期",
676
+ modelsTitle: "可选模型",
677
+ optionalModelsHint: "仅勾选的模型会出现在模型选择器里。",
678
+ optionalModelsAllHint: "所有模型默认都出现在选择器里;取消勾选不想用的即可。",
679
+ selectedCount: "已选 {n} / {total}",
680
+ selectAll: "全选",
681
+ free: "免费",
682
+ saveModels: "保存模型选择",
683
+ saving: "保存中…",
684
+ saved: "已保存",
685
+ signIn: "使用华为云账号登录",
686
+ signingIn: "登录中…(请在浏览器完成授权)",
687
+ openManually: "若未自动打开,请手动访问:",
688
+ manualToken: "手动粘贴 token(降级)",
689
+ loginFailed: "登录失败,请重试",
690
+ modelsLoading: "模型勾选区加载中…(若长期不出现,请确认已登录且 DSH 已完全重启)",
691
+ usageTitle: "本机用量",
692
+ usageToday: "今日",
693
+ usageRequests: "{n} 次请求",
694
+ usageTokens: "输入 {prompt} · 输出 {completion}",
695
+ usageAllTime: "累计({days} 天)",
696
+ usageByModel: "今日按模型",
697
+ usageSlots: "会话槽位",
698
+ usageStateOk: "可用",
699
+ usageStateCapped: "撞上限,优先避开",
700
+ usageStateCooling: "冷却中",
701
+ usageStateDisabled: "已停用",
702
+ usageNoQuota: "CodeArts 没有额度接口,这里统计的是本机经插件发出的请求;官方用量明细见",
703
+ usageEmpty: "还没有记录:发一条消息就会开始累计。"
704
+ };
705
+ const en = {
706
+ tabLabel: "CodeArts",
707
+ cardTitle: "DSH CodeArts Connect",
708
+ statusSignedIn: "Signed in",
709
+ statusSignedOut: "Not signed in",
710
+ statusExpired: "Credential expired",
711
+ descSignedIn: "Credential is ready. Checked models show up in the model picker.",
712
+ descSignedOut: "Sign in with your Huawei Cloud account, or paste a CodeArts cloud_dragon_token.",
713
+ storedMeta: "{label} · stored {time}",
714
+ storedMetaNoLabel: "stored {time}",
715
+ refresh: "Refresh",
716
+ clearToken: "Clear credential",
717
+ tokenLabel: "cloud_dragon_token",
718
+ tokenPlaceholder: "Paste the token taken from the CodeArts web/desktop client……",
719
+ labelLabel: "Label (optional)",
720
+ labelPlaceholder: "e.g. account nickname",
721
+ saveToken: "Save token",
722
+ expiredHint: "Your credential has expired. Sign in again to continue; your model selection is kept.",
723
+ accountsTitle: "Accounts",
724
+ accountRemove: "Remove",
725
+ addAccount: "Add account",
726
+ accountsRotateHint: "Multiple accounts stored: requests rotate automatically, so a busy account hands over to the next one instead of making you wait.",
727
+ accountNeedsSignIn: "Needs sign-in",
728
+ accountNoKey: "No AK/SK",
729
+ accountStored: "stored {time}",
730
+ accountExpires: "expires {time}",
731
+ accountExpired: "expired {time}",
732
+ modelsTitle: "Models",
733
+ optionalModelsHint: "Only checked models appear in the model picker.",
734
+ optionalModelsAllHint: "All models show in the picker by default; uncheck the ones you don’t want.",
735
+ selectedCount: "{n} of {total} selected",
736
+ selectAll: "Select all",
737
+ free: "Free",
738
+ saveModels: "Save selection",
739
+ saving: "Saving…",
740
+ saved: "Saved",
741
+ signIn: "Sign in with Huawei Cloud",
742
+ signingIn: "Signing in… (finish authorization in your browser)",
743
+ openManually: "If it did not open automatically, visit:",
744
+ manualToken: "Paste token manually (fallback)",
745
+ loginFailed: "Sign-in failed, please retry",
746
+ modelsLoading: "Loading model selection… (if it never appears, make sure you are signed in and DSH was fully restarted)",
747
+ usageTitle: "Local usage",
748
+ usageToday: "Today",
749
+ usageRequests: "{n} request(s)",
750
+ usageTokens: "in {prompt} · out {completion}",
751
+ usageAllTime: "All time ({days} days)",
752
+ usageByModel: "Today by model",
753
+ usageSlots: "Session slots",
754
+ usageStateOk: "Ready",
755
+ usageStateCapped: "Cap hit, avoiding",
756
+ usageStateCooling: "Cooling down",
757
+ usageStateDisabled: "Disabled",
758
+ usageNoQuota: "CodeArts exposes no quota API — this counts the requests this machine sent through the plugin. Official usage:",
759
+ usageEmpty: "Nothing recorded yet: send a message to start counting."
760
+ };
761
+ //#endregion
762
+ //#region src/client/index.tsx
763
+ const name = "dsh-codearts-client";
764
+ const inject = ["slots", "locale"];
765
+ function apply(ctx) {
766
+ try {
767
+ const namespace = "settings.codearts";
768
+ ctx.effect(() => ctx.locale.register(namespace, {
769
+ zh,
770
+ en
771
+ }), "dsh-codearts: settings copy");
772
+ const t = ctx.locale.bind(namespace);
773
+ ctx.slots.inject("plugins.bundle.config", () => ctx.slots.register({
774
+ name: "plugins.bundle.config",
775
+ key: "dsh-codearts",
776
+ locale: namespace
777
+ }, () => /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CodeArtsPluginCard, { t })));
778
+ } catch (error) {
779
+ console.error("[dsh-codearts] client card failed to load (host provider unaffected):", error);
780
+ }
781
+ }
782
+ //#endregion
783
+ exports.apply = apply;
784
+ exports.inject = inject;
785
+ exports.name = name;
786
+
787
+ return module.exports;
788
+ }
789
+ });