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
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Changelog

## 1.5.10 - 2026-05-16

- Profiles page redesign: account cards become single-row list items (account name + plan / 5-hour and weekly quotas / actions all in one horizontal row). Profile-list page size raised from 4 to 8 entries per page.
- Removed the placeholder Runtime tab and page (UI-only stub with no backend wiring).
- Top navigation tabs centered horizontally instead of right-aligned.
- Settings page trimmed: removed the unwired Forward port, Admin port, Launch at login, and Configuration backup rows. Codex CLI path row collapsed from two lines to a single inline row with the "Change" button on the right.

## 1.5.9 - 2026-05-10

- Bulk plan refresh (run on app launch + each local-day rollover) now skips any profile whose `last_plan_check_ms` was confirmed within the last 6 hours. On a workspace with several OAuth accounts the previous launch trickled cards updating one-by-one for 10–25 s of background work; with the gate, repeat launches inside the same working day cost zero round-trips.
Expand Down
7 changes: 2 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ Codex 账号切换工具是一个本地桌面应用,用来在同一台机器
## 当前功能

- 仪表盘:显示当前账号、账号总数、可用账号和待登录账号数量。
- 账号页:每页 4 张账号卡片,支持切换、登录刷新、重命名、删除或清空、打开账号目录、编辑 Base URL。登录中点击同一按钮可取消(向 codex login 发送 SIGTERM / taskkill),适用于 OAuth 浏览器关闭后应用卡在等待回调的场景。
- 运行时页:先放置运行时可视化界面,后续再接入更多后端能力。
- 设置页:包含语言、主题、端口、开机自启占位、更新地址、配置备份、版本、许可证、检查更新、GitHub 入口,以及 **Codex CLI 路径**(显示当前路径与来源标签,自动定位失败或路径错误时随时手动指定,写入 `install_state.json` 的 `user_codex_path` 优先级最高)。
- 账号页:每页 8 个账号条目(横向单行布局:账号名 + 套餐 / 5 小时与周额度 / 操作按钮),支持切换、登录刷新、重命名、删除或清空、打开账号目录、编辑 Base URL。登录中点击同一按钮可取消(向 codex login 发送 SIGTERM / taskkill),适用于 OAuth 浏览器关闭后应用卡在等待回调的场景。
- 设置页:包含语言、主题、更新地址、版本、许可证、检查更新、GitHub 入口,以及 **Codex CLI 路径**(显示当前路径与来源标签,自动定位失败或路径错误时随时手动指定,写入 `install_state.json` 的 `user_codex_path` 优先级最高)。
- 引导页:展示添加账号、登录、切换账号的基础流程。
- 支持多套浅色和深色主题、中英文界面,以及没有 Tauri API 时的本地预览数据。

部分设置项和运行时条目目前只完成前端界面,后续再接入后端。

## 平台支持

- macOS:原生 Tauri 桌面端,同时保留 `macOS-backup/` 下的兼容脚本。
Expand Down
7 changes: 2 additions & 5 deletions README.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,11 @@ Codex 账号切换工具是一个本地桌面应用,用来在同一台机器
## 当前功能

- 仪表盘:显示当前账号、账号总数、可用账号和待登录账号数量。
- 账号页:每页 4 张账号卡片,支持切换、登录刷新、重命名、删除或清空、打开账号目录、编辑 Base URL。登录中点击同一按钮可取消(向 codex login 发送 SIGTERM / taskkill),适用于 OAuth 浏览器关闭后应用卡在等待回调的场景。
- 运行时页:先放置运行时可视化界面,后续再接入更多后端能力。
- 设置页:包含语言、主题、端口、开机自启占位、更新地址、配置备份、版本、许可证、检查更新、GitHub 入口,以及 **Codex CLI 路径**(显示当前路径与来源标签,自动定位失败或路径错误时随时手动指定,写入 `install_state.json` 的 `user_codex_path` 优先级最高)。
- 账号页:每页 8 个账号条目(横向单行布局:账号名 + 套餐 / 5 小时与周额度 / 操作按钮),支持切换、登录刷新、重命名、删除或清空、打开账号目录、编辑 Base URL。登录中点击同一按钮可取消(向 codex login 发送 SIGTERM / taskkill),适用于 OAuth 浏览器关闭后应用卡在等待回调的场景。
- 设置页:包含语言、主题、更新地址、版本、许可证、检查更新、GitHub 入口,以及 **Codex CLI 路径**(显示当前路径与来源标签,自动定位失败或路径错误时随时手动指定,写入 `install_state.json` 的 `user_codex_path` 优先级最高)。
- 引导页:展示添加账号、登录、切换账号的基础流程。
- 支持多套浅色和深色主题、中英文界面,以及没有 Tauri API 时的本地预览数据。

部分设置项和运行时条目目前只完成前端界面,后续再接入后端。

## 平台支持

