dsh-connect-minimaxcode 0.5.4 → 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/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.
@@ -712,6 +714,7 @@ function statusDocument(deps) {
712
714
  models: deps.models,
713
715
  refreshing: deps.refreshing,
714
716
  ...deps.credits === void 0 ? {} : { credits: deps.credits },
717
+ ...deps.rateLimit === void 0 ? {} : { rateLimit: deps.rateLimit },
715
718
  ...deps.usage === void 0 ? {} : { usage: deps.usage },
716
719
  ...deps.signin === void 0 ? {} : { signin: deps.signin },
717
720
  ...deps.login === void 0 ? {} : { login: deps.login }
@@ -720,7 +723,7 @@ function statusDocument(deps) {
720
723
  ...base,
721
724
  expiry: "expired",
722
725
  daysRemaining: 0,
723
- hint: "登录令牌已过期。请打开并登录 MiniMax Code 桌面 App 以获取新令牌,然后重启 DSH。"
726
+ hint: HINTS[auth.reason ?? ""] ?? "登录令牌已过期。请打开并登录 MiniMax Code 桌面 App 以获取新令牌,然后重启 DSH。"
724
727
  };
725
728
  if (auth.state === "signed-out") return {
726
729
  ...base,
@@ -780,10 +783,18 @@ const MINIMAX_ACCOUNT_HOSTS = {
780
783
  io: "https://agent.minimax.io",
781
784
  com: "https://agent.minimaxi.com"
782
785
  };
786
+ /** Open-platform account API, which serves the per-model usage summary. */
787
+ const MINIMAX_OPEN_HOSTS = {
788
+ cn: "https://www.minimaxi.com",
789
+ io: "https://www.minimaxi.com",
790
+ com: "https://www.minimaxi.com"
791
+ };
783
792
  /** Membership endpoint: carries the credit summary. */
784
793
  const MEMBERSHIP_PATH = "/matrix/api/v1/commerce/get_membership_info";
785
794
  /** Credit ledger endpoint: per-grant amounts and expiry. */
786
795
  const CREDIT_DETAILS_PATH = "/minimax-cloud/api/v1/credit/details";
796
+ /** Rate-limit window endpoint: the 5-hour and weekly usage the plan meters. */
797
+ const REMAINS_PERCENT_PATH = "/backend/account/token_plan/remains_percent";
787
798
  /** OAuth token endpoint. */
788
799
  const TOKEN_PATH$1 = "/oauth2/token";
789
800
  /** Absolute path of the app's credential file for a region. */
@@ -1088,6 +1099,84 @@ async function fetchCreditLots(credential, region, fetchImpl = fetch) {
1088
1099
  return lots;
1089
1100
  }
1090
1101
  /**
1102
+ * Read the two rate-limit windows out of a remains-percent response.
1103
+ *
1104
+ * The upstream answers with one entry per metered group; the general one is
1105
+ * the only one the plan meters today, and the first entry is used when it is
1106
+ * absent. The percents arrive as strings ("19%"), and the counts arrive as -1
1107
+ * when the plan does not meter by count, so only the percents and the window
1108
+ * edges are read. The window length is derived from the entry's own endpoints
1109
+ * rather than assumed to be five hours or seven days — the plan's terms have
1110
+ * changed before, and the display should follow whatever the server says.
1111
+ *
1112
+ * A window the server marks as unlimited (`current_*_status` of 3) carries no
1113
+ * allowance to be a percentage of, so it produces no window at all: reporting
1114
+ * "0%" of an unlimited quota would be a number nobody can act on.
1115
+ */
1116
+ function parseRateLimitWindows(document) {
1117
+ if (typeof document !== "object" || document === null) return void 0;
1118
+ const remains = document.model_remains;
1119
+ if (!Array.isArray(remains) || remains.length === 0) return void 0;
1120
+ const entry = remains.find((item) => typeof item === "object" && item !== null && item.model_name === "general") ?? remains[0];
1121
+ if (typeof entry !== "object" || entry === null) return void 0;
1122
+ const record = entry;
1123
+ const interval = readWindow(record.current_interval_used_percent, record.start_time, record.end_time, record.current_interval_status);
1124
+ const weekly = readWindow(record.current_weekly_used_percent, record.weekly_start_time, record.weekly_end_time, record.current_weekly_status);
1125
+ if (interval === void 0 || weekly === void 0) return void 0;
1126
+ return {
1127
+ interval,
1128
+ weekly
1129
+ };
1130
+ }
1131
+ /**
1132
+ * The status the upstream gives a window that is not limited at all.
1133
+ *
1134
+ * The desktop app reads it the same way: `isUnlimited: 3 === status`.
1135
+ */
1136
+ const UNLIMITED_STATUS = 3;
1137
+ /** Assemble one window from its percent and edge fields; all must be present. */
1138
+ function readWindow(percent, startAtMs, resetAtMs, status) {
1139
+ if (status === UNLIMITED_STATUS) return void 0;
1140
+ const usedPercent = parsePercent(percent);
1141
+ const start = toNumber$1(startAtMs);
1142
+ const reset = toNumber$1(resetAtMs);
1143
+ if (usedPercent === void 0 || start === void 0 || reset === void 0) return void 0;
1144
+ return {
1145
+ usedPercent,
1146
+ startAtMs: start,
1147
+ resetAtMs: reset
1148
+ };
1149
+ }
1150
+ /**
1151
+ * Read "19%" as 19, and a bare 19 as 19 as well.
1152
+ *
1153
+ * The desktop app parses both shapes, so both are accepted here: anything
1154
+ * unreadable stays unreadable rather than becoming a zero.
1155
+ */
1156
+ function parsePercent(value) {
1157
+ if (typeof value === "number") return Number.isFinite(value) ? value : void 0;
1158
+ if (typeof value !== "string") return void 0;
1159
+ const parsed = Number(value.replace(/%\s*$/, ""));
1160
+ return Number.isFinite(parsed) ? parsed : void 0;
1161
+ }
1162
+ /**
1163
+ * Fetch the plan's two rate-limit windows.
1164
+ *
1165
+ * The endpoint lives on the open-platform host, like the usage summary, and
1166
+ * answers the same OAuth credential the membership endpoint takes. The JWT the
1167
+ * model gateway accepts does not work here: this is an account endpoint.
1168
+ *
1169
+ * @returns The windows, or `undefined` when the response carries none.
1170
+ */
1171
+ async function fetchRateLimitWindows(credential, region, fetchImpl = fetch) {
1172
+ const response = await fetchImpl(`${MINIMAX_OPEN_HOSTS[region]}${REMAINS_PERCENT_PATH}?business=Agent&device_platform=desktop`, { headers: {
1173
+ accept: "application/json",
1174
+ authorization: `Bearer ${credential.token}`
1175
+ } });
1176
+ if (!response.ok) throw new Error(`rate-limit window request failed: HTTP ${response.status}`);
1177
+ return parseRateLimitWindows(await response.json());
1178
+ }
1179
+ /**
1091
1180
  * Summarize what is about to expire.
1092
1181
  *
1093
1182
  * Only lots that still hold credits count: a lot that was granted and used up
@@ -1124,6 +1213,9 @@ var MinimaxCredits = class {
1124
1213
  #expiry;
1125
1214
  #ledgerAtMs;
1126
1215
  #ledgerError;
1216
+ #rateLimit;
1217
+ #rateLimitError;
1218
+ #rateLimitAtMs;
1127
1219
  /** The balance as last read. */
1128
1220
  get snapshot() {
1129
1221
  return this.#snapshot;
@@ -1148,12 +1240,26 @@ var MinimaxCredits = class {
1148
1240
  get ledgerError() {
1149
1241
  return this.#ledgerError;
1150
1242
  }
1243
+ /** The plan's rate-limit windows as last read. */
1244
+ get rateLimit() {
1245
+ return this.#rateLimit;
1246
+ }
1247
+ /** Why the windows could not be read, when they could not. */
1248
+ get rateLimitError() {
1249
+ return this.#rateLimitError;
1250
+ }
1251
+ /** When the windows were last read. */
1252
+ get rateLimitAtMs() {
1253
+ return this.#rateLimitAtMs;
1254
+ }
1151
1255
  /**
1152
1256
  * Read the balance and record how much was consumed since the last read.
1153
1257
  *
1154
1258
  * The credit ledger is read alongside it, but a ledger that cannot be read
1155
1259
  * never hides the balance: the two come from different endpoints and only
1156
- * the balance is essential.
1260
+ * the balance is essential. The rate-limit windows ride along under the
1261
+ * same rule — they come from yet another endpoint, and none of the three
1262
+ * takes the others down with it.
1157
1263
  *
1158
1264
  * @returns Whether the balance changed.
1159
1265
  */
@@ -1176,6 +1282,7 @@ var MinimaxCredits = class {
1176
1282
  this.#error = error instanceof Error ? error.message : String(error);
1177
1283
  }
1178
1284
  await this.refreshLedger(credential, region, fetchImpl, now);
1285
+ await this.refreshRateLimit(credential, region, fetchImpl, now);
1179
1286
  return changed;
1180
1287
  }
1181
1288
  /**
@@ -1196,6 +1303,22 @@ var MinimaxCredits = class {
1196
1303
  this.#ledgerError = error instanceof Error ? error.message : String(error);
1197
1304
  }
1198
1305
  }
1306
+ /**
1307
+ * Read the plan's rate-limit windows.
1308
+ *
1309
+ * Same rule as the ledger: a failure is remembered but never thrown, and a
1310
+ * window that cannot be read leaves the last one on display.
1311
+ */
1312
+ async refreshRateLimit(credential, region, fetchImpl = fetch, now = Date.now()) {
1313
+ try {
1314
+ const windows = await fetchRateLimitWindows(credential, region, fetchImpl);
1315
+ this.#rateLimit = windows;
1316
+ this.#rateLimitError = windows === void 0 ? "response carried no rate-limit windows" : void 0;
1317
+ this.#rateLimitAtMs = now;
1318
+ } catch (error) {
1319
+ this.#rateLimitError = error instanceof Error ? error.message : String(error);
1320
+ }
1321
+ }
1199
1322
  };
1200
1323
  //#endregion
1201
1324
  //#region src/credentials.ts
@@ -1284,6 +1407,11 @@ async function readPluginCredential(env = process.env) {
1284
1407
  async function writePluginCredential(credential, env = process.env) {
1285
1408
  await writePrivate(pluginCredentialPath(env), credential);
1286
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
+ }
1287
1415
  /** Read the plugin's own state. */
1288
1416
  async function readPluginState(env = process.env) {
1289
1417
  let text;
@@ -1891,6 +2019,25 @@ var UsageMeter = class {
1891
2019
  //#endregion
1892
2020
  //#region src/index.ts
1893
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);
1894
2041
  const name = "dsh-connect-minimaxcode";
1895
2042
  /** Services this plugin needs before it can serve anything. */
1896
2043
  const inject = ["llm"];
@@ -1951,14 +2098,50 @@ function apply(ctx) {
1951
2098
  let loginSource;
1952
2099
  /** Whether a device login is waiting to be authorized. */
1953
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
+ };
1954
2133
  /**
1955
2134
  * The credential the model gateway is called with.
1956
2135
  *
1957
2136
  * The plugin's own sign-in comes first: it is the credential the person
1958
2137
  * chose, and on a machine where the desktop app was never installed it is
1959
- * the only one there is. The desktop app's token is the fallback, and the
1960
- * two are interchangeable as far as the gateway is concerned — it accepts
1961
- * either bearer.
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.
1962
2145
  */
1963
2146
  const resolveGatewayCredential = async () => {
1964
2147
  const own = await readPluginCredential();
@@ -1968,11 +2151,18 @@ function apply(ctx) {
1968
2151
  await writePluginCredential(next);
1969
2152
  loginSource = "plugin";
1970
2153
  modelToken = next.accessToken;
2154
+ revokedByServer = false;
1971
2155
  return {
1972
2156
  token: next.accessToken,
1973
2157
  claims: { exp: Math.floor((next.expiresAtMs ?? Date.now()) / 1e3) }
1974
2158
  };
1975
- } 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
+ }
1976
2166
  else {
1977
2167
  loginSource = "plugin";
1978
2168
  modelToken = own.accessToken;
@@ -1982,6 +2172,15 @@ function apply(ctx) {
1982
2172
  };
1983
2173
  }
1984
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
+ }
1985
2184
  const state = await readCredential();
1986
2185
  if (state.state !== "signed-in") {
1987
2186
  loginSource = void 0;
@@ -2009,7 +2208,15 @@ function apply(ctx) {
2009
2208
  state: "signed-in",
2010
2209
  credential: toOAuthCredential(next)
2011
2210
  };
2012
- } 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
+ }
2013
2220
  return {
2014
2221
  state: "expired",
2015
2222
  credential: toOAuthCredential(own)
@@ -2064,6 +2271,15 @@ function apply(ctx) {
2064
2271
  }
2065
2272
  await credits.refresh(state.credential, region, fetch, now);
2066
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;
2067
2283
  };
2068
2284
  /**
2069
2285
  * Read the check-in cycle, and claim the day's grant when asked to.
@@ -2089,7 +2305,12 @@ function apply(ctx) {
2089
2305
  signinPanel = panel;
2090
2306
  signinError = void 0;
2091
2307
  } catch (error) {
2092
- signinError = error instanceof Error ? error.message : String(error);
2308
+ const message = error instanceof Error ? error.message : String(error);
2309
+ if (isUnauthorized(message)) {
2310
+ await revokePluginCredential();
2311
+ return;
2312
+ }
2313
+ signinError = message;
2093
2314
  return;
2094
2315
  }
2095
2316
  if (!pluginState.autoCheckin || panel === void 0) return;
@@ -2120,7 +2341,12 @@ function apply(ctx) {
2120
2341
  refreshCredits();
2121
2342
  return claim;
2122
2343
  } catch (error) {
2123
- signinError = error instanceof Error ? error.message : String(error);
2344
+ const message = error instanceof Error ? error.message : String(error);
2345
+ if (isUnauthorized(message)) {
2346
+ await revokePluginCredential();
2347
+ return;
2348
+ }
2349
+ signinError = message;
2124
2350
  return;
2125
2351
  }
2126
2352
  };
@@ -2150,6 +2376,21 @@ function apply(ctx) {
2150
2376
  ...credits.ledgerError === void 0 ? {} : { ledgerError: credits.ledgerError }
2151
2377
  };
2152
2378
  };
2379
+ /** The plan's rolling usage windows as the card reads them. */
2380
+ const buildRateLimitStatus = () => {
2381
+ if (creditState === "signed-out" || creditState === "expired") return { state: creditState };
2382
+ const windows = credits.rateLimit;
2383
+ if (windows === void 0) return {
2384
+ state: "unavailable",
2385
+ ...credits.rateLimitError === void 0 ? {} : { error: credits.rateLimitError }
2386
+ };
2387
+ return {
2388
+ state: "ok",
2389
+ interval: windows.interval,
2390
+ weekly: windows.weekly,
2391
+ ...credits.rateLimitAtMs === void 0 ? {} : { updatedAtMs: credits.rateLimitAtMs }
2392
+ };
2393
+ };
2153
2394
  /** What this host's own requests have used. */
2154
2395
  const buildUsageStatus = () => {
2155
2396
  const totals = meter.totals();
@@ -2227,21 +2468,47 @@ function apply(ctx) {
2227
2468
  }
2228
2469
  });
2229
2470
  ctx.llm.registerAdapter(["minimaxcode"], adapter);
2230
- /** Build the document the card renders, without ever exposing the token. */
2231
- const buildStatus = async () => {
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
+ }
2232
2498
  const state = await readCredential();
2233
- const auth = state.state === "signed-in" ? {
2234
- state: "signed-in",
2235
- daysRemaining: Math.ceil(expiresInMs(state.credential.claims) / 864e5),
2236
- expiry: expiryLevel(state.credential.claims)
2237
- } : state.state === "expired" ? { state: "expired" } : {
2499
+ if (state.state === "expired") return { state: "expired" };
2500
+ if (state.state === "signed-out") return {
2238
2501
  state: "signed-out",
2239
2502
  reason: state.reason
2240
2503
  };
2504
+ return { state: "signed-in" };
2505
+ };
2506
+ /** Build the document the card renders, without ever exposing the token. */
2507
+ const buildStatus = async () => {
2241
2508
  await refreshCredits();
2242
2509
  await refreshSignin();
2243
2510
  return statusDocument({
2244
- auth,
2511
+ auth: await buildAuthStatus(),
2245
2512
  region,
2246
2513
  catalogSource: catalog.source,
2247
2514
  catalogError: catalog.error,
@@ -2252,6 +2519,7 @@ function apply(ctx) {
2252
2519
  })),
2253
2520
  refreshing,
2254
2521
  credits: buildCreditStatus(),
2522
+ rateLimit: buildRateLimitStatus(),
2255
2523
  usage: buildUsageStatus(),
2256
2524
  signin: buildSigninStatus(),
2257
2525
  login: buildLoginStatus()
@@ -2328,6 +2596,7 @@ function apply(ctx) {
2328
2596
  };
2329
2597
  await writePluginState(pluginState);
2330
2598
  loginPending = false;
2599
+ revokedByServer = false;
2331
2600
  loginSource = "plugin";
2332
2601
  modelToken = result.credential.accessToken;
2333
2602
  catalog.invalidate();
@@ -2445,4 +2714,4 @@ async function readRequestBody(req) {
2445
2714
  return text;
2446
2715
  }
2447
2716
  //#endregion
2448
- 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, 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, fetchSigninPanel, inject, localDay, makePkce, name, parseAuthDocument, parseCatalog, parseCreditSummary, parseOAuthDocument, 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.4",
5
+ "version": "0.5.6",
6
6
  "author": "JeffTsuiCUG",
7
7
  "contributors": [
8
8
  {
@@ -13,9 +13,13 @@
13
13
  "name": "eghrhegpe",
14
14
  "url": "https://github.com/eghrhegpe"
15
15
  },
16
+ {
17
+ "name": "qzz19970504",
18
+ "url": "https://github.com/qzz19970504"
19
+ },
16
20
  {
17
- "name": "qzz19970504",
18
- "url": "https://github.com/qzz19970504"
21
+ "name": "azsora",
22
+ "url": "https://github.com/azsora"
19
23
  }
20
24
  ],
21
25
  "license": "MIT",