Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot] 655707bc09 chore(deps): bump actions/cache from 5 to 6
Bumps [actions/cache](https://github.com/actions/cache) from 5 to 6.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-07-01 18:26:54 +00:00
9 changed files with 8 additions and 57 deletions
+2 -2
View File
@@ -35,7 +35,7 @@ jobs:
run: echo "path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
- name: Cache pnpm store
uses: actions/cache@v5
uses: actions/cache@v6
with:
path: ${{ steps.pnpm-store.outputs.path }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
@@ -77,7 +77,7 @@ jobs:
|| sudo apt-get install -y --no-install-recommends libsoup2.4-dev
- name: Cache Cargo registry and build
uses: actions/cache@v5
uses: actions/cache@v6
with:
path: |
~/.cargo/registry
+1 -1
View File
@@ -106,7 +106,7 @@ jobs:
- name: Setup pnpm cache
if: runner.os != 'Windows' || matrix.arch != 'arm64'
uses: actions/cache@v5
uses: actions/cache@v6
with:
path: ${{ steps.pnpm-store.outputs.path }}
key: ${{ runner.os }}-${{ runner.arch }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
+2 -30
View File
@@ -312,12 +312,6 @@ pub const TIER_WEEKLY_LIMIT: &str = "weekly_limit";
/// 映射到 `subscription.monthly`。
pub const TIER_MONTHLY: &str = "monthly";
/// Codex 免费方案的 30 天(月)滚动窗口 tier 名。付费方案的次要窗口是 7 天
/// (`seven_day`),免费方案则是 30 天。由 `window_seconds_to_tier_name` 产出、
/// tray 的月分组渲染、前端 `TIER_I18N_KEYS` 映射到 `subscription.thirtyDay`
/// 三处共用同一标识。见 #3651。
pub const TIER_THIRTY_DAY: &str = "30_day";
/// Gemini 用量分组名称(按模型而非时间窗口)。`classify_gemini_model` 输出。
pub const TIER_GEMINI_PRO: &str = "gemini_pro";
pub const TIER_GEMINI_FLASH: &str = "gemini_flash";
@@ -638,12 +632,8 @@ struct CodexUsageResponse {
/// 根据窗口秒数映射到 tier 名称(与 Claude 的命名兼容以复用前端 i18n)
fn window_seconds_to_tier_name(secs: i64) -> String {
match secs {
18000 => TIER_FIVE_HOUR.to_string(),
604800 => TIER_SEVEN_DAY.to_string(),
// Codex 免费方案的 30 天窗口。显式映射到常量,与 tray 月分组、前端
// TIER_I18N_KEYS 保持同一标识(否则动态回退虽也得到 "30_day",但字符串
// 分散在多处、易和托盘/前端白名单脱节)。见 #3651。
2_592_000 => TIER_THIRTY_DAY.to_string(),
18000 => "five_hour".to_string(),
604800 => "seven_day".to_string(),
s => {
let hours = s / 3600;
if hours >= 24 {
@@ -1350,21 +1340,3 @@ fn now_millis() -> i64 {
.unwrap_or_default()
.as_millis() as i64
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn window_seconds_map_to_expected_tier_names() {
// 官方特例窗口
assert_eq!(window_seconds_to_tier_name(18000), TIER_FIVE_HOUR);
assert_eq!(window_seconds_to_tier_name(604800), TIER_SEVEN_DAY);
// Codex 免费方案的次要窗口是 30 天(30 * 24 * 3600 = 2_592_000 秒)。
// 前端 TIER_I18N_KEYS 与 tray 月分组都需要认得 "30_day",见 #3651。
assert_eq!(window_seconds_to_tier_name(2_592_000), TIER_THIRTY_DAY);
// 其他窗口按小时/天回退命名
assert_eq!(window_seconds_to_tier_name(3600), "1_hour");
assert_eq!(window_seconds_to_tier_name(86400), "1_day");
}
}
+3 -18
View File
@@ -19,13 +19,8 @@ const W_TIER_NAMES: &[&str] = &[
crate::services::subscription::TIER_SEVEN_DAY_OPUS,
crate::services::subscription::TIER_SEVEN_DAY_SONNET,
];
// 月窗口分组:火山方舟 Agent/Coding Plan 的月窗口(5h/周/月 三档)
// 以及 Codex 免费方案的 30 天窗口(#3651)——两者都归入 "m" 档,避免免费
// Codex 账号在托盘里空白(前端 footer 能看到、托盘却不显示的不对称)。
const M_TIER_NAMES: &[&str] = &[
crate::services::subscription::TIER_MONTHLY,
crate::services::subscription::TIER_THIRTY_DAY,
];
// 火山方舟 Agent/Coding Plan 的月窗口(5h/周/月 三档)
const M_TIER_NAMES: &[&str] = &[crate::services::subscription::TIER_MONTHLY];
const GEMINI_PRO_TIER_NAMES: &[&str] = &[crate::services::subscription::TIER_GEMINI_PRO];
const GEMINI_FLASH_TIER_NAMES: &[&str] = &[crate::services::subscription::TIER_GEMINI_FLASH];
const GEMINI_FLASH_LITE_TIER_NAMES: &[&str] =
@@ -887,7 +882,7 @@ mod tests {
use crate::services::subscription::{
CredentialStatus, QuotaTier, SubscriptionQuota, TIER_FIVE_HOUR, TIER_GEMINI_FLASH,
TIER_GEMINI_FLASH_LITE, TIER_GEMINI_PRO, TIER_MONTHLY, TIER_SEVEN_DAY, TIER_SEVEN_DAY_OPUS,
TIER_SEVEN_DAY_SONNET, TIER_THIRTY_DAY, TIER_WEEKLY_LIMIT,
TIER_SEVEN_DAY_SONNET, TIER_WEEKLY_LIMIT,
};
#[test]
@@ -969,16 +964,6 @@ mod tests {
assert!(s.contains("l80%"), "expected l80% in {s}");
}
#[test]
fn codex_summary_thirty_day_only_still_renders() {
// Codex 免费方案的唯一 tier 是 30 天窗口。前端 footer 已能显示(TIER_I18N_KEYS
// 有 "30_day"),托盘也必须能显示——否则就是这条不变量要防的非对称:footer
// 能看到、托盘却空白。30_day 归入 "m" 月分组。见 #3651。
let quota = make_quota("codex", true, vec![tier(TIER_THIRTY_DAY, 85.0)]);
let s = format_subscription_summary(&quota).expect("should format");
assert!(s.contains("m85%"), "expected m85% in {s}");
}
#[test]
fn gemini_summary_emoji_reflects_highest_tier_including_lite() {
// lite 是利用率最高的那条 → emoji 必须是红色,不能被 pro/flash 掩盖。
@@ -27,8 +27,6 @@ export const TIER_I18N_KEYS: Record<string, string> = {
seven_day: "subscription.sevenDay",
seven_day_opus: "subscription.sevenDayOpus",
seven_day_sonnet: "subscription.sevenDaySonnet",
// Codex 免费方案的次要窗口是 30 天(付费方案为 7 天)
"30_day": "subscription.thirtyDay",
// Gemini 模型分类
gemini_pro: "subscription.geminiPro",
gemini_flash: "subscription.geminiFlash",
-1
View File
@@ -2903,7 +2903,6 @@
"sevenDay": "7-Day",
"sevenDayOpus": "7-Day (Opus)",
"sevenDaySonnet": "7-Day (Sonnet)",
"thirtyDay": "30-Day",
"geminiPro": "Pro",
"geminiFlash": "Flash",
"geminiFlashLite": "Flash Lite",
-1
View File
@@ -2903,7 +2903,6 @@
"sevenDay": "7日間",
"sevenDayOpus": "7日間(Opus)",
"sevenDaySonnet": "7日間(Sonnet)",
"thirtyDay": "30日間",
"geminiPro": "Pro",
"geminiFlash": "Flash",
"geminiFlashLite": "Flash Lite",
-1
View File
@@ -2875,7 +2875,6 @@
"sevenDay": "7 天",
"sevenDayOpus": "7 天 (Opus)",
"sevenDaySonnet": "7 天 (Sonnet)",
"thirtyDay": "30 天",
"geminiPro": "Pro",
"geminiFlash": "Flash",
"geminiFlashLite": "Flash Lite",
-1
View File
@@ -2903,7 +2903,6 @@
"sevenDay": "7天",
"sevenDayOpus": "7天(Opus)",
"sevenDaySonnet": "7天(Sonnet)",
"thirtyDay": "30天",
"geminiPro": "Pro",
"geminiFlash": "Flash",
"geminiFlashLite": "Flash Lite",