feat: 路由不再开机自动接管 + 保存分组即写直连配置 + 官方登录完整备份 (v1.5.16)

- 启动不再自动 router.start():只想用其它功能的用户不再被接管
- 新增 applyDirectToCodex():保存 responses 中转分组即把直连配置写进
  config.toml+auth.json(非本地路由),重启 Codex 即用;本地路由降级为
  '启用本地路由(高级)'显式选项
- chat 协议转换分组(DeepSeek/GLM/Kimi)保存时只提示需启用路由,不自动起
- 新增 snapshotOfficialLogin():首次接管前完整快照官方 auth.json(含OAuth
  tokens)+config.toml(router.json加密存+落盘副本);restoreDirect 优先用它
  100%还原官方登录态,并清理 td-direct 残段
- setActive 按 isRunning 分流:路由在跑走本地路由秒切,否则写直连需重启
- 隔离测试:登录态21/21 + Mac custom回归9/9 全绿
- 版本 1.5.15 → 1.5.16

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
mac
2026-07-16 22:36:56 +08:00
parent 3f27682e78
commit 45ee76e3c8
10 changed files with 215 additions and 54 deletions
+14 -4
View File
@@ -1414,9 +1414,19 @@ $("#grp-save").addEventListener("click", async () => {
// 编辑留空时不传 key 字段,避免覆盖
if (grpEditing && !key) delete group.key;
try {
renderRouter(await apic.routerUpsertGroup(group));
const st = await apic.routerUpsertGroup(group);
renderRouter(st);
closeGrpModal();
toast("已保存分组 ✅", "ok");
// 保存后根据是否已把直连中转配置写进 Codex 给出对应提示
if (st._directApplied) {
toast("已保存并写入 Codex 配置 ✅ 重启 Codex 即用当前分组", "ok");
} else if (st._directError) {
toast("已保存,但写入 Codex 配置失败:" + st._directError, "err");
} else if (st._directSkipped) {
toast("已保存分组。" + (st._directReason || "该分组需启用本地路由或补全密钥后才能接入 Codex"), "warn");
} else {
toast("已保存分组 ✅", "ok");
}
} catch (e) {
toast("保存失败:" + (e.message || e), "err");
}
@@ -1473,13 +1483,13 @@ $("#router-save-port").addEventListener("click", async () => {
}
});
$("#router-apply").addEventListener("click", async (ev) => {
if (!confirm("将修改 Codex 的 config.toml,指向本地路由(会自动备份)。\n注意:启用后账号切换请统一在本软件切,不要再用 cc-switch,以免冲突。\n\n确认?")) return;
if (!confirm("【高级】启用本地路由:将把 Codex 的 config.toml 改为指向本地路由并启动路由进程(会自动备份)。\n\n普通使用无需此项——保存分组时已把中转配置直接写进 Codex,重启即用。\n仅当你需要「切分组免重启」或使用 Chat 协议转换分组(如 DeepSeek/GLM/Kimi)时才需要启用路由。\n\n注意:启用后账号切换请统一在本软件切,不要再用 cc-switch,以免冲突。\n\n确认启用?")) return;
const btn = ev.currentTarget;
busy(btn, true, "配置中…");
try {
const r = await apic.routerApplyCodex();
renderRouter(r.status);
toast("已配置到 Codex ✅ 重启 Codex 后即可通过本地路由,之后切分组无需重启", "ok");
toast("已启用本地路由 ✅ 重启 Codex 后即可通过路由,之后切分组无需重启", "ok");
} catch (e) {
toast("配置失败:" + (e.message || e), "err");
} finally {
+1 -1
View File
@@ -300,7 +300,7 @@
<div><code id="router-addr">—</code> <span class="pc-badge" id="router-state">未启动</span></div>
</div>
<div class="btn-group">
<button id="router-apply" class="btn primary">一键配置到 Codex</button>
<button id="router-apply" class="btn primary">启用本地路由(高级)</button>
<button id="router-apply-claude" class="btn">接入 Claude Code</button>
<button id="router-toggle" class="btn">启动</button>
</div>
+1
View File
@@ -217,6 +217,7 @@ h3 { margin: 0; font-size: 16px; }
max-width: 80%; font-size: 13px; }
.toast.ok { border-color: var(--ok); }
.toast.err { border-color: var(--danger); }
.toast.warn { border-color: #f5a623; }
/* 卡片内按钮忙碌态 */
.installing { pointer-events: none; opacity: .7; }