- macOS:原生 Tauri 桌面端,同时保留 `macOS-backup/` 下的兼容脚本。
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "codex_switch",
"private": true,
"version": "1.5.9",
"version": "1.5.10",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "codex_switch"
version = "1.5.9"
version = "1.5.10"
description = "Native Tauri control panel for Codex account switching"
authors = ["Cmochance"]
edition = "2021"
Expand Down
70 changes: 4 additions & 66 deletions src-tauri/mac/front/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
<nav class="route-tabs" aria-label="Primary navigation">
<a class="route-tab" href="#dashboard" data-route-tab="dashboard" data-i18n-key="navDashboard">Dashboard</a>
<a class="route-tab" href="#profiles" data-route-tab="profiles" data-i18n-key="navProfiles">Profiles</a>
<a class="route-tab" href="#runtime" data-route-tab="runtime" data-i18n-key="navRuntime">Runtime</a>
<a class="route-tab" href="#settings" data-route-tab="settings" data-i18n-key="navSettings">Settings</a>
<a class="route-tab" href="#guide" data-route-tab="guide" data-i18n-key="navGuide">Guide</a>
</nav>
Expand Down Expand Up @@ -97,7 +96,6 @@ <h2 id="control-deck-heading" class="section-title section-title-rail">Control D
<section class="profiles-stage">
<div class="profiles-header">
<div>
<p class="page-kicker" data-i18n-key="navProfiles">Profiles</p>
<h2 id="profiles-heading" class="section-title">Profiles</h2>
</div>

Expand All @@ -116,37 +114,6 @@ <h2 id="profiles-heading" class="section-title">Profiles</h2>
</section>
</section>

<section class="page" id="page-runtime" data-page="runtime">
<div class="page-title-block">
<p class="page-kicker" data-i18n-key="navRuntime">Runtime</p>
<h2 class="section-title" data-i18n-key="runtimeTitle">Runtime Console</h2>
<p class="page-copy" data-i18n-key="runtimeSubtitle">Front-end layout for runtime visibility before backend wiring.</p>
</div>

<div class="settings-grid runtime-grid">
<article class="setting-card">
<span class="setting-status is-live" data-i18n-key="runtimeDraftStatus">UI draft</span>
<strong data-i18n-key="runtimeCodexApp">Codex desktop app</strong>
<p data-i18n-key="runtimeCodexAppCopy">Launch and activation controls will stay connected to the existing platform runtime.</p>
</article>
<article class="setting-card">
<span class="setting-status" data-i18n-key="runtimeDeferredStatus">Not wired</span>
<strong data-i18n-key="runtimeShellShim">Shell shim</strong>
<p data-i18n-key="runtimeShellShimCopy">Future controls can expose the managed command path without changing profile data.</p>
</article>
<article class="setting-card">
<span class="setting-status" data-i18n-key="runtimeDeferredStatus">Not wired</span>
<strong data-i18n-key="runtimeAuthRefresh">Auth refresh</strong>
<p data-i18n-key="runtimeAuthRefreshCopy">Queue, retry, and last-run details can be shown here after backend support lands.</p>
</article>
<article class="setting-card">
<span class="setting-status" data-i18n-key="runtimeDeferredStatus">Not wired</span>
<strong data-i18n-key="runtimeBackupRoot">Backup root</strong>
<p data-i18n-key="runtimeBackupRootCopy">Profile storage and autosave paths can be surfaced here in a later phase.</p>
</article>
</div>
</section>

<section class="page" id="page-settings" data-page="settings">
<article class="settings-panel settings-panel--runtime">
<div class="settings-row">
Expand Down Expand Up @@ -176,44 +143,15 @@ <h2 class="section-title" data-i18n-key="runtimeTitle">Runtime Console</h2>
</button>
</div>
</div>
<label class="settings-row settings-row--field">
<strong data-i18n-key="settingsForwardPort">Forward port</strong>
<input class="settings-input" type="number" min="1" max="65535" inputmode="numeric" value="18082" />
</label>
<label class="settings-row settings-row--field">
<strong data-i18n-key="settingsAdminPort">Admin port</strong>
<input class="settings-input" type="number" min="1" max="65535" inputmode="numeric" value="18081" />
</label>
<div class="settings-row">
<strong data-i18n-key="settingsLaunchAtLogin">Launch at login</strong>
<label class="settings-switch">
<input type="checkbox" />
<span aria-hidden="true"></span>
</label>
</div>
<label class="settings-row settings-row--field">
<strong data-i18n-key="settingsUpdateUrl">Update URL</strong>
<input id="settings-update-url-input" class="settings-input" type="url" value="https://api.github.com/repos/Cmochance/Codex_Account_Switch/releases/latest" />
</label>
<div class="settings-row settings-row--stacked">
<div class="settings-row">
<strong id="settings-codex-cli-label">Codex CLI path</strong>
<div class="settings-row-content">
<p id="settings-codex-cli-value" class="settings-value">--</p>
<div class="settings-action-row">
<button id="settings-codex-cli-button" class="settings-action-button" type="button">Change</button>
</div>
</div>
</div>
<div class="settings-row settings-row--stacked">
<strong data-i18n-key="settingsConfigBackup">Configuration backup</strong>
<div class="settings-row-content">
<div class="settings-action-row">
<button class="settings-action-button" type="button" data-i18n-key="settingsBackupNow">Back up now</button>
<button class="settings-action-button" type="button" data-i18n-key="settingsExportConfig">Export config</button>
<button class="settings-action-button" type="button" data-i18n-key="settingsImportConfig">Import config</button>
</div>
<p class="settings-value" data-i18n-key="settingsNoBackup">No backups yet</p>
<p class="settings-help" data-i18n-key="settingsBackupCopy">Exported configs include API keys. Keep them only on trusted devices.</p>
<div class="settings-cli-inline">
<p id="settings-codex-cli-value" class="settings-value settings-value--inline">--</p>
<button id="settings-codex-cli-button" class="settings-action-button" type="button">Change</button>
</div>
</div>
<div class="settings-row">
Expand Down
108 changes: 81 additions & 27 deletions src-tauri/mac/front/styles.css
Original file line number Diff line number Diff line change
Expand Up @@ -175,28 +175,32 @@ button.pager-pill:hover:not(:disabled) {
}

