dsh-codearts 0.4.0 → 0.4.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.
- package/DEV.md +29 -0
- package/lib/bin.mjs +2 -2
- package/lib/client/index.d.cts +2 -4
- package/lib/client/index.js +46 -68
- package/lib/index.mjs +3 -4
- package/lib/{usage-3W88T_H1.mjs → usage-D6EeUWiQ.mjs} +12 -7
- package/package.json +1 -1
package/DEV.md
CHANGED
|
@@ -40,6 +40,35 @@ pnpm run hmr:off # 关掉,回到 base 默认(只监听 profile 配置
|
|
|
40
40
|
|
|
41
41
|
改完这个 patch 通常不用重启:profile 的 patch 文件本身也在 HMR 的监听范围内(profile 里 `patchReload: live`),条目会重新加载。若发现没生效,重启一次 DSH 即可,之后就一直有效。
|
|
42
42
|
|
|
43
|
+
> ⚠️ **开了模块监听就别用插件管理器/npm 升级本插件。** 宿主为热重载监视着
|
|
44
|
+
> `node_modules/dsh-codearts`,目录被占用后 pnpm 替换版本时会失败:
|
|
45
|
+
>
|
|
46
|
+
> ```
|
|
47
|
+
> [ERR_PNPM_EPERM] [importPackage ...\node_modules\dsh-codearts]
|
|
48
|
+
> EPERM: operation not permitted, rename
|
|
49
|
+
> '...\dsh-codearts_tmp_20976_1' -> '...\dsh-codearts'
|
|
50
|
+
> ```
|
|
51
|
+
>
|
|
52
|
+
> 更麻烦的是失败后**插件管理器会回滚**:把 `dsh-codearts` 从 profile 的
|
|
53
|
+
> `dependencies` 和 `bundles` 里一起删掉,表现为「插件列表里它没了」。升级前的正确顺序是
|
|
54
|
+
> `pnpm run hmr:off` → 升级 → (要接着开发再)`pnpm run hmr:on`。
|
|
55
|
+
>
|
|
56
|
+
> 这条只影响**跑过 `hmr:on` 的开发机**:该覆盖行写在 profile 的
|
|
57
|
+
> `cordis.patch.yml` 里,插件包自带的 patch 只有 `insert: llm-codearts`,
|
|
58
|
+
> 普通用户从 dshmarket 直接升级不会碰到。DSH base 的 desktop bundle 里默认是
|
|
59
|
+
> **不监视模块**的(原文,`app.asar` 内 base 的 patch):
|
|
60
|
+
>
|
|
61
|
+
> ```yaml
|
|
62
|
+
> # Profile configuration reloads by default; module roots are opt-in.
|
|
63
|
+
> - id: hmr
|
|
64
|
+
> name: '@deepseek-ai/dsh-hmr'
|
|
65
|
+
> disabled: !!js "!ctx.get('profileContext')"
|
|
66
|
+
> config:
|
|
67
|
+
> root: []
|
|
68
|
+
> ```
|
|
69
|
+
>
|
|
70
|
+
> 即 `root` 默认空表 —— 没人去开它,就没有句柄占用 `node_modules/dsh-codearts`。
|
|
71
|
+
|
|
43
72
|
## 日常循环
|
|
44
73
|
|
|
45
74
|
```sh
|
package/lib/bin.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { C as codeartsAccountsPath, b as isBenefitModel, n as codeartsUsagePath, r as discoverModels, t as CodeArtsUsageTracker, u as fetchCallerIdentity, v as FALLBACK_CODEARTS_MODELS, x as CodeArtsAccountStore } from "./usage-
|
|
2
|
+
import { C as codeartsAccountsPath, b as isBenefitModel, n as codeartsUsagePath, r as discoverModels, t as CodeArtsUsageTracker, u as fetchCallerIdentity, v as FALLBACK_CODEARTS_MODELS, x as CodeArtsAccountStore } from "./usage-D6EeUWiQ.mjs";
|
|
3
3
|
import { existsSync, statSync } from "node:fs";
|
|
4
4
|
//#region src/version.ts
|
|
5
|
-
const CODEARTS_VERSION = "0.
|
|
5
|
+
const CODEARTS_VERSION = "0.4.1";
|
|
6
6
|
//#endregion
|
|
7
7
|
//#region src/bin.ts
|
|
8
8
|
/**
|
package/lib/client/index.d.cts
CHANGED
|
@@ -67,10 +67,8 @@ interface CodeArtsSettingsKey {
|
|
|
67
67
|
creditsUnavailable: string;
|
|
68
68
|
creditsDock: string;
|
|
69
69
|
creditsDockTitle: string;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
claimSuccess: string;
|
|
73
|
-
claimFailed: string;
|
|
70
|
+
signInButton: string;
|
|
71
|
+
signInHint: string;
|
|
74
72
|
[key: string]: string;
|
|
75
73
|
}
|
|
76
74
|
//#endregion
|
package/lib/client/index.js
CHANGED
|
@@ -18,32 +18,32 @@ if (typeof document !== "undefined" && document.querySelector("style[data-plugin
|
|
|
18
18
|
document.head.appendChild(tag);
|
|
19
19
|
}
|
|
20
20
|
var CodeArtsPluginCard_module_css_default = {
|
|
21
|
-
"
|
|
22
|
-
"
|
|
21
|
+
"manual": "DZPfya_manual",
|
|
22
|
+
"area": "DZPfya_area",
|
|
23
|
+
"error": "DZPfya_error",
|
|
23
24
|
"choiceRow": "DZPfya_choiceRow",
|
|
25
|
+
"fieldLabel": "DZPfya_fieldLabel",
|
|
26
|
+
"desc": "DZPfya_desc",
|
|
27
|
+
"card": "DZPfya_card",
|
|
28
|
+
"field": "DZPfya_field",
|
|
24
29
|
"header": "DZPfya_header",
|
|
30
|
+
"link": "DZPfya_link",
|
|
25
31
|
"manualSummary": "DZPfya_manualSummary",
|
|
26
|
-
"
|
|
32
|
+
"section": "DZPfya_section",
|
|
33
|
+
"sectionLabel": "DZPfya_sectionLabel",
|
|
34
|
+
"headText": "DZPfya_headText",
|
|
35
|
+
"statusLine": "DZPfya_statusLine",
|
|
27
36
|
"meta": "DZPfya_meta",
|
|
28
|
-
"link": "DZPfya_link",
|
|
29
|
-
"area": "DZPfya_area",
|
|
30
37
|
"headActions": "DZPfya_headActions",
|
|
31
|
-
"hint": "DZPfya_hint",
|
|
32
|
-
"statusLine": "DZPfya_statusLine",
|
|
33
|
-
"check": "DZPfya_check",
|
|
34
|
-
"manual": "DZPfya_manual",
|
|
35
|
-
"desc": "DZPfya_desc",
|
|
36
|
-
"fieldLabel": "DZPfya_fieldLabel",
|
|
37
38
|
"body": "DZPfya_body",
|
|
38
|
-
"section": "DZPfya_section",
|
|
39
|
-
"card": "DZPfya_card",
|
|
40
|
-
"name": "DZPfya_name",
|
|
41
39
|
"sectionHead": "DZPfya_sectionHead",
|
|
42
|
-
"
|
|
40
|
+
"name": "DZPfya_name",
|
|
41
|
+
"actions": "DZPfya_actions",
|
|
42
|
+
"danger": "DZPfya_danger",
|
|
43
43
|
"count": "DZPfya_count",
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"
|
|
44
|
+
"hint": "DZPfya_hint",
|
|
45
|
+
"choices": "DZPfya_choices",
|
|
46
|
+
"check": "DZPfya_check"
|
|
47
47
|
};
|
|
48
48
|
//#endregion
|
|
49
49
|
//#region src/client/CodeArtsPluginCard.tsx
|
|
@@ -84,47 +84,31 @@ function formatCredits(value) {
|
|
|
84
84
|
return Number.isFinite(value) ? new Intl.NumberFormat().format(Math.round(value)) : "0";
|
|
85
85
|
}
|
|
86
86
|
/**
|
|
87
|
+
* 签到领积分的入口页。
|
|
88
|
+
*
|
|
89
|
+
* 官方 CodeArts Agent 客户端里,用户菜单的「活动福利(签到领 1000 积分)」点击后
|
|
90
|
+
* **不发任何接口请求**,只是用系统浏览器打开这个页面(SnapChat 的 isActivity 分支 →
|
|
91
|
+
* `jumpToBrowser(INIT_CONFIG.personalUsageSettings, isOutSideOpen: true)`,URL 来自
|
|
92
|
+
* `vscode-codebot/product.json`)。也就是说积分的签到动作只在那一页上完成,AK/SK
|
|
93
|
+
* 网关那套(benefit/claim、statistics/plugin)里没有任何发积分的接口 —— 详见
|
|
94
|
+
* src/upstream.ts 的 claimBenefit:它开通的是「限时福利免费模型」渠道,不是积分。
|
|
95
|
+
*/
|
|
96
|
+
const CODEARTS_SIGN_IN_URL = "https://codearts.huaweicloud.com/portal/settings/personal-usage";
|
|
97
|
+
/** 打开签到页;带 locale 参数,与官方客户端的拼法一致。 */
|
|
98
|
+
function openSignInPage() {
|
|
99
|
+
if (typeof window === "undefined") return;
|
|
100
|
+
const locale = (typeof navigator === "undefined" ? "" : navigator.language ?? "").toLowerCase().startsWith("en") ? "en-us" : "zh-cn";
|
|
101
|
+
window.open(`${CODEARTS_SIGN_IN_URL}?locale=${locale}`, "_blank", "noopener");
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
87
104
|
* 积分区块。
|
|
88
105
|
*
|
|
89
106
|
* 2026-10 从官方 CodeArts Agent 客户端挖出积分接口并实测通过(见 src/credits.ts),
|
|
90
107
|
* 所以这里能直接显示账号总额度 —— 与下面的「本机用量」互补:一个是账号级、一个是
|
|
91
108
|
* 本机级。拉不到时显示原因(creditsError),不静默吞掉。
|
|
92
109
|
*/
|
|
93
|
-
function CreditsSection({ credits, error, t
|
|
94
|
-
const [claimState, setClaimState] = (0, react.useState)(() => {
|
|
95
|
-
try {
|
|
96
|
-
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
97
|
-
if (typeof localStorage !== "undefined" && localStorage.getItem("codearts-claim-date") === today) return "success";
|
|
98
|
-
} catch {}
|
|
99
|
-
return "idle";
|
|
100
|
-
});
|
|
101
|
-
const [claimMessage, setClaimMessage] = (0, react.useState)("");
|
|
110
|
+
function CreditsSection({ credits, error, t }) {
|
|
102
111
|
if (credits === void 0 && error === void 0) return null;
|
|
103
|
-
const handleClaim = async () => {
|
|
104
|
-
setClaimState("loading");
|
|
105
|
-
try {
|
|
106
|
-
const res = await fetch("/api/codearts/claim", {
|
|
107
|
-
method: "POST",
|
|
108
|
-
headers: { Accept: "application/json" },
|
|
109
|
-
credentials: "same-origin"
|
|
110
|
-
});
|
|
111
|
-
const data = await res.json().catch(() => void 0);
|
|
112
|
-
if (res.ok && data?.ok === true) {
|
|
113
|
-
setClaimState("success");
|
|
114
|
-
try {
|
|
115
|
-
const today = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
|
|
116
|
-
if (typeof localStorage !== "undefined") localStorage.setItem("codearts-claim-date", today);
|
|
117
|
-
} catch {}
|
|
118
|
-
onClaimed?.();
|
|
119
|
-
} else {
|
|
120
|
-
setClaimState("error");
|
|
121
|
-
setClaimMessage(data?.message ?? `HTTP ${res.status}`);
|
|
122
|
-
}
|
|
123
|
-
} catch (err) {
|
|
124
|
-
setClaimState("error");
|
|
125
|
-
setClaimMessage(err instanceof Error ? err.message : String(err));
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
112
|
const c = credits?.credits;
|
|
129
113
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
130
114
|
className: CodeArtsPluginCard_module_css_default.section,
|
|
@@ -142,12 +126,11 @@ function CreditsSection({ credits, error, t, onClaimed }) {
|
|
|
142
126
|
remain: formatCredits(c.total.remain),
|
|
143
127
|
total: formatCredits(c.total.total)
|
|
144
128
|
})
|
|
145
|
-
}),
|
|
129
|
+
}), /* @__PURE__ */ (0, react_jsx_runtime.jsx)(_deepseek_ai_dsh_client_ui_primitives.Button, {
|
|
146
130
|
variant: "outline",
|
|
147
131
|
size: "sm",
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
children: claimState === "loading" ? t("claiming") : claimState === "success" ? t("claimSuccess") : t("claimButton")
|
|
132
|
+
onClick: () => openSignInPage(),
|
|
133
|
+
children: t("signInButton")
|
|
151
134
|
})]
|
|
152
135
|
})]
|
|
153
136
|
}),
|
|
@@ -155,9 +138,9 @@ function CreditsSection({ credits, error, t, onClaimed }) {
|
|
|
155
138
|
className: CodeArtsPluginCard_module_css_default.hint,
|
|
156
139
|
children: t("creditsUnavailable", { message: error })
|
|
157
140
|
}),
|
|
158
|
-
|
|
141
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
159
142
|
className: CodeArtsPluginCard_module_css_default.hint,
|
|
160
|
-
children: t("
|
|
143
|
+
children: t("signInHint")
|
|
161
144
|
}),
|
|
162
145
|
c !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [
|
|
163
146
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
@@ -780,8 +763,7 @@ function CodeArtsPluginCard({ t }) {
|
|
|
780
763
|
signedIn && (status?.credits !== void 0 || status?.creditsError !== void 0) && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(CreditsSection, {
|
|
781
764
|
credits: status?.credits,
|
|
782
765
|
error: status?.creditsError,
|
|
783
|
-
t
|
|
784
|
-
onClaimed: () => void refresh()
|
|
766
|
+
t
|
|
785
767
|
}),
|
|
786
768
|
status?.usage !== void 0 && /* @__PURE__ */ (0, react_jsx_runtime.jsx)(UsageSection, {
|
|
787
769
|
usage: status.usage,
|
|
@@ -948,10 +930,8 @@ const zh = {
|
|
|
948
930
|
creditsUnavailable: "积分不可用:{message}",
|
|
949
931
|
creditsDock: "积分 {remain}",
|
|
950
932
|
creditsDockTitle: "CodeArts 剩余积分 {remain} / {total}",
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
claimSuccess: "已领取",
|
|
954
|
-
claimFailed: "领取失败:{message}"
|
|
933
|
+
signInButton: "去签到领积分",
|
|
934
|
+
signInHint: "积分由 CodeArts 官网活动页发放,签到要在官网页面完成(和官方客户端同一入口)。"
|
|
955
935
|
};
|
|
956
936
|
const en = {
|
|
957
937
|
tabLabel: "CodeArts",
|
|
@@ -1020,10 +1000,8 @@ const en = {
|
|
|
1020
1000
|
creditsUnavailable: "Credits unavailable: {message}",
|
|
1021
1001
|
creditsDock: "Credits {remain}",
|
|
1022
1002
|
creditsDockTitle: "CodeArts credits left {remain} / {total}",
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
claimSuccess: "Claimed",
|
|
1026
|
-
claimFailed: "Claim failed: {message}"
|
|
1003
|
+
signInButton: "Check in for credits",
|
|
1004
|
+
signInHint: "Credits are issued on the CodeArts portal; check-in happens on that page (same entry as the official client)."
|
|
1027
1005
|
};
|
|
1028
1006
|
//#endregion
|
|
1029
1007
|
//#region src/client/index.tsx
|
package/lib/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as codeartsAccountsPath, S as CodeArtsCredentialStore, T as startLogin, _ as CodeArtsCatalog, a as SNAP_HOST, b as isBenefitModel, c as claimBenefit, d as fetchModels, f as isConcurrencyCap, g as signedGet, h as prepareChatBody, i as refreshCatalog, l as degradeTokenCeiling, m as maxTokensCeilingFor, n as codeartsUsagePath, o as canonicalModel, p as isParamInvalidFrame, r as discoverModels, s as chatStream, t as CodeArtsUsageTracker, u as fetchCallerIdentity, v as FALLBACK_CODEARTS_MODELS, w as codeartsAuthPath, x as CodeArtsAccountStore, y as filterEnabledModels } from "./usage-
|
|
1
|
+
import { C as codeartsAccountsPath, S as CodeArtsCredentialStore, T as startLogin, _ as CodeArtsCatalog, a as SNAP_HOST, b as isBenefitModel, c as claimBenefit, d as fetchModels, f as isConcurrencyCap, g as signedGet, h as prepareChatBody, i as refreshCatalog, l as degradeTokenCeiling, m as maxTokensCeilingFor, n as codeartsUsagePath, o as canonicalModel, p as isParamInvalidFrame, r as discoverModels, s as chatStream, t as CodeArtsUsageTracker, u as fetchCallerIdentity, v as FALLBACK_CODEARTS_MODELS, w as codeartsAuthPath, x as CodeArtsAccountStore, y as filterEnabledModels } from "./usage-D6EeUWiQ.mjs";
|
|
2
2
|
import z from "@deepseek-ai/schemastery";
|
|
3
3
|
import { randomBytes, timingSafeEqual } from "node:crypto";
|
|
4
4
|
import { createServer } from "node:http";
|
|
@@ -999,7 +999,7 @@ const CODEARTS_LOGIN_PATH = "/api/codearts/login";
|
|
|
999
999
|
const CODEARTS_LOGIN_STATUS_PATH = "/api/codearts/login/status";
|
|
1000
1000
|
/** 删除某个账号:DELETE /api/codearts/accounts?id=<accountId> */
|
|
1001
1001
|
const CODEARTS_ACCOUNTS_PATH = "/api/codearts/accounts";
|
|
1002
|
-
/** POST /api/codearts/claim —
|
|
1002
|
+
/** POST /api/codearts/claim — 开通「限时福利」免费模型渠道(幂等);**不发积分**。 */
|
|
1003
1003
|
const CODEARTS_CLAIM_PATH = "/api/codearts/claim";
|
|
1004
1004
|
/**
|
|
1005
1005
|
* 由完整目录 + 已存 enabled 计算 selection。
|
|
@@ -1333,7 +1333,7 @@ function accountsHandler(deps) {
|
|
|
1333
1333
|
}
|
|
1334
1334
|
};
|
|
1335
1335
|
}
|
|
1336
|
-
/** POST /api/codearts/claim —
|
|
1336
|
+
/** POST /api/codearts/claim — 开通「限时福利」免费模型渠道(幂等);**不发积分**。 */
|
|
1337
1337
|
function claimHandler(deps) {
|
|
1338
1338
|
return async (req, res) => {
|
|
1339
1339
|
if (req.method !== "POST") {
|
|
@@ -1655,7 +1655,6 @@ function apply(ctx, rawConfig) {
|
|
|
1655
1655
|
const resolved = await store.resolve(id);
|
|
1656
1656
|
if (resolved === void 0) continue;
|
|
1657
1657
|
await claimBenefit(resolved, AbortSignal.timeout(1e4));
|
|
1658
|
-
credits.invalidate();
|
|
1659
1658
|
return { ok: true };
|
|
1660
1659
|
}
|
|
1661
1660
|
return {
|
|
@@ -1883,9 +1883,14 @@ async function fetchModels(credential, signal) {
|
|
|
1883
1883
|
};
|
|
1884
1884
|
}
|
|
1885
1885
|
/**
|
|
1886
|
-
*
|
|
1887
|
-
*
|
|
1886
|
+
* 开通「限时福利」(免费模型)渠道,幂等:已开通就原样返回。官方客户端打开模型菜单
|
|
1887
|
+
* 即调用(GET),用户点「领取」时也调(POST)——两种方法实测都返回 200/0000。
|
|
1888
|
+
* 不开通时福利模型调用必报 InferHub.4004.200 benefit not found。
|
|
1888
1889
|
* 需要 AK/SK 签名(凭证要带 accessKeyId/secretAccessKey)。
|
|
1890
|
+
*
|
|
1891
|
+
* **它不发积分。** 返回体只是一条渠道开通记录(channel / create_time / update_time,
|
|
1892
|
+
* 幂等所以时间戳是旧的),账号积分由套餐决定(见 credits.ts),领取动作在官网签到页。
|
|
1893
|
+
* 别把它当「领取积分」用 —— 早先卡片这么用,结果就是「点了显示已领取、积分没变」。
|
|
1889
1894
|
*/
|
|
1890
1895
|
async function claimBenefit(credential, abort) {
|
|
1891
1896
|
if (!credential.accessKeyId || !credential.secretAccessKey) return;
|
|
@@ -1908,13 +1913,13 @@ async function claimBenefit(credential, abort) {
|
|
|
1908
1913
|
const resp = await fetch(req, { signal: abort });
|
|
1909
1914
|
const raw = await resp.text().catch(() => "");
|
|
1910
1915
|
if (!resp.ok) throw new Error(`claim benefit failed: ${resp.status} ${raw.slice(0, 200)}`);
|
|
1916
|
+
let json;
|
|
1911
1917
|
try {
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1915
|
-
if (e instanceof SyntaxError) return;
|
|
1916
|
-
throw e;
|
|
1918
|
+
json = JSON.parse(raw);
|
|
1919
|
+
} catch {
|
|
1920
|
+
throw new Error(`claim benefit: unexpected non-JSON response: ${raw.slice(0, 200)}`);
|
|
1917
1921
|
}
|
|
1922
|
+
if (json.error_code !== "0000") throw new Error(`claim benefit rejected: ${json.error_code ?? "(no error_code)"} ${json.error_msg ?? ""}`.trim());
|
|
1918
1923
|
}
|
|
1919
1924
|
//#endregion
|
|
1920
1925
|
//#region src/discovery.ts
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "dsh-codearts",
|
|
3
3
|
"displayName": "DSH CodeArts Connect",
|
|
4
4
|
"description": "把华为云 CodeArts 接入 DeepSeek Harness —— 内置 OAuth2 登录(PKCE + DPoP),登录后即可在 DSH 对话窗口使用 CodeArts 的模型。",
|
|
5
|
-
"version": "0.4.
|
|
5
|
+
"version": "0.4.1",
|
|
6
6
|
"author": "elegant01",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"dsh-plugin",
|