chore(release): bump version to FlowPilot1.0
@@ -1,4 +1,4 @@
|
|||||||
# Multi-Page Automation
|
# FlowPilot
|
||||||
|
|
||||||
一个用于批量跑通 ChatGPT OAuth 注册/登录流程的 Chrome 扩展。
|
一个用于批量跑通 ChatGPT OAuth 注册/登录流程的 Chrome 扩展。
|
||||||
|
|
||||||
@@ -20,11 +20,11 @@
|
|||||||
|
|
||||||
## Star History
|
## Star History
|
||||||
|
|
||||||
<a href="https://www.star-history.com/?repos=QLHazyCoder%2Fcodex-oauth-automation-extension&type=timeline&logscale&legend=top-left">
|
<a href="https://www.star-history.com/?repos=QLHazyCoder%2FFlowPilot&type=timeline&logscale&legend=top-left">
|
||||||
<picture>
|
<picture>
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=QLHazyCoder/codex-oauth-automation-extension&type=timeline&logscale&theme=dark&legend=top-left" />
|
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=QLHazyCoder/FlowPilot&type=timeline&logscale&theme=dark&legend=top-left" />
|
||||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=QLHazyCoder/codex-oauth-automation-extension&type=timeline&logscale&legend=top-left" />
|
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=QLHazyCoder/FlowPilot&type=timeline&logscale&legend=top-left" />
|
||||||
<img alt="Star History Chart" src="https://api.star-history.com/chart?repos=QLHazyCoder/codex-oauth-automation-extension&type=timeline&logscale&legend=top-left" />
|
<img alt="Star History Chart" src="https://api.star-history.com/chart?repos=QLHazyCoder/FlowPilot&type=timeline&logscale&legend=top-left" />
|
||||||
</picture>
|
</picture>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
|||||||
@@ -7244,7 +7244,7 @@ async function fetchIcloudHideMyEmail(options = {}) {
|
|||||||
: {}),
|
: {}),
|
||||||
hme: generatedAlias,
|
hme: generatedAlias,
|
||||||
label: getIcloudAliasLabel(),
|
label: getIcloudAliasLabel(),
|
||||||
note: 'Generated through Multi-Page Automation',
|
note: 'Generated through FlowPilot',
|
||||||
};
|
};
|
||||||
|
|
||||||
let alias = '';
|
let alias = '';
|
||||||
|
|||||||
|
After Width: | Height: | Size: 1.4 MiB |
@@ -1,4 +1,4 @@
|
|||||||
# Codex 注册扩展相关项目、更新、邮箱、PayPal 与 Clash Verge 配置教程
|
# FlowPilot 相关项目、更新、邮箱、PayPal 与 Clash Verge 配置教程
|
||||||
|
|
||||||
本教程用于说明相关项目地址、扩展更新方式、`Cloudflare Temp Email`、`iCloud 隐私邮箱` 与 `QQ 邮箱` 的使用方法、`HeroSMS` 手机接码扩展能力、`PayPal` 注册绑卡流程、扩展内置动态 IP 代理、节点检测与纯净度检查,以及 [Clash Verge](https://github.com/clash-verge-rev/clash-verge-rev) 的 `🔁 非港轮询` 配置方法。
|
本教程用于说明相关项目地址、扩展更新方式、`Cloudflare Temp Email`、`iCloud 隐私邮箱` 与 `QQ 邮箱` 的使用方法、`HeroSMS` 手机接码扩展能力、`PayPal` 注册绑卡流程、扩展内置动态 IP 代理、节点检测与纯净度检查,以及 [Clash Verge](https://github.com/clash-verge-rev/clash-verge-rev) 的 `🔁 非港轮询` 配置方法。
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# 使用教程总索引
|
# 使用教程总索引
|
||||||
|
|
||||||
本目录用于维护 `Codex 注册扩展` 的分部分使用教程。
|
本目录用于维护 `FlowPilot` 的分部分使用教程。
|
||||||
从现在开始,教程正文不再直接堆到这一个文件里,而是拆到 `分部分/` 目录下分别维护。
|
从现在开始,教程正文不再直接堆到这一个文件里,而是拆到 `分部分/` 目录下分别维护。
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# 公告书写标准
|
# 公告书写标准
|
||||||
|
|
||||||
本文件用于约束 AI 生成“账号贡献站 / Codex 注册扩展”相关公告时的 Markdown 格式。
|
本文件用于约束 AI 生成“账号贡献站 / FlowPilot”相关公告时的 Markdown 格式。
|
||||||
|
|
||||||
使用方式:
|
使用方式:
|
||||||
|
|
||||||
@@ -184,7 +184,7 @@ AI 生成公告时禁止:
|
|||||||
把下面这段直接发给 AI:
|
把下面这段直接发给 AI:
|
||||||
|
|
||||||
```md
|
```md
|
||||||
请帮我写一份“账号贡献站 / Codex 注册扩展”公告,严格遵守以下要求:
|
请帮我写一份“账号贡献站 / FlowPilot”公告,严格遵守以下要求:
|
||||||
|
|
||||||
1. 输出必须是 Markdown
|
1. 输出必须是 Markdown
|
||||||
2. 不要使用 HTML
|
2. 不要使用 HTML
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 327 B After Width: | Height: | Size: 763 B |
|
Before Width: | Height: | Size: 1.0 KiB After Width: | Height: | Size: 3.3 KiB |
@@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"manifest_version": 3,
|
"manifest_version": 3,
|
||||||
"name": "codex-oauth-automation-extension",
|
"name": "FlowPilot",
|
||||||
"version": "9.99",
|
"version": "1.0",
|
||||||
"version_name": "Ultra9.99",
|
"version_name": "FlowPilot1.0",
|
||||||
"description": "用于自动执行多步骤 OAuth 注册流程",
|
"description": "用于自动执行多步骤 OAuth 注册流程",
|
||||||
"permissions": [
|
"permissions": [
|
||||||
"sidePanel",
|
"sidePanel",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "codex-oauth-automation-extension",
|
"name": "flowpilot",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/* ============================================================
|
/* ============================================================
|
||||||
MultiPage Automation — Side Panel
|
FlowPilot — Side Panel
|
||||||
Design: Swiss Modernism + Developer Tool
|
Design: Swiss Modernism + Developer Tool
|
||||||
Font: Inter (UI) + JetBrains Mono (code)
|
Font: Inter (UI) + JetBrains Mono (code)
|
||||||
Themes: Light (default) + Dark (toggle)
|
Themes: Light (default) + Dark (toggle)
|
||||||
@@ -7,35 +7,36 @@
|
|||||||
|
|
||||||
/* ---- Light Theme (default) ---- */
|
/* ---- Light Theme (default) ---- */
|
||||||
:root {
|
:root {
|
||||||
--bg-base: #ffffff;
|
--bg-base: #eef6f4;
|
||||||
--bg-surface: #f7f8fa;
|
--bg-surface: #fbfefd;
|
||||||
--bg-elevated: #eef0f4;
|
--bg-field: #f7fbfa;
|
||||||
--bg-hover: #e4e7ec;
|
--bg-elevated: #e7f1ee;
|
||||||
--bg-active: #dce0e8;
|
--bg-hover: #dce9e6;
|
||||||
|
--bg-active: #d0e0dc;
|
||||||
|
|
||||||
--border: #d8dce3;
|
--border: #c8d9d5;
|
||||||
--border-subtle: #e8ecf1;
|
--border-subtle: #dce9e6;
|
||||||
|
|
||||||
--text-primary: #1a1d24;
|
--text-primary: #162025;
|
||||||
--text-secondary: #5c6370;
|
--text-secondary: #516368;
|
||||||
--text-muted: #9ca3af;
|
--text-muted: #7f9194;
|
||||||
|
|
||||||
--blue: #2563eb;
|
--blue: #1473e6;
|
||||||
--blue-soft: rgba(37, 99, 235, 0.08);
|
--blue-soft: rgba(20, 115, 230, 0.09);
|
||||||
--blue-glow: rgba(37, 99, 235, 0.12);
|
--blue-glow: rgba(20, 115, 230, 0.16);
|
||||||
--green: #16a34a;
|
--green: #5eaf00;
|
||||||
--green-soft: rgba(22, 163, 74, 0.08);
|
--green-soft: rgba(94, 175, 0, 0.10);
|
||||||
--orange: #ea580c;
|
--orange: #d8661f;
|
||||||
--orange-soft: rgba(234, 88, 12, 0.08);
|
--orange-soft: rgba(216, 102, 31, 0.10);
|
||||||
--amber: #d97706;
|
--amber: #b98200;
|
||||||
--amber-soft: rgba(217, 119, 6, 0.08);
|
--amber-soft: rgba(185, 130, 0, 0.10);
|
||||||
--red: #dc2626;
|
--red: #d63c3c;
|
||||||
--red-soft: rgba(220, 38, 38, 0.08);
|
--red-soft: rgba(214, 60, 60, 0.10);
|
||||||
--cyan: #0891b2;
|
--cyan: #0aa5bd;
|
||||||
--purple: #7c3aed;
|
--purple: #7160d7;
|
||||||
|
|
||||||
--shadow-sm: 0 1px 2px rgba(0,0,0,0.04);
|
--shadow-sm: 0 1px 3px rgba(22, 32, 37, 0.06);
|
||||||
--shadow-md: 0 2px 6px rgba(0,0,0,0.06);
|
--shadow-md: 0 6px 18px rgba(22, 32, 37, 0.10);
|
||||||
|
|
||||||
--radius-sm: 6px;
|
--radius-sm: 6px;
|
||||||
--radius-md: 8px;
|
--radius-md: 8px;
|
||||||
@@ -44,35 +45,36 @@
|
|||||||
|
|
||||||
/* ---- Dark Theme ---- */
|
/* ---- Dark Theme ---- */
|
||||||
[data-theme="dark"] {
|
[data-theme="dark"] {
|
||||||
--bg-base: #0f1117;
|
--bg-base: #0c1214;
|
||||||
--bg-surface: #181a21;
|
--bg-surface: #141b1e;
|
||||||
--bg-elevated: #21242d;
|
--bg-field: #101719;
|
||||||
--bg-hover: #2a2e38;
|
--bg-elevated: #1d272a;
|
||||||
--bg-active: #323844;
|
--bg-hover: #263236;
|
||||||
|
--bg-active: #2f3d42;
|
||||||
|
|
||||||
--border: #2a2e38;
|
--border: #2a383c;
|
||||||
--border-subtle: #21242d;
|
--border-subtle: #1f2b2f;
|
||||||
|
|
||||||
--text-primary: #e4e6eb;
|
--text-primary: #edf5f3;
|
||||||
--text-secondary: #8b919e;
|
--text-secondary: #9cada9;
|
||||||
--text-muted: #565c6a;
|
--text-muted: #748583;
|
||||||
|
|
||||||
--blue: #3b82f6;
|
--blue: #4d9aff;
|
||||||
--blue-soft: rgba(59, 130, 246, 0.12);
|
--blue-soft: rgba(77, 154, 255, 0.14);
|
||||||
--blue-glow: rgba(59, 130, 246, 0.18);
|
--blue-glow: rgba(77, 154, 255, 0.22);
|
||||||
--green: #22c55e;
|
--green: #8bdc2d;
|
||||||
--green-soft: rgba(34, 197, 94, 0.12);
|
--green-soft: rgba(139, 220, 45, 0.14);
|
||||||
--orange: #f97316;
|
--orange: #ff9148;
|
||||||
--orange-soft: rgba(249, 115, 22, 0.12);
|
--orange-soft: rgba(255, 145, 72, 0.14);
|
||||||
--amber: #f59e0b;
|
--amber: #ffc247;
|
||||||
--amber-soft: rgba(245, 158, 11, 0.12);
|
--amber-soft: rgba(255, 194, 71, 0.14);
|
||||||
--red: #ef4444;
|
--red: #ff6b6b;
|
||||||
--red-soft: rgba(239, 68, 68, 0.12);
|
--red-soft: rgba(255, 107, 107, 0.14);
|
||||||
--cyan: #06b6d4;
|
--cyan: #38d5e6;
|
||||||
--purple: #a78bfa;
|
--purple: #a997ff;
|
||||||
|
|
||||||
--shadow-sm: 0 1px 2px rgba(0,0,0,0.2);
|
--shadow-sm: 0 1px 2px rgba(0,0,0,0.22);
|
||||||
--shadow-md: 0 2px 8px rgba(0,0,0,0.3);
|
--shadow-md: 0 8px 24px rgba(0,0,0,0.34);
|
||||||
}
|
}
|
||||||
|
|
||||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||||
@@ -109,7 +111,7 @@ header {
|
|||||||
margin-bottom: 14px;
|
margin-bottom: 14px;
|
||||||
padding-top: 4px;
|
padding-top: 4px;
|
||||||
padding-bottom: 12px;
|
padding-bottom: 12px;
|
||||||
background: color-mix(in srgb, var(--bg-base) 94%, transparent);
|
background: color-mix(in srgb, var(--bg-surface) 92%, transparent);
|
||||||
backdrop-filter: blur(8px);
|
backdrop-filter: blur(8px);
|
||||||
border-bottom: 1px solid var(--border-subtle);
|
border-bottom: 1px solid var(--border-subtle);
|
||||||
}
|
}
|
||||||
@@ -447,7 +449,7 @@ header {
|
|||||||
width: 42px;
|
width: 42px;
|
||||||
padding: 6px 4px;
|
padding: 6px 4px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
background: var(--bg-base);
|
background: var(--bg-field);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
@@ -1176,7 +1178,7 @@ header {
|
|||||||
padding: 2px 6px;
|
padding: 2px 6px;
|
||||||
border-radius: 999px;
|
border-radius: 999px;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
background: var(--bg-base);
|
background: var(--bg-field);
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
||||||
@@ -1238,7 +1240,7 @@ header {
|
|||||||
.data-input {
|
.data-input {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 7px 10px;
|
padding: 7px 10px;
|
||||||
background: var(--bg-base);
|
background: var(--bg-field);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
@@ -1256,7 +1258,7 @@ header {
|
|||||||
min-height: 88px;
|
min-height: 88px;
|
||||||
resize: vertical;
|
resize: vertical;
|
||||||
padding: 8px 10px;
|
padding: 8px 10px;
|
||||||
background: var(--bg-base);
|
background: var(--bg-field);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
@@ -1890,7 +1892,7 @@ header {
|
|||||||
.data-select {
|
.data-select {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 7px 10px;
|
padding: 7px 10px;
|
||||||
background: var(--bg-base);
|
background: var(--bg-field);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
color: var(--text-primary);
|
color: var(--text-primary);
|
||||||
@@ -1904,6 +1906,11 @@ header {
|
|||||||
.data-select:focus { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-soft); }
|
.data-select:focus { border-color: var(--blue); box-shadow: 0 0 0 3px var(--blue-soft); }
|
||||||
[data-theme="dark"] .data-select { color-scheme: dark; }
|
[data-theme="dark"] .data-select { color-scheme: dark; }
|
||||||
|
|
||||||
|
#select-flow {
|
||||||
|
text-align: center;
|
||||||
|
text-align-last: center;
|
||||||
|
}
|
||||||
|
|
||||||
.data-input[readonly] {
|
.data-input[readonly] {
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
background: var(--bg-surface);
|
background: var(--bg-surface);
|
||||||
@@ -1955,7 +1962,7 @@ header {
|
|||||||
padding: 4px;
|
padding: 4px;
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
background: var(--bg-base);
|
background: var(--bg-surface);
|
||||||
box-shadow: var(--shadow-md);
|
box-shadow: var(--shadow-md);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2158,7 +2165,7 @@ header {
|
|||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
border-radius: 50%;
|
border-radius: 50%;
|
||||||
background: var(--bg-base);
|
background: var(--bg-field);
|
||||||
box-shadow: var(--shadow-sm);
|
box-shadow: var(--shadow-sm);
|
||||||
transition: transform var(--transition), background var(--transition);
|
transition: transform var(--transition), background var(--transition);
|
||||||
}
|
}
|
||||||
@@ -2268,7 +2275,7 @@ header {
|
|||||||
padding: 6px;
|
padding: 6px;
|
||||||
max-height: 180px;
|
max-height: 180px;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
background: var(--bg-base);
|
background: var(--bg-field);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: var(--radius-sm);
|
border-radius: var(--radius-sm);
|
||||||
box-shadow: var(--shadow-md);
|
box-shadow: var(--shadow-md);
|
||||||
@@ -2755,7 +2762,7 @@ header {
|
|||||||
.step-manual-btn:disabled {
|
.step-manual-btn:disabled {
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
border-color: var(--border-subtle);
|
border-color: var(--border-subtle);
|
||||||
background: var(--bg-base);
|
background: var(--bg-field);
|
||||||
cursor: not-allowed;
|
cursor: not-allowed;
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
@@ -3269,7 +3276,7 @@ header {
|
|||||||
|
|
||||||
.modal-card {
|
.modal-card {
|
||||||
width: min(100%, 320px);
|
width: min(100%, 320px);
|
||||||
background: var(--bg-base);
|
background: var(--bg-surface);
|
||||||
border: 1px solid var(--border);
|
border: 1px solid var(--border);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: var(--shadow-md), 0 18px 36px rgba(0, 0, 0, 0.18);
|
box-shadow: var(--shadow-md), 0 18px 36px rgba(0, 0, 0, 0.18);
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>codex-oauth-automation-extension</title>
|
<title>FlowPilot</title>
|
||||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||||
<link
|
<link
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
<div class="header-version-block">
|
<div class="header-version-block">
|
||||||
<div class="header-version-main">
|
<div class="header-version-main">
|
||||||
<button id="extension-update-status" class="header-version-title header-version-link" type="button"
|
<button id="extension-update-status" class="header-version-title header-version-link" type="button"
|
||||||
aria-label="打开 GitHub Releases 页面" title="打开 GitHub Releases 页面">Ultra0.0</button>
|
aria-label="打开 GitHub Releases 页面" title="打开 GitHub Releases 页面">FlowPilot0.0</button>
|
||||||
<button id="btn-release-log" class="header-link-btn" type="button" hidden>更新日志</button>
|
<button id="btn-release-log" class="header-link-btn" type="button" hidden>更新日志</button>
|
||||||
</div>
|
</div>
|
||||||
<span id="extension-version-meta" class="header-version-meta" hidden></span>
|
<span id="extension-version-meta" class="header-version-meta" hidden></span>
|
||||||
@@ -111,10 +111,10 @@
|
|||||||
<section id="data-section">
|
<section id="data-section">
|
||||||
<div id="settings-card" class="data-card">
|
<div id="settings-card" class="data-card">
|
||||||
<div class="data-row">
|
<div class="data-row">
|
||||||
<span class="data-label">Flow</span>
|
<span class="data-label">注册</span>
|
||||||
<select id="select-flow" class="data-select" aria-label="Flow 选择">
|
<select id="select-flow" class="data-select" aria-label="Flow 选择">
|
||||||
<option value="codex" selected>codex</option>
|
<option value="codex" selected>codex</option>
|
||||||
<option value="pending-1" disabled>待添加</option>
|
<option value="pending-1" disabled>kiro</option>
|
||||||
<option value="pending-2" disabled>待添加</option>
|
<option value="pending-2" disabled>待添加</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -9729,7 +9729,7 @@ function getRepositoryHomeUrl() {
|
|||||||
return releasesPageUrl.replace(/\/releases\/?$/, '');
|
return releasesPageUrl.replace(/\/releases\/?$/, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'https://github.com/QLHazyCoder/codex-oauth-automation-extension';
|
return 'https://github.com/QLHazyCoder/FlowPilot';
|
||||||
}
|
}
|
||||||
|
|
||||||
function getReleaseListUrl() {
|
function getReleaseListUrl() {
|
||||||
@@ -9823,7 +9823,7 @@ function renderUpdateReleaseList(releases = []) {
|
|||||||
|
|
||||||
const version = document.createElement('span');
|
const version = document.createElement('span');
|
||||||
version.className = 'update-release-version';
|
version.className = 'update-release-version';
|
||||||
version.textContent = release.displayVersion || `Ultra${release.version}`;
|
version.textContent = release.displayVersion || `FlowPilot${release.version}`;
|
||||||
titleRow.appendChild(version);
|
titleRow.appendChild(version);
|
||||||
|
|
||||||
if (release.title) {
|
if (release.title) {
|
||||||
@@ -9925,21 +9925,21 @@ function renderReleaseSnapshot(snapshot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case 'ignored': {
|
case 'ignored': {
|
||||||
extensionUpdateStatus.textContent = localVersionText || 'Ultra0.0';
|
extensionUpdateStatus.textContent = localVersionText || 'FlowPilot0.0';
|
||||||
extensionUpdateStatus.classList.add('is-version-label');
|
extensionUpdateStatus.classList.add('is-version-label');
|
||||||
resetUpdateCard();
|
resetUpdateCard();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'latest': {
|
case 'latest': {
|
||||||
extensionUpdateStatus.textContent = localVersionText || 'Ultra0.0';
|
extensionUpdateStatus.textContent = localVersionText || 'FlowPilot0.0';
|
||||||
extensionUpdateStatus.classList.add('is-version-label');
|
extensionUpdateStatus.classList.add('is-version-label');
|
||||||
resetUpdateCard();
|
resetUpdateCard();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'empty': {
|
case 'empty': {
|
||||||
extensionUpdateStatus.textContent = localVersionText || 'Ultra0.0';
|
extensionUpdateStatus.textContent = localVersionText || 'FlowPilot0.0';
|
||||||
extensionUpdateStatus.classList.add('is-version-label');
|
extensionUpdateStatus.classList.add('is-version-label');
|
||||||
resetUpdateCard();
|
resetUpdateCard();
|
||||||
break;
|
break;
|
||||||
@@ -9947,7 +9947,7 @@ function renderReleaseSnapshot(snapshot) {
|
|||||||
|
|
||||||
case 'error':
|
case 'error':
|
||||||
default: {
|
default: {
|
||||||
extensionUpdateStatus.textContent = localVersionText || 'Ultra0.0';
|
extensionUpdateStatus.textContent = localVersionText || 'FlowPilot0.0';
|
||||||
extensionUpdateStatus.classList.add('is-version-label', 'is-check-failed');
|
extensionUpdateStatus.classList.add('is-version-label', 'is-check-failed');
|
||||||
extensionVersionMeta.textContent = snapshot?.errorMessage || 'GitHub Releases 检查失败';
|
extensionVersionMeta.textContent = snapshot?.errorMessage || 'GitHub Releases 检查失败';
|
||||||
extensionVersionMeta.hidden = false;
|
extensionVersionMeta.hidden = false;
|
||||||
@@ -9958,7 +9958,7 @@ function renderReleaseSnapshot(snapshot) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function initializeReleaseInfo() {
|
async function initializeReleaseInfo() {
|
||||||
const fallbackReleaseUrl = sidepanelUpdateService?.releasesPageUrl || 'https://github.com/QLHazyCoder/codex-oauth-automation-extension/releases';
|
const fallbackReleaseUrl = sidepanelUpdateService?.releasesPageUrl || 'https://github.com/QLHazyCoder/FlowPilot/releases';
|
||||||
|
|
||||||
if (btnReleaseLog) {
|
if (btnReleaseLog) {
|
||||||
btnReleaseLog.onclick = () => openExternalUrl(currentReleaseSnapshot?.logUrl || fallbackReleaseUrl);
|
btnReleaseLog.onclick = () => openExternalUrl(currentReleaseSnapshot?.logUrl || fallbackReleaseUrl);
|
||||||
@@ -9970,8 +9970,8 @@ async function initializeReleaseInfo() {
|
|||||||
|
|
||||||
const localVersion = sidepanelUpdateService?.getLocalVersionLabel?.(chrome.runtime.getManifest())
|
const localVersion = sidepanelUpdateService?.getLocalVersionLabel?.(chrome.runtime.getManifest())
|
||||||
|| chrome.runtime.getManifest()?.version_name
|
|| chrome.runtime.getManifest()?.version_name
|
||||||
|| (chrome.runtime.getManifest()?.version ? `Ultra${chrome.runtime.getManifest().version}` : '');
|
|| (chrome.runtime.getManifest()?.version ? `FlowPilot${chrome.runtime.getManifest().version}` : '');
|
||||||
extensionUpdateStatus.textContent = localVersion || 'Ultra0.0';
|
extensionUpdateStatus.textContent = localVersion || 'FlowPilot0.0';
|
||||||
extensionUpdateStatus.classList.remove('is-update-available', 'is-check-failed');
|
extensionUpdateStatus.classList.remove('is-update-available', 'is-check-failed');
|
||||||
extensionUpdateStatus.classList.add('is-version-label');
|
extensionUpdateStatus.classList.add('is-version-label');
|
||||||
extensionVersionMeta.hidden = true;
|
extensionVersionMeta.hidden = true;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
(() => {
|
(() => {
|
||||||
const GITHUB_OWNER = 'QLHazyCoder';
|
const GITHUB_OWNER = 'QLHazyCoder';
|
||||||
const GITHUB_REPO = 'codex-oauth-automation-extension';
|
const GITHUB_REPO = 'FlowPilot';
|
||||||
const RELEASES_PAGE_URL = `https://github.com/${GITHUB_OWNER}/${GITHUB_REPO}/releases`;
|
const RELEASES_PAGE_URL = `https://github.com/${GITHUB_OWNER}/${GITHUB_REPO}/releases`;
|
||||||
const RELEASES_API_URL = `https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/releases?per_page=10`;
|
const RELEASES_API_URL = `https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/releases?per_page=10`;
|
||||||
const CACHE_KEY = 'multipage-release-snapshot-v1';
|
const CACHE_KEY = 'multipage-release-snapshot-v1';
|
||||||
@@ -9,12 +9,16 @@
|
|||||||
const FETCH_TIMEOUT_MS = 8000;
|
const FETCH_TIMEOUT_MS = 8000;
|
||||||
const MAX_RELEASES = 10;
|
const MAX_RELEASES = 10;
|
||||||
const MAX_NOTES_PER_RELEASE = 5;
|
const MAX_NOTES_PER_RELEASE = 5;
|
||||||
|
const VERSION_FAMILY_FLOWPILOT = 'flowpilot';
|
||||||
const VERSION_FAMILY_ULTRA = 'ultra';
|
const VERSION_FAMILY_ULTRA = 'ultra';
|
||||||
const VERSION_FAMILY_PRO = 'pro';
|
const VERSION_FAMILY_PRO = 'pro';
|
||||||
const VERSION_FAMILY_LEGACY = 'legacy';
|
const VERSION_FAMILY_LEGACY = 'legacy';
|
||||||
|
|
||||||
function getVersionFamily(version, fallbackFamily = VERSION_FAMILY_LEGACY) {
|
function getVersionFamily(version, fallbackFamily = VERSION_FAMILY_LEGACY) {
|
||||||
const trimmed = String(version || '').trim();
|
const trimmed = String(version || '').trim();
|
||||||
|
if (/^flowpilot/i.test(trimmed)) {
|
||||||
|
return VERSION_FAMILY_FLOWPILOT;
|
||||||
|
}
|
||||||
if (/^ultra/i.test(trimmed)) {
|
if (/^ultra/i.test(trimmed)) {
|
||||||
return VERSION_FAMILY_ULTRA;
|
return VERSION_FAMILY_ULTRA;
|
||||||
}
|
}
|
||||||
@@ -28,7 +32,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function stripVersionPrefix(version) {
|
function stripVersionPrefix(version) {
|
||||||
return String(version || '').trim().replace(/^(?:ultra|pro|v)\s*/i, '');
|
return String(version || '').trim().replace(/^(?:flowpilot|ultra|pro|v)\s*/i, '');
|
||||||
}
|
}
|
||||||
|
|
||||||
function extractVersionCore(version) {
|
function extractVersionCore(version) {
|
||||||
@@ -63,6 +67,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getVersionFamilyPrefix(family) {
|
function getVersionFamilyPrefix(family) {
|
||||||
|
if (family === VERSION_FAMILY_FLOWPILOT) {
|
||||||
|
return 'FlowPilot';
|
||||||
|
}
|
||||||
if (family === VERSION_FAMILY_ULTRA) {
|
if (family === VERSION_FAMILY_ULTRA) {
|
||||||
return 'Ultra';
|
return 'Ultra';
|
||||||
}
|
}
|
||||||
@@ -73,6 +80,9 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getVersionFamilyRank(family) {
|
function getVersionFamilyRank(family) {
|
||||||
|
if (family === VERSION_FAMILY_FLOWPILOT) {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
if (family === VERSION_FAMILY_ULTRA) {
|
if (family === VERSION_FAMILY_ULTRA) {
|
||||||
return 3;
|
return 3;
|
||||||
}
|
}
|
||||||
@@ -206,7 +216,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getComparableReleaseVersion(release) {
|
function getComparableReleaseVersion(release) {
|
||||||
const fallbackFamily = [VERSION_FAMILY_ULTRA, VERSION_FAMILY_PRO].includes(release?.family)
|
const fallbackFamily = [VERSION_FAMILY_FLOWPILOT, VERSION_FAMILY_ULTRA, VERSION_FAMILY_PRO].includes(release?.family)
|
||||||
? release.family
|
? release.family
|
||||||
: VERSION_FAMILY_LEGACY;
|
: VERSION_FAMILY_LEGACY;
|
||||||
const displayVersion = String(release?.displayVersion || '').trim();
|
const displayVersion = String(release?.displayVersion || '').trim();
|
||||||
@@ -267,7 +277,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function setIgnoredUpdateVersion(version) {
|
function setIgnoredUpdateVersion(version) {
|
||||||
const normalized = formatDisplayVersion(version, VERSION_FAMILY_ULTRA) || String(version || '').trim();
|
const normalized = formatDisplayVersion(version, VERSION_FAMILY_FLOWPILOT) || String(version || '').trim();
|
||||||
try {
|
try {
|
||||||
if (normalized) {
|
if (normalized) {
|
||||||
localStorage.setItem(IGNORED_UPDATE_VERSION_KEY, normalized);
|
localStorage.setItem(IGNORED_UPDATE_VERSION_KEY, normalized);
|
||||||
@@ -387,17 +397,17 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getLocalVersionLabel(manifest = chrome.runtime.getManifest()) {
|
function getLocalVersionLabel(manifest = chrome.runtime.getManifest()) {
|
||||||
const versionName = formatDisplayVersion(manifest?.version_name, VERSION_FAMILY_ULTRA);
|
const versionName = formatDisplayVersion(manifest?.version_name, VERSION_FAMILY_FLOWPILOT);
|
||||||
if (versionName) {
|
if (versionName) {
|
||||||
return versionName;
|
return versionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
const versionCore = extractVersionCore(manifest?.version || '');
|
const versionCore = extractVersionCore(manifest?.version || '');
|
||||||
return versionCore ? formatDisplayVersion(`Ultra${versionCore}`, VERSION_FAMILY_ULTRA) : '';
|
return versionCore ? formatDisplayVersion(`FlowPilot${versionCore}`, VERSION_FAMILY_FLOWPILOT) : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getReleaseSnapshot(options = {}) {
|
async function getReleaseSnapshot(options = {}) {
|
||||||
const localVersion = getLocalVersionLabel(chrome.runtime.getManifest()) || 'Ultra0.0';
|
const localVersion = getLocalVersionLabel(chrome.runtime.getManifest()) || 'FlowPilot0.0';
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const releases = await loadReleases(options);
|
const releases = await loadReleases(options);
|
||||||
@@ -442,6 +452,7 @@
|
|||||||
getLocalVersionLabel,
|
getLocalVersionLabel,
|
||||||
getReleaseSnapshot,
|
getReleaseSnapshot,
|
||||||
ignoreReleaseSnapshot,
|
ignoreReleaseSnapshot,
|
||||||
|
repositoryUrl: `https://github.com/${GITHUB_OWNER}/${GITHUB_REPO}`,
|
||||||
releasesPageUrl: RELEASES_PAGE_URL,
|
releasesPageUrl: RELEASES_PAGE_URL,
|
||||||
stripVersionPrefix,
|
stripVersionPrefix,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ const source = fs.readFileSync('sidepanel/update-service.js', 'utf8');
|
|||||||
function createUpdateService(options = {}) {
|
function createUpdateService(options = {}) {
|
||||||
const manifest = options.manifest || {
|
const manifest = options.manifest || {
|
||||||
version: '1.0',
|
version: '1.0',
|
||||||
version_name: 'Ultra1.0',
|
version_name: 'FlowPilot1.0',
|
||||||
};
|
};
|
||||||
const cache = new Map();
|
const cache = new Map();
|
||||||
const windowObject = {};
|
const windowObject = {};
|
||||||
@@ -77,11 +77,11 @@ function createUpdateService(options = {}) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
test('getReleaseSnapshot keeps Ultra releases ahead of historical Pro and legacy v releases', async () => {
|
test('getReleaseSnapshot keeps FlowPilot releases ahead of historical Ultra, Pro, and legacy v releases', async () => {
|
||||||
const { api } = createUpdateService({
|
const { api } = createUpdateService({
|
||||||
manifest: {
|
manifest: {
|
||||||
version: '1.0',
|
version: '9.99',
|
||||||
version_name: 'Ultra1.0',
|
version_name: 'Ultra9.99',
|
||||||
},
|
},
|
||||||
fetchImpl: async () => ({
|
fetchImpl: async () => ({
|
||||||
ok: true,
|
ok: true,
|
||||||
@@ -106,10 +106,19 @@ test('getReleaseSnapshot keeps Ultra releases ahead of historical Pro and legacy
|
|||||||
prerelease: false,
|
prerelease: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
tag_name: 'Ultra1.1',
|
tag_name: 'Ultra9.99',
|
||||||
name: 'Ultra1.1',
|
name: 'Ultra9.99',
|
||||||
html_url: 'https://example.com/Ultra1.1',
|
html_url: 'https://example.com/Ultra9.99',
|
||||||
published_at: '2026-04-19T00:00:00.000Z',
|
published_at: '2026-04-19T00:00:00.000Z',
|
||||||
|
body: '- historical ultra release',
|
||||||
|
draft: false,
|
||||||
|
prerelease: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
tag_name: 'FlowPilot1.0',
|
||||||
|
name: 'FlowPilot1.0',
|
||||||
|
html_url: 'https://example.com/FlowPilot1.0',
|
||||||
|
published_at: '2026-04-20T00:00:00.000Z',
|
||||||
body: '- current release',
|
body: '- current release',
|
||||||
draft: false,
|
draft: false,
|
||||||
prerelease: false,
|
prerelease: false,
|
||||||
@@ -122,11 +131,11 @@ test('getReleaseSnapshot keeps Ultra releases ahead of historical Pro and legacy
|
|||||||
const snapshot = await api.getReleaseSnapshot({ force: true });
|
const snapshot = await api.getReleaseSnapshot({ force: true });
|
||||||
|
|
||||||
assert.equal(snapshot.status, 'update-available');
|
assert.equal(snapshot.status, 'update-available');
|
||||||
assert.equal(snapshot.localVersion, 'Ultra1.0');
|
assert.equal(snapshot.localVersion, 'Ultra9.99');
|
||||||
assert.equal(snapshot.latestVersion, 'Ultra1.1');
|
assert.equal(snapshot.latestVersion, 'FlowPilot1.0');
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
snapshot.newerReleases.map((release) => release.displayVersion),
|
snapshot.newerReleases.map((release) => release.displayVersion),
|
||||||
['Ultra1.1']
|
['FlowPilot1.0']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -134,7 +143,7 @@ test('getReleaseSnapshot reorders cached releases before choosing latest version
|
|||||||
const { api, getFetchCalls } = createUpdateService({
|
const { api, getFetchCalls } = createUpdateService({
|
||||||
manifest: {
|
manifest: {
|
||||||
version: '1.0',
|
version: '1.0',
|
||||||
version_name: 'Ultra1.0',
|
version_name: 'FlowPilot1.0',
|
||||||
},
|
},
|
||||||
cachedSnapshot: {
|
cachedSnapshot: {
|
||||||
fetchedAt: Date.now(),
|
fetchedAt: Date.now(),
|
||||||
@@ -158,14 +167,23 @@ test('getReleaseSnapshot reorders cached releases before choosing latest version
|
|||||||
notes: [],
|
notes: [],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
version: '1.1',
|
version: '9.99',
|
||||||
displayVersion: 'Ultra1.1',
|
displayVersion: 'Ultra9.99',
|
||||||
family: 'ultra',
|
family: 'ultra',
|
||||||
title: '',
|
title: '',
|
||||||
url: 'https://example.com/Ultra1.1',
|
url: 'https://example.com/Ultra9.99',
|
||||||
publishedAt: '2026-04-19T00:00:00.000Z',
|
publishedAt: '2026-04-19T00:00:00.000Z',
|
||||||
notes: [],
|
notes: [],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
version: '1.1',
|
||||||
|
displayVersion: 'FlowPilot1.1',
|
||||||
|
family: 'flowpilot',
|
||||||
|
title: '',
|
||||||
|
url: 'https://example.com/FlowPilot1.1',
|
||||||
|
publishedAt: '2026-04-20T00:00:00.000Z',
|
||||||
|
notes: [],
|
||||||
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
fetchImpl: async () => {
|
fetchImpl: async () => {
|
||||||
@@ -177,19 +195,19 @@ test('getReleaseSnapshot reorders cached releases before choosing latest version
|
|||||||
|
|
||||||
assert.equal(getFetchCalls(), 0);
|
assert.equal(getFetchCalls(), 0);
|
||||||
assert.equal(snapshot.status, 'update-available');
|
assert.equal(snapshot.status, 'update-available');
|
||||||
assert.equal(snapshot.latestVersion, 'Ultra1.1');
|
assert.equal(snapshot.latestVersion, 'FlowPilot1.1');
|
||||||
assert.deepEqual(
|
assert.deepEqual(
|
||||||
snapshot.newerReleases.map((release) => release.displayVersion),
|
snapshot.newerReleases.map((release) => release.displayVersion),
|
||||||
['Ultra1.1']
|
['FlowPilot1.1']
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getReleaseSnapshot suppresses an ignored latest update until a newer release appears', async () => {
|
test('getReleaseSnapshot suppresses an ignored latest update until a newer release appears', async () => {
|
||||||
let releases = [
|
let releases = [
|
||||||
{
|
{
|
||||||
tag_name: 'Ultra1.1',
|
tag_name: 'FlowPilot1.1',
|
||||||
name: 'Ultra1.1',
|
name: 'FlowPilot1.1',
|
||||||
html_url: 'https://example.com/Ultra1.1',
|
html_url: 'https://example.com/FlowPilot1.1',
|
||||||
published_at: '2026-04-19T00:00:00.000Z',
|
published_at: '2026-04-19T00:00:00.000Z',
|
||||||
body: '- current release',
|
body: '- current release',
|
||||||
draft: false,
|
draft: false,
|
||||||
@@ -199,7 +217,7 @@ test('getReleaseSnapshot suppresses an ignored latest update until a newer relea
|
|||||||
const { api } = createUpdateService({
|
const { api } = createUpdateService({
|
||||||
manifest: {
|
manifest: {
|
||||||
version: '1.0',
|
version: '1.0',
|
||||||
version_name: 'Ultra1.0',
|
version_name: 'FlowPilot1.0',
|
||||||
},
|
},
|
||||||
fetchImpl: async () => ({
|
fetchImpl: async () => ({
|
||||||
ok: true,
|
ok: true,
|
||||||
@@ -211,17 +229,17 @@ test('getReleaseSnapshot suppresses an ignored latest update until a newer relea
|
|||||||
|
|
||||||
const firstSnapshot = await api.getReleaseSnapshot({ force: true });
|
const firstSnapshot = await api.getReleaseSnapshot({ force: true });
|
||||||
assert.equal(firstSnapshot.status, 'update-available');
|
assert.equal(firstSnapshot.status, 'update-available');
|
||||||
assert.equal(api.ignoreReleaseSnapshot(firstSnapshot), 'Ultra1.1');
|
assert.equal(api.ignoreReleaseSnapshot(firstSnapshot), 'FlowPilot1.1');
|
||||||
|
|
||||||
const ignoredSnapshot = await api.getReleaseSnapshot({ force: true });
|
const ignoredSnapshot = await api.getReleaseSnapshot({ force: true });
|
||||||
assert.equal(ignoredSnapshot.status, 'ignored');
|
assert.equal(ignoredSnapshot.status, 'ignored');
|
||||||
assert.equal(ignoredSnapshot.ignoredVersion, 'Ultra1.1');
|
assert.equal(ignoredSnapshot.ignoredVersion, 'FlowPilot1.1');
|
||||||
|
|
||||||
releases = [
|
releases = [
|
||||||
{
|
{
|
||||||
tag_name: 'Ultra1.2',
|
tag_name: 'FlowPilot1.2',
|
||||||
name: 'Ultra1.2',
|
name: 'FlowPilot1.2',
|
||||||
html_url: 'https://example.com/Ultra1.2',
|
html_url: 'https://example.com/FlowPilot1.2',
|
||||||
published_at: '2026-04-20T00:00:00.000Z',
|
published_at: '2026-04-20T00:00:00.000Z',
|
||||||
body: '- next release',
|
body: '- next release',
|
||||||
draft: false,
|
draft: false,
|
||||||
@@ -232,5 +250,5 @@ test('getReleaseSnapshot suppresses an ignored latest update until a newer relea
|
|||||||
|
|
||||||
const newerSnapshot = await api.getReleaseSnapshot({ force: true });
|
const newerSnapshot = await api.getReleaseSnapshot({ force: true });
|
||||||
assert.equal(newerSnapshot.status, 'update-available');
|
assert.equal(newerSnapshot.status, 'update-available');
|
||||||
assert.equal(newerSnapshot.latestVersion, 'Ultra1.2');
|
assert.equal(newerSnapshot.latestVersion, 'FlowPilot1.2');
|
||||||
});
|
});
|
||||||
|
|||||||