dsh-connect-minimaxcode 0.5.5 → 0.5.6
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 +497 -490
- package/README.md +8 -1
- package/lib/index.d.ts +3 -2
- package/lib/index.js +150 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -89,7 +89,7 @@ Web profile 把 `--profile desktop` 换成 `--profile web`。
|
|
|
89
89
|
|
|
90
90
|
```bash
|
|
91
91
|
pnpm pack
|
|
92
|
-
dsh plugin --profile desktop add ./dsh-connect-minimaxcode-0.5.
|
|
92
|
+
dsh plugin --profile desktop add ./dsh-connect-minimaxcode-0.5.6.tgz
|
|
93
93
|
```
|
|
94
94
|
> 桌面版的 profile 由 Electron 应用独占,若 `dsh` 命令不在 PATH 中,请使用 DSH 应用自带的载体 CLI(路径随安装位置而变,例如 `<DSH安装目录>\resources\runtime\cli\bin\dsh.cmd`)。
|
|
95
95
|
|
|
@@ -340,6 +340,13 @@ OAuth 令牌有效期约 1 小时,由客户端自动续期。插件**只在自
|
|
|
340
340
|
|
|
341
341
|
## 更新记录
|
|
342
342
|
|
|
343
|
+
### 0.5.6(2026-11-09)
|
|
344
|
+
|
|
345
|
+
- **修复「模型请求全部失败,但积分/签到正常」**:这是两条凭证路径读的不是同一个文件。模型网关此前只认插件自登录与桌面 App 留下的**旧版 JWT**(`local-runtime.auth.json`),而新版 App 早已改用 OAuth 存储(`auth/prod/<region>/mcode-public/auth.json`,`mmoat_` 令牌)。旧 JWT 过期后网关一律回 `401 auth failed`,而积分走的是 OAuth 文件,于是出现「积分能看、模型不通」。现在网关依次尝试:插件自登录 → **桌面 App 的 OAuth 授权** → 旧版 JWT,三者取第一个可用的。
|
|
346
|
+
- **修复「令牌被上游吊销后永不重登」**:吊销不会改动本地记录的过期时间,而此前的续期判断**只看过期时间**,于是死令牌被一直使用,所有请求 401,界面却仍显示已登录、也没有重新登录入口。现在账户接口返回 `401` 会触发一次强制续期;续期被拒(`400`/`401`/`invalid_grant`,或凭据本身没有 refresh token)则删除该凭据、清空缓存状态,卡片改为提示重新登录。**续期的网络错误与 `5xx` 不算吊销**,不会因为上游一时抽风就把人登出。
|
|
347
|
+
- **修复状态卡把「可用」报成「已过期」**:卡片的登录态此前只读旧 JWT,因此网关明明能通也显示 `expired`。现在它描述的是**网关实际会用的那枚凭据**,并新增 `credential-revoked` / `credential-expired` 两种更贴切的提示文案(指向卡片上的登录按钮,而不是「去桌面 App 登录后重启 DSH」)。
|
|
348
|
+
- 新增 `tests/revoked-credential.spec.ts`(6 个用例)钉住:401 后凭据被删除且卡片转为未登录、被拒时给出「重新登录」提示、`503` 不会误删凭据、无桌面 App 时插件自登录显示为已登录、OAuth 授权优先于旧 JWT、状态文档不泄露任何令牌。全量 193 个用例通过。
|
|
349
|
+
|
|
343
350
|
### 0.5.5(2026-11-07)
|
|
344
351
|
|
|
345
352
|
- **新增「限额窗口」显示**:读取开放平台的 `GET /backend/account/token_plan/remains_percent`(该接口来自桌面 App 每天真实调用的日志,同样未在官方文档中公开),展示套餐的**5 小时窗口**与**每周窗口**的已用百分比与重置倒计时。窗口时长从响应自身的起止字段推导,不写死 5 小时或 7 天——套餐条款变过不止一次,显示应跟随服务端所说。
|
package/lib/index.d.ts
CHANGED
|
@@ -611,6 +611,8 @@ declare function pluginStatePath(env?: NodeJS.ProcessEnv): string;
|
|
|
611
611
|
declare function readPluginCredential(env?: NodeJS.ProcessEnv): Promise<PluginCredential | undefined>;
|
|
612
612
|
/** Write the plugin's own credential. */
|
|
613
613
|
declare function writePluginCredential(credential: PluginCredential, env?: NodeJS.ProcessEnv): Promise<void>;
|
|
614
|
+
/** Remove the plugin's own credential, which is what signing out means. */
|
|
615
|
+
declare function deletePluginCredential(env?: NodeJS.ProcessEnv): Promise<void>;
|
|
614
616
|
/** Read the plugin's own state. */
|
|
615
617
|
declare function readPluginState(env?: NodeJS.ProcessEnv): Promise<PluginState>;
|
|
616
618
|
/** Write the plugin's own state. */
|
|
@@ -1037,7 +1039,6 @@ interface AdapterBundle {
|
|
|
1037
1039
|
declare function createMinimaxCodeAdapter(options: AdapterOptions): AdapterBundle;
|
|
1038
1040
|
//#endregion
|
|
1039
1041
|
//#region src/index.d.ts
|
|
1040
|
-
/** Loader entry name; also the id the bundle patch inserts. */
|
|
1041
1042
|
declare const name = "dsh-connect-minimaxcode";
|
|
1042
1043
|
/** Services this plugin needs before it can serve anything. */
|
|
1043
1044
|
declare const inject: string[];
|
|
@@ -1052,4 +1053,4 @@ declare const inject: string[];
|
|
|
1052
1053
|
*/
|
|
1053
1054
|
declare function apply(ctx: Context): void;
|
|
1054
1055
|
//#endregion
|
|
1055
|
-
export { type AuthState, type CatalogModel, type CatalogSource, type Credential, type CreditSummary, DEVICE_CODE_GRANT, DEVICE_CODE_PATH, type DeviceLoginState, EMPTY_USAGE, FALLBACK_MODELS, MEMBERSHIP_PATH, MINIMAXCODE_PROVIDER_ID, MINIMAX_ACTION_PATH, MINIMAX_AUTH_FILENAME, MINIMAX_DATA_DIR, MINIMAX_GATEWAYS, MINIMAX_OAUTH_CLIENT_ID, MINIMAX_REGIONS, MINIMAX_STATUS_PATH, MINIMAX_STREAM_IDLE_TIMEOUT_MS, MODEL_PRICES, MinimaxCatalog, MinimaxCredits, type MinimaxRegion, type ModelUsage, type OAuthCredential, type OAuthState, PLUGIN_CREDENTIAL_FILENAME, PLUGIN_STATE_FILENAME, type PluginCredential, type PluginState, REMAINS_PERCENT_PATH, type RateLimitWindows, SIGNIN_CLAIM_PATH, SIGNIN_CLAIM_RESULT, SIGNIN_CYCLE_DAYS, SIGNIN_DAY_STATUS, SIGNIN_PANEL_PATH, type SigninClaim, type SigninDay, type SigninPanel, type StatusDocument, type TokenClaims, UsageMeter, apply, authPath, bearerToken, catalogUrl, chatBaseUrl, claimSignin, createMinimaxCodeAdapter, dataDir, daysRemaining, decodeClaims, dshHome, ensureOAuthCredential, estimateCny, expiresInMs, expiryLevel, fetchCreditSummary, fetchRateLimitWindows, fetchSigninPanel, inject, localDay, makePkce, name, parseAuthDocument, parseCatalog, parseCreditSummary, parseOAuthDocument, parseRateLimitWindows, parseSigninClaim, parseSigninPanel, pluginCredentialPath, pluginStatePath, pollDeviceLogin, priceFor, readCredential, readOAuthCredential, readPluginCredential, readPluginState, refreshOAuthCredential, refreshPluginCredential, startDeviceLogin, statusDocument, timezoneId, writeOAuthCredential, writePluginCredential, writePluginState };
|
|
1056
|
+
export { type AuthState, type CatalogModel, type CatalogSource, type Credential, type CreditSummary, DEVICE_CODE_GRANT, DEVICE_CODE_PATH, type DeviceLoginState, EMPTY_USAGE, FALLBACK_MODELS, MEMBERSHIP_PATH, MINIMAXCODE_PROVIDER_ID, MINIMAX_ACTION_PATH, MINIMAX_AUTH_FILENAME, MINIMAX_DATA_DIR, MINIMAX_GATEWAYS, MINIMAX_OAUTH_CLIENT_ID, MINIMAX_REGIONS, MINIMAX_STATUS_PATH, MINIMAX_STREAM_IDLE_TIMEOUT_MS, MODEL_PRICES, MinimaxCatalog, MinimaxCredits, type MinimaxRegion, type ModelUsage, type OAuthCredential, type OAuthState, PLUGIN_CREDENTIAL_FILENAME, PLUGIN_STATE_FILENAME, type PluginCredential, type PluginState, REMAINS_PERCENT_PATH, type RateLimitWindows, SIGNIN_CLAIM_PATH, SIGNIN_CLAIM_RESULT, SIGNIN_CYCLE_DAYS, SIGNIN_DAY_STATUS, SIGNIN_PANEL_PATH, type SigninClaim, type SigninDay, type SigninPanel, type StatusDocument, type TokenClaims, UsageMeter, apply, authPath, bearerToken, catalogUrl, chatBaseUrl, claimSignin, createMinimaxCodeAdapter, dataDir, daysRemaining, decodeClaims, deletePluginCredential, dshHome, ensureOAuthCredential, estimateCny, expiresInMs, expiryLevel, fetchCreditSummary, fetchRateLimitWindows, fetchSigninPanel, inject, localDay, makePkce, name, parseAuthDocument, parseCatalog, parseCreditSummary, parseOAuthDocument, parseRateLimitWindows, parseSigninClaim, parseSigninPanel, pluginCredentialPath, pluginStatePath, pollDeviceLogin, priceFor, readCredential, readOAuthCredential, readPluginCredential, readPluginState, refreshOAuthCredential, refreshPluginCredential, startDeviceLogin, statusDocument, timezoneId, writeOAuthCredential, writePluginCredential, writePluginState };
|
package/lib/index.js
CHANGED
|
@@ -693,7 +693,9 @@ const HINTS = {
|
|
|
693
693
|
"app-missing": "未找到 MiniMax Code 的登录信息。请先安装并登录 MiniMax Code 桌面 App,然后重启 DSH。",
|
|
694
694
|
"not-signed-in": "MiniMax Code 尚未登录。请在 MiniMax Code 桌面 App 中登录后重启 DSH。",
|
|
695
695
|
unreadable: "登录信息文件无法读取。请确认 MiniMax Code 仍处于登录状态。",
|
|
696
|
-
malformed: "登录令牌格式无法解析。请在 MiniMax Code 中重新登录后重启 DSH。"
|
|
696
|
+
malformed: "登录令牌格式无法解析。请在 MiniMax Code 中重新登录后重启 DSH。",
|
|
697
|
+
"credential-revoked": "登录凭据已被服务器撤销,模型请求无法通过。请点击下方登录按钮重新登录 MiniMax Code。",
|
|
698
|
+
"credential-expired": "登录凭据已过期。请点击下方登录按钮重新登录 MiniMax Code。"
|
|
697
699
|
};
|
|
698
700
|
/**
|
|
699
701
|
* Build the card's status document.
|
|
@@ -721,7 +723,7 @@ function statusDocument(deps) {
|
|
|
721
723
|
...base,
|
|
722
724
|
expiry: "expired",
|
|
723
725
|
daysRemaining: 0,
|
|
724
|
-
hint: "登录令牌已过期。请打开并登录 MiniMax Code 桌面 App 以获取新令牌,然后重启 DSH。"
|
|
726
|
+
hint: HINTS[auth.reason ?? ""] ?? "登录令牌已过期。请打开并登录 MiniMax Code 桌面 App 以获取新令牌,然后重启 DSH。"
|
|
725
727
|
};
|
|
726
728
|
if (auth.state === "signed-out") return {
|
|
727
729
|
...base,
|
|
@@ -1405,6 +1407,11 @@ async function readPluginCredential(env = process.env) {
|
|
|
1405
1407
|
async function writePluginCredential(credential, env = process.env) {
|
|
1406
1408
|
await writePrivate(pluginCredentialPath(env), credential);
|
|
1407
1409
|
}
|
|
1410
|
+
/** Remove the plugin's own credential, which is what signing out means. */
|
|
1411
|
+
async function deletePluginCredential(env = process.env) {
|
|
1412
|
+
const { rm } = await import("node:fs/promises");
|
|
1413
|
+
await rm(pluginCredentialPath(env), { force: true });
|
|
1414
|
+
}
|
|
1408
1415
|
/** Read the plugin's own state. */
|
|
1409
1416
|
async function readPluginState(env = process.env) {
|
|
1410
1417
|
let text;
|
|
@@ -2012,6 +2019,25 @@ var UsageMeter = class {
|
|
|
2012
2019
|
//#endregion
|
|
2013
2020
|
//#region src/index.ts
|
|
2014
2021
|
/** Loader entry name; also the id the bundle patch inserts. */
|
|
2022
|
+
/**
|
|
2023
|
+
* Whether a message says the server refused the credential itself.
|
|
2024
|
+
*
|
|
2025
|
+
* The account and catalog endpoints answer a revoked or unknown bearer with
|
|
2026
|
+
* `401`, and the only place that surfaces is the message the request layer
|
|
2027
|
+
* built. Matching the status code rather than the wording keeps this working
|
|
2028
|
+
* whatever language the message is written in.
|
|
2029
|
+
*/
|
|
2030
|
+
const isUnauthorized = (message) => message !== void 0 && /\bHTTP 401\b/.test(message);
|
|
2031
|
+
/**
|
|
2032
|
+
* Whether a failed refresh means the credential can never be used again.
|
|
2033
|
+
*
|
|
2034
|
+
* The authorization server answers a revoked or already-spent refresh token
|
|
2035
|
+
* with `400`/`401`, and a credential that carries no refresh token can never
|
|
2036
|
+
* be renewed at all. Both are final. A `5xx` or a dropped connection is not:
|
|
2037
|
+
* throwing the credential away over a bad minute upstream would sign the
|
|
2038
|
+
* person out for nothing.
|
|
2039
|
+
*/
|
|
2040
|
+
const isRefreshRefused = (message) => message.includes("没有可用于续期的 refresh token") || /\bHTTP (400|401)\b/.test(message);
|
|
2015
2041
|
const name = "dsh-connect-minimaxcode";
|
|
2016
2042
|
/** Services this plugin needs before it can serve anything. */
|
|
2017
2043
|
const inject = ["llm"];
|
|
@@ -2072,14 +2098,50 @@ function apply(ctx) {
|
|
|
2072
2098
|
let loginSource;
|
|
2073
2099
|
/** Whether a device login is waiting to be authorized. */
|
|
2074
2100
|
let loginPending = false;
|
|
2101
|
+
/** Whether the server refused the plugin's own credential. */
|
|
2102
|
+
let revokedByServer = false;
|
|
2103
|
+
/**
|
|
2104
|
+
* Give up on the plugin's own credential after the server refused it.
|
|
2105
|
+
*
|
|
2106
|
+
* A revoked token keeps its expiry date, so every later call would send the
|
|
2107
|
+
* same dead token and fail the same way. The only way back is a new sign-in,
|
|
2108
|
+
* so the credential is deleted, the cached views of the account it belonged
|
|
2109
|
+
* to are dropped, and the card is left asking for one.
|
|
2110
|
+
*/
|
|
2111
|
+
const revokePluginCredential = async () => {
|
|
2112
|
+
await deletePluginCredential();
|
|
2113
|
+
if (pluginState.deviceLogin !== void 0) {
|
|
2114
|
+
pluginState = {
|
|
2115
|
+
...pluginState,
|
|
2116
|
+
deviceLogin: void 0
|
|
2117
|
+
};
|
|
2118
|
+
await writePluginState(pluginState);
|
|
2119
|
+
}
|
|
2120
|
+
revokedByServer = true;
|
|
2121
|
+
modelToken = void 0;
|
|
2122
|
+
loginSource = void 0;
|
|
2123
|
+
loginPending = false;
|
|
2124
|
+
creditState = "signed-out";
|
|
2125
|
+
signinPanel = void 0;
|
|
2126
|
+
signinClaim = void 0;
|
|
2127
|
+
signinError = void 0;
|
|
2128
|
+
catalog.invalidate();
|
|
2129
|
+
lastCreditAtMs = Date.now();
|
|
2130
|
+
lastSigninAtMs = Date.now();
|
|
2131
|
+
lastCatalogAtMs = 0;
|
|
2132
|
+
};
|
|
2075
2133
|
/**
|
|
2076
2134
|
* The credential the model gateway is called with.
|
|
2077
2135
|
*
|
|
2078
2136
|
* The plugin's own sign-in comes first: it is the credential the person
|
|
2079
2137
|
* chose, and on a machine where the desktop app was never installed it is
|
|
2080
|
-
* the only one there is.
|
|
2081
|
-
*
|
|
2082
|
-
*
|
|
2138
|
+
* the only one there is.
|
|
2139
|
+
*
|
|
2140
|
+
* The desktop app's OAuth grant is next, and it is not a mere fallback: it
|
|
2141
|
+
* is the credential a current install actually holds. Its `mmoat_` bearer is
|
|
2142
|
+
* what the gateway accepts, while the legacy JWT older installs left behind
|
|
2143
|
+
* is refused with `401 auth failed` — so the OAuth file has to be consulted
|
|
2144
|
+
* before that JWT, or a working machine looks broken.
|
|
2083
2145
|
*/
|
|
2084
2146
|
const resolveGatewayCredential = async () => {
|
|
2085
2147
|
const own = await readPluginCredential();
|
|
@@ -2089,11 +2151,18 @@ function apply(ctx) {
|
|
|
2089
2151
|
await writePluginCredential(next);
|
|
2090
2152
|
loginSource = "plugin";
|
|
2091
2153
|
modelToken = next.accessToken;
|
|
2154
|
+
revokedByServer = false;
|
|
2092
2155
|
return {
|
|
2093
2156
|
token: next.accessToken,
|
|
2094
2157
|
claims: { exp: Math.floor((next.expiresAtMs ?? Date.now()) / 1e3) }
|
|
2095
2158
|
};
|
|
2096
|
-
} catch {
|
|
2159
|
+
} catch (error) {
|
|
2160
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2161
|
+
if (isRefreshRefused(message)) {
|
|
2162
|
+
await revokePluginCredential();
|
|
2163
|
+
return;
|
|
2164
|
+
}
|
|
2165
|
+
}
|
|
2097
2166
|
else {
|
|
2098
2167
|
loginSource = "plugin";
|
|
2099
2168
|
modelToken = own.accessToken;
|
|
@@ -2103,6 +2172,15 @@ function apply(ctx) {
|
|
|
2103
2172
|
};
|
|
2104
2173
|
}
|
|
2105
2174
|
}
|
|
2175
|
+
const oauth = await ensureOAuthCredential(region, process.env);
|
|
2176
|
+
if (oauth.state === "signed-in") {
|
|
2177
|
+
loginSource = "desktop-app";
|
|
2178
|
+
modelToken = oauth.credential.token;
|
|
2179
|
+
return {
|
|
2180
|
+
token: oauth.credential.token,
|
|
2181
|
+
claims: { exp: Math.floor((oauth.credential.expiresAtMs ?? Date.now()) / 1e3) }
|
|
2182
|
+
};
|
|
2183
|
+
}
|
|
2106
2184
|
const state = await readCredential();
|
|
2107
2185
|
if (state.state !== "signed-in") {
|
|
2108
2186
|
loginSource = void 0;
|
|
@@ -2130,7 +2208,15 @@ function apply(ctx) {
|
|
|
2130
2208
|
state: "signed-in",
|
|
2131
2209
|
credential: toOAuthCredential(next)
|
|
2132
2210
|
};
|
|
2133
|
-
} catch {
|
|
2211
|
+
} catch (error) {
|
|
2212
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2213
|
+
if (isRefreshRefused(message)) {
|
|
2214
|
+
await revokePluginCredential();
|
|
2215
|
+
return {
|
|
2216
|
+
state: "signed-out",
|
|
2217
|
+
reason: "not-signed-in"
|
|
2218
|
+
};
|
|
2219
|
+
}
|
|
2134
2220
|
return {
|
|
2135
2221
|
state: "expired",
|
|
2136
2222
|
credential: toOAuthCredential(own)
|
|
@@ -2185,6 +2271,15 @@ function apply(ctx) {
|
|
|
2185
2271
|
}
|
|
2186
2272
|
await credits.refresh(state.credential, region, fetch, now);
|
|
2187
2273
|
creditState = credits.snapshot === void 0 ? "unavailable" : "ok";
|
|
2274
|
+
if ([
|
|
2275
|
+
credits.error,
|
|
2276
|
+
credits.ledgerError,
|
|
2277
|
+
credits.rateLimitError
|
|
2278
|
+
].find((message) => isUnauthorized(message)) !== void 0) {
|
|
2279
|
+
await revokePluginCredential();
|
|
2280
|
+
return;
|
|
2281
|
+
}
|
|
2282
|
+
if (credits.snapshot !== void 0) revokedByServer = false;
|
|
2188
2283
|
};
|
|
2189
2284
|
/**
|
|
2190
2285
|
* Read the check-in cycle, and claim the day's grant when asked to.
|
|
@@ -2210,7 +2305,12 @@ function apply(ctx) {
|
|
|
2210
2305
|
signinPanel = panel;
|
|
2211
2306
|
signinError = void 0;
|
|
2212
2307
|
} catch (error) {
|
|
2213
|
-
|
|
2308
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2309
|
+
if (isUnauthorized(message)) {
|
|
2310
|
+
await revokePluginCredential();
|
|
2311
|
+
return;
|
|
2312
|
+
}
|
|
2313
|
+
signinError = message;
|
|
2214
2314
|
return;
|
|
2215
2315
|
}
|
|
2216
2316
|
if (!pluginState.autoCheckin || panel === void 0) return;
|
|
@@ -2241,7 +2341,12 @@ function apply(ctx) {
|
|
|
2241
2341
|
refreshCredits();
|
|
2242
2342
|
return claim;
|
|
2243
2343
|
} catch (error) {
|
|
2244
|
-
|
|
2344
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
2345
|
+
if (isUnauthorized(message)) {
|
|
2346
|
+
await revokePluginCredential();
|
|
2347
|
+
return;
|
|
2348
|
+
}
|
|
2349
|
+
signinError = message;
|
|
2245
2350
|
return;
|
|
2246
2351
|
}
|
|
2247
2352
|
};
|
|
@@ -2363,21 +2468,47 @@ function apply(ctx) {
|
|
|
2363
2468
|
}
|
|
2364
2469
|
});
|
|
2365
2470
|
ctx.llm.registerAdapter(["minimaxcode"], adapter);
|
|
2366
|
-
/**
|
|
2367
|
-
|
|
2471
|
+
/**
|
|
2472
|
+
* The sign-in state the card reports.
|
|
2473
|
+
*
|
|
2474
|
+
* It describes the credential the gateway will actually be called with, not
|
|
2475
|
+
* a particular file on disk: the card exists to answer "will a request
|
|
2476
|
+
* work", and a token the server refused is not a sign-in however unexpired
|
|
2477
|
+
* it looks. Reading the legacy JWT alone is what made a machine whose model
|
|
2478
|
+
* gateway was working report a signed-out, expired card.
|
|
2479
|
+
*/
|
|
2480
|
+
const buildAuthStatus = async () => {
|
|
2481
|
+
if (revokedByServer) return {
|
|
2482
|
+
state: "signed-out",
|
|
2483
|
+
reason: "credential-revoked"
|
|
2484
|
+
};
|
|
2485
|
+
const current = await readNow();
|
|
2486
|
+
if (current !== void 0) {
|
|
2487
|
+
const remaining = expiresInMs(current.claims);
|
|
2488
|
+
if (remaining <= 0) return {
|
|
2489
|
+
state: "expired",
|
|
2490
|
+
reason: "credential-expired"
|
|
2491
|
+
};
|
|
2492
|
+
return {
|
|
2493
|
+
state: "signed-in",
|
|
2494
|
+
daysRemaining: Math.ceil(remaining / 864e5),
|
|
2495
|
+
expiry: expiryLevel(current.claims)
|
|
2496
|
+
};
|
|
2497
|
+
}
|
|
2368
2498
|
const state = await readCredential();
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
daysRemaining: Math.ceil(expiresInMs(state.credential.claims) / 864e5),
|
|
2372
|
-
expiry: expiryLevel(state.credential.claims)
|
|
2373
|
-
} : state.state === "expired" ? { state: "expired" } : {
|
|
2499
|
+
if (state.state === "expired") return { state: "expired" };
|
|
2500
|
+
if (state.state === "signed-out") return {
|
|
2374
2501
|
state: "signed-out",
|
|
2375
2502
|
reason: state.reason
|
|
2376
2503
|
};
|
|
2504
|
+
return { state: "signed-in" };
|
|
2505
|
+
};
|
|
2506
|
+
/** Build the document the card renders, without ever exposing the token. */
|
|
2507
|
+
const buildStatus = async () => {
|
|
2377
2508
|
await refreshCredits();
|
|
2378
2509
|
await refreshSignin();
|
|
2379
2510
|
return statusDocument({
|
|
2380
|
-
auth,
|
|
2511
|
+
auth: await buildAuthStatus(),
|
|
2381
2512
|
region,
|
|
2382
2513
|
catalogSource: catalog.source,
|
|
2383
2514
|
catalogError: catalog.error,
|
|
@@ -2465,6 +2596,7 @@ function apply(ctx) {
|
|
|
2465
2596
|
};
|
|
2466
2597
|
await writePluginState(pluginState);
|
|
2467
2598
|
loginPending = false;
|
|
2599
|
+
revokedByServer = false;
|
|
2468
2600
|
loginSource = "plugin";
|
|
2469
2601
|
modelToken = result.credential.accessToken;
|
|
2470
2602
|
catalog.invalidate();
|
|
@@ -2582,4 +2714,4 @@ async function readRequestBody(req) {
|
|
|
2582
2714
|
return text;
|
|
2583
2715
|
}
|
|
2584
2716
|
//#endregion
|
|
2585
|
-
export { DEVICE_CODE_GRANT, DEVICE_CODE_PATH, EMPTY_USAGE, FALLBACK_MODELS, MEMBERSHIP_PATH, MINIMAXCODE_PROVIDER_ID, MINIMAX_ACTION_PATH, MINIMAX_AUTH_FILENAME, MINIMAX_DATA_DIR, MINIMAX_GATEWAYS, MINIMAX_OAUTH_CLIENT_ID, MINIMAX_REGIONS, MINIMAX_STATUS_PATH, MINIMAX_STREAM_IDLE_TIMEOUT_MS, MODEL_PRICES, MinimaxCatalog, MinimaxCredits, PLUGIN_CREDENTIAL_FILENAME, PLUGIN_STATE_FILENAME, REMAINS_PERCENT_PATH, SIGNIN_CLAIM_PATH, SIGNIN_CLAIM_RESULT, SIGNIN_CYCLE_DAYS, SIGNIN_DAY_STATUS, SIGNIN_PANEL_PATH, UsageMeter, apply, authPath, bearerToken, catalogUrl, chatBaseUrl, claimSignin, createMinimaxCodeAdapter, dataDir, daysRemaining, decodeClaims, dshHome, ensureOAuthCredential, estimateCny, expiresInMs, expiryLevel, fetchCreditSummary, fetchRateLimitWindows, fetchSigninPanel, inject, localDay, makePkce, name, parseAuthDocument, parseCatalog, parseCreditSummary, parseOAuthDocument, parseRateLimitWindows, parseSigninClaim, parseSigninPanel, pluginCredentialPath, pluginStatePath, pollDeviceLogin, priceFor, readCredential, readOAuthCredential, readPluginCredential, readPluginState, refreshOAuthCredential, refreshPluginCredential, startDeviceLogin, statusDocument, timezoneId, writeOAuthCredential, writePluginCredential, writePluginState };
|
|
2717
|
+
export { DEVICE_CODE_GRANT, DEVICE_CODE_PATH, EMPTY_USAGE, FALLBACK_MODELS, MEMBERSHIP_PATH, MINIMAXCODE_PROVIDER_ID, MINIMAX_ACTION_PATH, MINIMAX_AUTH_FILENAME, MINIMAX_DATA_DIR, MINIMAX_GATEWAYS, MINIMAX_OAUTH_CLIENT_ID, MINIMAX_REGIONS, MINIMAX_STATUS_PATH, MINIMAX_STREAM_IDLE_TIMEOUT_MS, MODEL_PRICES, MinimaxCatalog, MinimaxCredits, PLUGIN_CREDENTIAL_FILENAME, PLUGIN_STATE_FILENAME, REMAINS_PERCENT_PATH, SIGNIN_CLAIM_PATH, SIGNIN_CLAIM_RESULT, SIGNIN_CYCLE_DAYS, SIGNIN_DAY_STATUS, SIGNIN_PANEL_PATH, UsageMeter, apply, authPath, bearerToken, catalogUrl, chatBaseUrl, claimSignin, createMinimaxCodeAdapter, dataDir, daysRemaining, decodeClaims, deletePluginCredential, dshHome, ensureOAuthCredential, estimateCny, expiresInMs, expiryLevel, fetchCreditSummary, fetchRateLimitWindows, fetchSigninPanel, inject, localDay, makePkce, name, parseAuthDocument, parseCatalog, parseCreditSummary, parseOAuthDocument, parseRateLimitWindows, parseSigninClaim, parseSigninPanel, pluginCredentialPath, pluginStatePath, pollDeviceLogin, priceFor, readCredential, readOAuthCredential, readPluginCredential, readPluginState, refreshOAuthCredential, refreshPluginCredential, startDeviceLogin, statusDocument, timezoneId, writeOAuthCredential, writePluginCredential, writePluginState };
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "dsh-connect-minimaxcode",
|
|
3
3
|
"displayName": "DSH Connect MiniMax Code",
|
|
4
4
|
"description": "把本机已登录的 MiniMax Code 桌面 App 模型接入 DeepSeek Harness:零配置、Anthropic Messages 兼容、动态模型目录,并显示积分余额与到期 — bring MiniMax Code desktop app models into DSH with a dynamic model catalog and a credit balance with expiry details.",
|
|
5
|
-
"version": "0.5.
|
|
5
|
+
"version": "0.5.6",
|
|
6
6
|
"author": "JeffTsuiCUG",
|
|
7
7
|
"contributors": [
|
|
8
8
|
{
|