dsh-astudio-connect 0.2.1 → 0.2.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.en.md +8 -2
- package/README.md +8 -2
- package/lib/index.d.ts +2 -0
- package/lib/index.js +3 -1
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -221,7 +221,9 @@ One press is two requests: read the pending list, then report completion. The ba
|
|
|
221
221
|
|
|
222
222
|
The third row is deliberately not worded as "already claimed": the two are not the same state. `11003002` is upstream *saying* the popup was booked; an empty list only says the service is holding no reward at this moment — it may not have been issued yet, or the account may not have travelled with the request. Calling that "already claimed" tells someone to stop pressing a button that would still have worked, which is exactly what an earlier version did.
|
|
223
223
|
|
|
224
|
-
|
|
224
|
+
"Not issued yet" is the common case, not the corner one: **the daily popup is only attached to the account once the desktop app starts.** Measured on `2026-11-05` with AStudio not running, every header combination polled `client-popups/pending` and got an empty list with the balance unchanged (7793); replaying the read-only endpoints the app hits on startup (`membership/me`, `points/summary`, `bot/models/configs`) changed nothing either. Starting the app the same day added 100 straight away. So the plugin can claim, but only on days you have already opened AStudio — otherwise there is no popup and the button truthfully reports "Nothing to claim right now". The headers are not the cause: adding `clientVersion` made no difference in an A/B run.
|
|
225
|
+
|
|
226
|
+
`clientType` (`21` on Windows, `22` on macOS) and `studioVersion` are mandatory (without either, the gateway answers `11001001`). The desktop app also adds `clientVersion` to every request bound for an xfyun domain — both come from `electron.app.getVersion()`, currently `3.6.0` — and the plugin sends all three so its requests match the app's. The version is only shape-checked, which is why a constant works instead of reading the installed app's version, and why this works with AStudio uninstalled.
|
|
225
227
|
|
|
226
228
|
One more detail `pending` will not forgive: `popupId` is a **positive integer**, and `complete` is parsed with `Number.isSafeInteger` upstream — a string makes the desktop client treat the whole popup config as invalid. The plugin used to read it as a string, which filtered out every reward the service sent while still reporting "already claimed", leaving the reward sitting there for the client to book. It now parses ids the way the client does and skips anything non-positive (the `-3` a preview uses, for instance).
|
|
227
229
|
|
|
@@ -283,6 +285,7 @@ Five write routes (probing, visibility, claim, and the two sign-in routes) requi
|
|
|
283
285
|
|
|
284
286
|
| Plugin version | DSH kernel range it supports |
|
|
285
287
|
|---|---|
|
|
288
|
+
| `0.2.2` | `^0.2.1-rc.2` (from `0.2.1-rc.2`, below `0.3.0`) |
|
|
286
289
|
| `0.2.1` | `^0.2.1-rc.2` (from `0.2.1-rc.2`, below `0.3.0`) |
|
|
287
290
|
| `0.2.0` | `^0.2.1-rc.2` (from `0.2.1-rc.2`, below `0.3.0`) |
|
|
288
291
|
| `0.1.1` | `^0.2.1-rc.2` (from `0.2.1-rc.2`, below `0.3.0`) |
|
|
@@ -294,6 +297,8 @@ The plugin declares a kernel range in `peerDependencies`; the host's `evaluatePl
|
|
|
294
297
|
|
|
295
298
|
`0.2.1` is a fix-only release with an unchanged kernel range. **If you are on `0.2.0`, upgrade: its Claim button never actually claimed anything.** Pending popups carry `popupId` as a positive integer, but the plugin read it as a string, so every real reward was filtered out locally, the UI always said "already claimed today", and the reward sat untouched on the server — opening AStudio still claimed it. `0.2.1` parses the id the way the app does, separates "no pending reward" from an explicit `11003002` answer, and sends the four account-scoped cookies the claim endpoints expect.
|
|
296
299
|
|
|
300
|
+
`0.2.2` only aligns the request headers, and **does not fix the "claimable only while the client is running" symptom**. Two changes: a new `clientVersion` header (constant `3.6.0`), and `studioVersion` moving from `3.5.5` to `3.6.0` — the desktop app's `fetchWithClientVersion` adds the former to every xfyun request and the plugin never sent it at all. An A/B run before and after this release showed the header is not the cause (see [Known limitations](#known-limitations)), so what this version actually delivers is making a plugin request indistinguishable from the app's, plus writing the real constraint into the docs: the daily reward is only issued after the desktop app has started. Any release note claiming this version fixed claiming is wrong.
|
|
301
|
+
|
|
297
302
|
## When the upstream refuses a request
|
|
298
303
|
|
|
299
304
|
maas-api answers a non-conforming request with a bare `10005 invalid request` and never names the field. The plugin heals the request in the forwarding layer, in this order, without DSH or pi-ai having to change:
|
|
@@ -322,7 +327,8 @@ A refused body is also written to `%TEMP%\dsh-astudio-connect\failed-requests\`
|
|
|
322
327
|
- [ ] **QR sign-in depends on three private upstream endpoints**: `scanlogin/qrcode` and `scanlogin/uids` on `sso.xfyun.cn`, plus the `api_key` inside `bot/models/configs`. If upstream adds a captcha, a signature or a device fingerprint, sign-in stops working (the panel then says "Sign-in is unavailable"), though a credential already stored keeps working.
|
|
323
328
|
- [ ] **A stored sign-in is not refreshed**: once its `ssoSessionId` expires you have to scan again; the plugin does not renew it (upstream exposes no renewal endpoint — the client simply signs in again).
|
|
324
329
|
- [ ] **One QR sign-in per DSH home**: switching accounts means signing out first; no multi-account coexistence.
|
|
325
|
-
- [ ] **The claim button depends on
|
|
330
|
+
- [ ] **The claim button depends on three hard-coded client identity headers**: `clientType` (platform), `studioVersion` and `clientVersion` (both constants, `3.6.0`, tracking the current client release). If upstream ever demands a build number, a signature or a device fingerprint, this path dies immediately and the button will only report "Unavailable".
|
|
331
|
+
- [ ] **The daily reward is only claimable after the desktop app has run**: without the app, upstream never attaches the day's popup, so the plugin polls an empty list and the button truthfully reports "Nothing to claim right now". Measured on `2026-11-05` with the app closed: three header combinations plus a replay of the app's startup endpoints all left it empty; starting the app the same day added 100 immediately. This is upstream's issuance timing, not a defect the plugin can fix — claiming from DSH requires opening AStudio once that day.
|
|
326
332
|
- [ ] **The CLI's `status` now issues one live fetch**: it waits for a real request so it can report the actual catalog source and model count; offline or signed out, it reports `empty` with the matching failure.
|
|
327
333
|
- [ ] **No account-switch following**: unlike WorkBuddy's two variants, AStudio is a single product, so the plugin does not replicate variant-level capabilities.
|
|
328
334
|
|
package/README.md
CHANGED
|
@@ -221,7 +221,9 @@ GET agent.xfyun.cn/xingchen-studio/bot/models/configs → Cookie 用上
|
|
|
221
221
|
|
|
222
222
|
第三种情况不写成「今日已领过」,因为这两种状态并不等价:`11003002` 是上游**明确**说这条弹窗早就被核销了;而列表为空只说明服务端此刻没挂着奖励,也可能只是今天还没下发,或者账号信息没有传全。把后者说成「已领过」,人就再也不会去点第二次了——早期版本正是在这里骗了用户。
|
|
223
223
|
|
|
224
|
-
|
|
224
|
+
而「今天还没下发」这句话比想象中更常成立:**每日弹窗是桌面端启动之后才挂到账号上的**。实测(`2026-11-05`,客户端完全没开)三个请求头组合轮询 `client-popups/pending` 全部返回空列表、余额纹丝不动(7793);把桌面端启动的那些只读接口(`membership/me`、`points/summary`、`bot/models/configs`)重放一遍,结论一样。同日启动客户端,余额随即 +100。所以插件能领,但前提是这一天你已经启动过 AStudio——不启动就不会有弹窗,按钮只能如实报「当前没有可领取的奖励」。请求头不是原因:补上 `clientVersion` 之后 A/B 结果没有任何变化。
|
|
225
|
+
|
|
226
|
+
`clientType`(Windows `21` / macOS `22`)与 `studioVersion` 是硬性要求(缺任一个,网关直接回 `11001001`)。桌面端还会给所有讯飞域名的请求额外加一个 `clientVersion`(两者都取自 `electron.app.getVersion()`,当前是 `3.6.0`);插件三个头都发,保持与客户端请求一致。版本号只做形态校验,所以用常量而不是去读已安装的 AStudio 版本——这正是它能做到「不需要装 AStudio」的原因。
|
|
225
227
|
|
|
226
228
|
`pending` 的返回里还有一个必须按原样解析的细节:`popupId` 是**正整数**,`complete` 上游也用 `Number.isSafeInteger` 校验,客户端拿到字符串会直接判定整条弹窗配置非法。插件早期按字符串收,结果服务端下发的每一条奖励都被自己过滤掉了,界面照样报「今日已领过」,而奖励其实还老老实实躺在服务端——客户端一点就能领。现在按客户端的方式解析,非正整数的 id(例如预览用的 `-3`)直接跳过。
|
|
227
229
|
|
|
@@ -283,6 +285,7 @@ GET agent.xfyun.cn/xingchen-studio/bot/models/configs → Cookie 用上
|
|
|
283
285
|
|
|
284
286
|
| 插件版本 | 支持的 DSH 内核版本 |
|
|
285
287
|
|---|---|
|
|
288
|
+
| `0.2.2` | `^0.2.1-rc.2`(`0.2.1-rc.2` 起,`0.3.0` 以下) |
|
|
286
289
|
| `0.2.1` | `^0.2.1-rc.2`(`0.2.1-rc.2` 起,`0.3.0` 以下) |
|
|
287
290
|
| `0.2.0` | `^0.2.1-rc.2`(`0.2.1-rc.2` 起,`0.3.0` 以下) |
|
|
288
291
|
| `0.1.1` | `^0.2.1-rc.2`(`0.2.1-rc.2` 起,`0.3.0` 以下) |
|
|
@@ -294,6 +297,8 @@ GET agent.xfyun.cn/xingchen-studio/bot/models/configs → Cookie 用上
|
|
|
294
297
|
|
|
295
298
|
`0.2.1` 是纯修复版,内核范围不变。**装了 `0.2.0` 的请升级:那一版的「领取」按钮实际领不到积分。** 待领弹窗的 `popupId` 是正整数,插件却按字符串接收,于是每条真实奖励都在本地被过滤掉,界面一律报「今日已领过」,而奖励还挂在服务端——打开 AStudio 客户端照样能领。`0.2.1` 按客户端的方式解析 id,把「待领列表为空」与「上游明确回 `11003002`」拆成两种结果,领取请求也补齐了按账户鉴权的四个 cookie。
|
|
296
299
|
|
|
300
|
+
`0.2.2` 只做请求头对齐,**不解决「只有客户端开着才能领」那个现象**。改动有两处:新增 `clientVersion`(常量 `3.6.0`),`studioVersion` 从 `3.5.5` 提到 `3.6.0`——桌面端的 `fetchWithClientVersion` 会给所有讯飞域名请求加这个头,插件此前完全没有发过。发版前后的 A/B 实测表明这个头不是原因(见[已知限制](#已知限制)),所以这版的实际价值是把「插件发出的请求与客户端无法区分」这件事做实,以及把「每日奖励只在桌面端启动后才下发」这个限制如实写进文档。谁要是在版本说明里看到这版修好了领取,那话说错了。
|
|
301
|
+
|
|
297
302
|
## 请求被上游拒绝时
|
|
298
303
|
|
|
299
304
|
maas-api 对不合规的请求只回一句 `10005 invalid request`,不说明是哪个字段。插件按下面的顺序自愈,全部发生在转发层,DSH 与 pi-ai 不需要改动:
|
|
@@ -322,7 +327,8 @@ maas-api 对不合规的请求只回一句 `10005 invalid request`,不说明
|
|
|
322
327
|
- [ ] **扫码登录依赖上游三个私有接口**:`sso.xfyun.cn` 的 `scanlogin/qrcode` 与 `scanlogin/uids`,以及 `bot/models/configs` 里的 `api_key`。上游若加验证码、签名或设备指纹,扫码登录会直接失效(届时只显示「登录暂不可用」),但已保存的凭据仍然可用。
|
|
323
328
|
- [ ] **扫码登录的凭据不会被主动刷新**:`ssoSessionId` 过期后需要重新扫码;插件不会拿它去换新(上游也没有公开的续期接口,客户端是重新登录)。
|
|
324
329
|
- [ ] **一个 DSH 只保存一个扫码登录**:后期换账号需要先「退出登录」再扫,不做多账号并存。
|
|
325
|
-
- [ ]
|
|
330
|
+
- [ ] **领取按钮依赖三个硬编码的客户端身份头**:`clientType`(平台)、`studioVersion` 与 `clientVersion`(后两者都是常量 `3.6.0`,跟随当前客户端版本)。上游一旦要求构建号、签名或设备指纹,这条路会立即失效,届时按钮只会显示「暂不可用」。
|
|
331
|
+
- [ ] **每日奖励只在桌面端启动之后才可领**:客户端不启动,服务端就不挂当天的弹窗,插件轮到的永远是空列表,按钮只能如实报「当前没有可领取的奖励」。实测(`2026-11-05`,客户端未运行)请求头三种组合、外加重放客户端启动时的只读接口,都改变不了这一点;同日启动客户端后余额立即 +100。这不是插件能修的缺陷,而是上游的发放时机——想当天在 DSH 里领,就得先开一次 AStudio。
|
|
326
332
|
- [ ] **CLI 的 `status` 会发起一次实时刷新**:它现在等待一次真实请求,才能如实报出目录来源与模型数;离线或未登录时报告 `empty` 与对应的失败原因。
|
|
327
333
|
- [ ] **不做账号切换跟随**:与 WorkBuddy 双 variant 不同,AStudio 只有一个产品,插件不复制 variant 级能力。
|
|
328
334
|
|
package/lib/index.d.ts
CHANGED
|
@@ -345,6 +345,8 @@ interface AStudioDailyRewardClientOptions {
|
|
|
345
345
|
clientType?: string | undefined;
|
|
346
346
|
/** Overrides {@link ASTRO_STUDIO_VERSION}. */
|
|
347
347
|
studioVersion?: string;
|
|
348
|
+
/** Overrides {@link ASTRO_CLIENT_VERSION}. */
|
|
349
|
+
clientVersion?: string;
|
|
348
350
|
/** Per-call timeout. */
|
|
349
351
|
timeoutMs?: number;
|
|
350
352
|
}
|
package/lib/index.js
CHANGED
|
@@ -2476,7 +2476,8 @@ function claimCookie(credentials) {
|
|
|
2476
2476
|
function createAStudioDailyRewardClient(options) {
|
|
2477
2477
|
const fetchImpl = options.fetchImpl ?? fetch;
|
|
2478
2478
|
const clientType = "clientType" in options ? options.clientType : astudioClientType();
|
|
2479
|
-
const studioVersion = options.studioVersion ?? "3.
|
|
2479
|
+
const studioVersion = options.studioVersion ?? "3.6.0";
|
|
2480
|
+
const clientVersion = options.clientVersion ?? "3.6.0";
|
|
2480
2481
|
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS$1;
|
|
2481
2482
|
const call = async (credentials, path, init = {}) => {
|
|
2482
2483
|
let response;
|
|
@@ -2488,6 +2489,7 @@ function createAStudioDailyRewardClient(options) {
|
|
|
2488
2489
|
Cookie: claimCookie(credentials),
|
|
2489
2490
|
...clientType === void 0 ? {} : { clientType },
|
|
2490
2491
|
studioVersion,
|
|
2492
|
+
clientVersion,
|
|
2491
2493
|
...init.headers ?? {}
|
|
2492
2494
|
},
|
|
2493
2495
|
signal: AbortSignal.timeout(timeoutMs)
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "dsh-astudio-connect",
|
|
3
3
|
"displayName": "DSH AStudio Connect",
|
|
4
4
|
"description": "将 AStudio 应用中已登录的模型复用到 DeepSeek Harness — bring AStudio app models into DeepSeek Harness with zero configuration.",
|
|
5
|
-
"version": "0.2.
|
|
5
|
+
"version": "0.2.2",
|
|
6
6
|
"author": "astudio-connect",
|
|
7
7
|
"keywords": [
|
|
8
8
|
"dsh-plugin",
|