.profiles-grid {
display: grid;
grid-template-columns: repeat(2, minmax(0, 1fr));
gap: 14px;
display: flex;
flex-direction: column;
gap: 8px;
}

.profile-card {
display: flex;
flex-direction: column;
gap: 18px;
display: grid;
grid-template-columns: minmax(0, 1fr) max-content;
grid-template-areas:
"title title"
"quotas actions";
align-items: center;
row-gap: 10px;
column-gap: 18px;
min-width: 0;
min-height: 188px;
padding: 18px;
padding: 14px 18px;
border: 1px solid var(--border-accent);
border-radius: var(--radius-profile);
background:
radial-gradient(circle at 100% 0%, rgba(255, 255, 255, 0.52), transparent 16rem),
linear-gradient(180deg, rgba(250, 248, 244, 0.98), rgba(243, 239, 234, 0.98));
box-shadow:
var(--shadow-card),
inset 0 1px 0 rgba(255, 255, 255, 0.9);
border-radius: var(--radius-metric);
background: linear-gradient(180deg, rgba(250, 248, 244, 0.98), rgba(243, 239, 234, 0.98));
box-shadow: inset 0 1px 0 rgba(255, 255, 255, 0.9);
}

.profile-title-wrap { grid-area: title; }
.profile-quota-stack { grid-area: quotas; }
.profile-card-actions { grid-area: actions; }

.profile-card.status-current {
border-color: rgba(199, 227, 238, 0.98);
}
Expand All @@ -208,8 +212,10 @@ button.pager-pill:hover:not(:disabled) {

.profile-title-wrap {
display: flex;
flex-direction: column;
gap: 8px;
flex-direction: row;
align-items: baseline;
flex-wrap: wrap;
gap: 4px 12px;
min-width: 0;
}

Expand All @@ -235,14 +241,28 @@ button.pager-pill:hover:not(:disabled) {
color: #727684;
}

.profile-quota-stack,
.profile-quota-stack {
display: flex;
flex-direction: row;
gap: 24px;
align-items: center;
min-width: 0;
}

.current-quota-stack {
display: flex;
flex-direction: column;
gap: 14px;
}

.profile-quota-metric,
.profile-quota-metric {
display: flex;
flex-direction: column;
gap: 4px;
flex: 1;
min-width: 0;
}

.current-quota-metric {
display: flex;
flex-direction: column;
Expand All @@ -267,6 +287,14 @@ button.pager-pill:hover:not(:disabled) {
min-width: 0;
}

.profile-quota-line {
gap: 8px;
}

.profile-quota-stack .quota-track {
height: 6px;
}

.current-quota-line {
gap: 8px;
}
Expand All @@ -292,7 +320,10 @@ button.pager-pill:hover:not(:disabled) {

.current-quota-title,
.current-quota-value,
.current-quota-refresh {
.current-quota-refresh,
.profile-quota-title,
.profile-quota-value,
.profile-quota-refresh {
font-size: 0.78rem;
}

Expand Down Expand Up @@ -338,10 +369,18 @@ button.pager-pill:hover:not(:disabled) {
}

.profile-card-actions {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
margin-top: auto;
display: flex;
flex-wrap: wrap;
justify-content: flex-end;
gap: 6px;
margin-top: 0;
}

.profile-card-actions .profile-action-button {
height: 28px;
padding: 0 10px;
font-size: 0.78rem;
white-space: nowrap;
}

.profile-action-button,
Expand Down Expand Up @@ -684,13 +723,29 @@ button.pager-pill:disabled {
justify-content: flex-start;
}

.profiles-grid,
.right-rail {
grid-template-columns: 1fr;
}

.current-actions,
.profile-card {
grid-template-columns: 1fr;
grid-template-areas:
"title"
"quotas"
"actions";
}

.profile-quota-stack {
flex-direction: column;
align-items: stretch;
gap: 8px;
}

.profile-card-actions {
justify-content: flex-start;
}

.current-actions {
grid-template-columns: repeat(2, minmax(0, 1fr));
}

Expand Down Expand Up @@ -725,7 +780,6 @@ button.pager-pill:disabled {
}

.current-actions,
.profile-card-actions,
.dialog-actions {
grid-template-columns: 1fr;
}
Expand Down
Loading
Loading