Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 13 additions & 11 deletions config.example.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -53,8 +53,8 @@ models:
identity:
# Mirrors process.env.ZCODE_APP_VERSION in the ZCode bundle.
# Must be printable ASCII; non-conforming values fall back to the default.
# Default: "3.14.0" (current ZCode release). Override to match your real client.
appVersion: "3.14.0"
# Default: "3.15.1" (current ZCode release). Override to match your real client.
appVersion: "3.15.1"
# X-Title suffix → "Z Code@{sourceTitle}". Default "cli".
sourceTitle: "cli"
# HTTP-Referer URL. Default "https://zcode.z.ai".
Expand Down Expand Up @@ -160,8 +160,8 @@ async:
# `auth login`), and identity.appVersion must be >= the campaign's minimum
# client version or the server rejects with `ineligible` — an app_version
# below the floor can also surface as a silently empty preview list
# (measured floor 3.14.0 for the 2026-09 campaign; the default appVersion
# "3.14.0" satisfies it).
# (measured floor 3.14.0 for the 2026-09 campaign; the default appVersion
# "3.15.1" satisfies it).
#
# Env overrides: ZCODE_CLAIM_ENABLED, ZCODE_CLAIM_AUTO, ZCODE_CLAIM_ORIGIN,
# ZCODE_CLAIM_POLL_INTERVAL_MS.
Expand Down Expand Up @@ -204,13 +204,15 @@ clientSigning:

# HighSpeed 加速卡 (mirrors the ZCode 3.15.1 HighspeedCardService — Coding Plan
# subscriber benefit, server-side random draw). Enabled by default, matching the
# official client (which has no toggle): eligible coding-plan requests lazily
# trigger POST {origin}/api/v1/highspeed/draw; on a hit, requests inside the
# card window are rewritten to the card model with the highspeed auth set
# (X-Highspeed-Card-ID) and stay unsigned, exactly like the official client.
# Misses/cooldowns honor server next_draw_at; accounts outside the rollout
# (503/3404) are negative-cached 10min. task_id reuses the local client-session
# affinity inference. Env override: ZCODE_HIGHSPEED_ENABLED=false.
# official client (which has no toggle): the first eligible coding-plan request
# ignites a background draw loop (POST {origin}/api/v1/highspeed/draw at ~1/s —
# the measured token-bucket refill rate; server next_draw_at is ignored on a
# miss); on a hit, requests inside the card window are rewritten to the card
# model with the highspeed auth set (X-Highspeed-Card-ID) and stay unsigned,
# exactly like the official client. The loop self-extinguishes 5 minutes after
# the last eligible request; account unavailability (503/3404) is
# negative-cached 10min, HTTP 429 backs off 30s. task_id reuses the local
# client-session affinity inference. Env override: ZCODE_HIGHSPEED_ENABLED=false.
highspeed:
enabled: true
origin: "https://zcode.z.ai"
Expand Down
4 changes: 2 additions & 2 deletions src/auth/oauth.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ describe("ZaiOAuthClient (server-mediated cli login)", () => {
expect(interstitial).toStartWith("https://zcode.z.ai/app/oauth/login?");
const inner = new URL(interstitial);
expect(inner.searchParams.get("redirect")).toBe("zcode://oauth/callback");
expect(inner.searchParams.get("app_version")).toBe("3.14.0");
expect(inner.searchParams.get("app_version")).toBe("3.15.1");
} finally {
await client.close();
}
Expand Down Expand Up @@ -256,7 +256,7 @@ describe("BigmodelPollOAuthClient (server-mediated cli login)", () => {
expect(url.origin + url.pathname).toBe("https://bigmodel.cn/login");
const interstitial = url.searchParams.get("redirect") ?? "";
expect(interstitial).toStartWith("https://zcode.z.ai/app/oauth/login?");
expect(new URL(interstitial).searchParams.get("app_version")).toBe("3.14.0");
expect(new URL(interstitial).searchParams.get("app_version")).toBe("3.15.1");
expect(url.searchParams.get("redirect_uri")).toBeNull();
expect(started.callbackUrl).toBe("");
} finally {
Expand Down
5 changes: 4 additions & 1 deletion src/auth/resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,9 @@ export class KeyResolver {
if (secret) fullKey = `${apiKey}.${secret}`;
} catch { /* use apiKey only */ }

return { apiKey: fullKey, provider: "bigmodel", userId };
// 3.15.1 project-access-token plane: the raw OAuth token mints the signing
// JWT (`…/access_tokens`); without it signing falls back to the apiKey
// form and fails open on the bigmodel handshake.
return { apiKey: fullKey, provider: "bigmodel", userId, oauthAccessToken: accessToken };
}
}
8 changes: 8 additions & 0 deletions src/auth/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ export interface Credential {
userId?: string;
/** JWT token for start-plan (zcode.z.ai). Present when login captured the ZCode plan token. */
jwt?: string;
/**
* Raw provider OAuth access token (bigmodel). Required by the 3.15.1
* project-access-token plane: getCustomerInfo (bare) and
* `…/api_keys/{id}/access_tokens` (Bearer) mint the signing JWT
* (`project_access`, 5h). Absent for API-key imports and pre-patch logins
* — signing then falls back to the apiKey form and fails open.
*/
oauthAccessToken?: string;
}

/**
Expand Down
4 changes: 2 additions & 2 deletions src/config/loader.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,7 @@ models:
const path = writeYaml(`
`);
const cfg = loadConfig(path);
expect(cfg.identity.appVersion).toBe("3.14.0");
expect(cfg.identity.appVersion).toBe("3.15.1");
expect(cfg.identity.sourceTitle).toBe("cli");
expect(cfg.identity.refererOrigin).toBe("https://zcode.z.ai");
});
Expand Down Expand Up @@ -471,6 +471,6 @@ identity:
appVersion: "v3.3.3-中文"
`);
const cfg = loadConfig(path);
expect(cfg.identity.appVersion).toBe("3.14.0");
expect(cfg.identity.appVersion).toBe("3.15.1");
});
});
2 changes: 1 addition & 1 deletion src/config/loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ const ENV = {

/** Mirrors the ZCode desktop release (`_reverse/NOTEPAD.md`); bump per client
* release or User-Agent/X-ZCode-App-Version become distinguishable. */
export const DEFAULT_APP_VERSION = "3.14.0";
export const DEFAULT_APP_VERSION = "3.15.1";

const DEFAULTS = {
PORT: 8080,
Expand Down
20 changes: 11 additions & 9 deletions src/config/template.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ models:
identity:
# Mirrors process.env.ZCODE_APP_VERSION in the ZCode bundle.
# Must be printable ASCII; non-conforming values fall back to the default.
# Default: "3.14.0" (current ZCode release). Override to match your real client.
appVersion: "3.14.0"
# Default: "3.15.1" (current ZCode release). Override to match your real client.
appVersion: "3.15.1"
# X-Title suffix → "Z Code@{sourceTitle}". Default "cli".
sourceTitle: "cli"
# HTTP-Referer URL. Default "https://zcode.z.ai".
Expand Down Expand Up @@ -106,13 +106,15 @@ clientSigning:

# HighSpeed 加速卡 (mirrors the ZCode 3.15.1 HighspeedCardService — Coding Plan
# subscriber benefit, server-side random draw). Enabled by default, matching the
# official client (which has no toggle): eligible coding-plan requests lazily
# trigger POST {origin}/api/v1/highspeed/draw; on a hit, requests inside the
# card window are rewritten to the card model with the highspeed auth set
# (X-Highspeed-Card-ID) and stay unsigned, exactly like the official client.
# Misses/cooldowns honor server next_draw_at; accounts outside the rollout
# (503/3404) are negative-cached 10min. task_id reuses the local client-session
# affinity inference. Env override: ZCODE_HIGHSPEED_ENABLED=false.
# official client (which has no toggle): the first eligible coding-plan request
# ignites a background draw loop (POST {origin}/api/v1/highspeed/draw at ~1/s —
# the measured token-bucket refill rate; server next_draw_at is ignored on a
# miss); on a hit, requests inside the card window are rewritten to the card
# model with the highspeed auth set (X-Highspeed-Card-ID) and stay unsigned,
# exactly like the official client. The loop self-extinguishes 5 minutes after
# the last eligible request; account unavailability (503/3404) is
# negative-cached 10min, HTTP 429 backs off 30s. task_id reuses the local
# client-session affinity inference. Env override: ZCODE_HIGHSPEED_ENABLED=false.
highspeed:
enabled: true
origin: "https://zcode.z.ai"
Expand Down
Loading
Loading