diff --git a/README.md b/README.md index 89ac67a..3302f1f 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Multi-Page Automation +# FlowPilot 一个用于批量跑通 ChatGPT OAuth 注册/登录流程的 Chrome 扩展。 @@ -20,11 +20,11 @@ ## Star History - + - - - Star History Chart + + + Star History Chart diff --git a/background.js b/background.js index 3598798..09e1c0b 100644 --- a/background.js +++ b/background.js @@ -7244,7 +7244,7 @@ async function fetchIcloudHideMyEmail(options = {}) { : {}), hme: generatedAlias, label: getIcloudAliasLabel(), - note: 'Generated through Multi-Page Automation', + note: 'Generated through FlowPilot', }; let alias = ''; diff --git a/docs/images/log.png b/docs/images/log.png new file mode 100644 index 0000000..60ae17d Binary files /dev/null and b/docs/images/log.png differ diff --git a/docs/使用教程.md b/docs/使用教程.md index b4388c0..b3c335e 100644 --- a/docs/使用教程.md +++ b/docs/使用教程.md @@ -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) 的 `🔁 非港轮询` 配置方法。 diff --git a/docs/使用教程/使用教程.md b/docs/使用教程/使用教程.md index fea6679..e20465c 100644 --- a/docs/使用教程/使用教程.md +++ b/docs/使用教程/使用教程.md @@ -1,6 +1,6 @@ # 使用教程总索引 -本目录用于维护 `Codex 注册扩展` 的分部分使用教程。 +本目录用于维护 `FlowPilot` 的分部分使用教程。 从现在开始,教程正文不再直接堆到这一个文件里,而是拆到 `分部分/` 目录下分别维护。 --- diff --git a/docs/公告书写标准.md b/docs/公告书写标准.md index 4452de3..266ed70 100644 --- a/docs/公告书写标准.md +++ b/docs/公告书写标准.md @@ -1,6 +1,6 @@ # 公告书写标准 -本文件用于约束 AI 生成“账号贡献站 / Codex 注册扩展”相关公告时的 Markdown 格式。 +本文件用于约束 AI 生成“账号贡献站 / FlowPilot”相关公告时的 Markdown 格式。 使用方式: @@ -184,7 +184,7 @@ AI 生成公告时禁止: 把下面这段直接发给 AI: ```md -请帮我写一份“账号贡献站 / Codex 注册扩展”公告,严格遵守以下要求: +请帮我写一份“账号贡献站 / FlowPilot”公告,严格遵守以下要求: 1. 输出必须是 Markdown 2. 不要使用 HTML diff --git a/icons/icon128.png b/icons/icon128.png index cfe63a0..03e1e17 100644 Binary files a/icons/icon128.png and b/icons/icon128.png differ diff --git a/icons/icon16.png b/icons/icon16.png index fea6c40..746f955 100644 Binary files a/icons/icon16.png and b/icons/icon16.png differ diff --git a/icons/icon48.png b/icons/icon48.png index 4986d82..2afaacb 100644 Binary files a/icons/icon48.png and b/icons/icon48.png differ diff --git a/manifest.json b/manifest.json index bcdfe77..b43891b 100644 --- a/manifest.json +++ b/manifest.json @@ -1,8 +1,8 @@ { "manifest_version": 3, - "name": "codex-oauth-automation-extension", - "version": "9.99", - "version_name": "Ultra9.99", + "name": "FlowPilot", + "version": "1.0", + "version_name": "FlowPilot1.0", "description": "用于自动执行多步骤 OAuth 注册流程", "permissions": [ "sidePanel", diff --git a/package.json b/package.json index 01a2464..c5452e6 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "name": "codex-oauth-automation-extension", + "name": "flowpilot", "license": "MIT", "private": true, "scripts": { diff --git a/sidepanel/sidepanel.css b/sidepanel/sidepanel.css index 63136f7..bf79889 100644 --- a/sidepanel/sidepanel.css +++ b/sidepanel/sidepanel.css @@ -1,5 +1,5 @@ /* ============================================================ - MultiPage Automation — Side Panel + FlowPilot — Side Panel Design: Swiss Modernism + Developer Tool Font: Inter (UI) + JetBrains Mono (code) Themes: Light (default) + Dark (toggle) @@ -7,35 +7,36 @@ /* ---- Light Theme (default) ---- */ :root { - --bg-base: #ffffff; - --bg-surface: #f7f8fa; - --bg-elevated: #eef0f4; - --bg-hover: #e4e7ec; - --bg-active: #dce0e8; + --bg-base: #eef6f4; + --bg-surface: #fbfefd; + --bg-field: #f7fbfa; + --bg-elevated: #e7f1ee; + --bg-hover: #dce9e6; + --bg-active: #d0e0dc; - --border: #d8dce3; - --border-subtle: #e8ecf1; + --border: #c8d9d5; + --border-subtle: #dce9e6; - --text-primary: #1a1d24; - --text-secondary: #5c6370; - --text-muted: #9ca3af; + --text-primary: #162025; + --text-secondary: #516368; + --text-muted: #7f9194; - --blue: #2563eb; - --blue-soft: rgba(37, 99, 235, 0.08); - --blue-glow: rgba(37, 99, 235, 0.12); - --green: #16a34a; - --green-soft: rgba(22, 163, 74, 0.08); - --orange: #ea580c; - --orange-soft: rgba(234, 88, 12, 0.08); - --amber: #d97706; - --amber-soft: rgba(217, 119, 6, 0.08); - --red: #dc2626; - --red-soft: rgba(220, 38, 38, 0.08); - --cyan: #0891b2; - --purple: #7c3aed; + --blue: #1473e6; + --blue-soft: rgba(20, 115, 230, 0.09); + --blue-glow: rgba(20, 115, 230, 0.16); + --green: #5eaf00; + --green-soft: rgba(94, 175, 0, 0.10); + --orange: #d8661f; + --orange-soft: rgba(216, 102, 31, 0.10); + --amber: #b98200; + --amber-soft: rgba(185, 130, 0, 0.10); + --red: #d63c3c; + --red-soft: rgba(214, 60, 60, 0.10); + --cyan: #0aa5bd; + --purple: #7160d7; - --shadow-sm: 0 1px 2px rgba(0,0,0,0.04); - --shadow-md: 0 2px 6px rgba(0,0,0,0.06); + --shadow-sm: 0 1px 3px rgba(22, 32, 37, 0.06); + --shadow-md: 0 6px 18px rgba(22, 32, 37, 0.10); --radius-sm: 6px; --radius-md: 8px; @@ -44,35 +45,36 @@ /* ---- Dark Theme ---- */ [data-theme="dark"] { - --bg-base: #0f1117; - --bg-surface: #181a21; - --bg-elevated: #21242d; - --bg-hover: #2a2e38; - --bg-active: #323844; + --bg-base: #0c1214; + --bg-surface: #141b1e; + --bg-field: #101719; + --bg-elevated: #1d272a; + --bg-hover: #263236; + --bg-active: #2f3d42; - --border: #2a2e38; - --border-subtle: #21242d; + --border: #2a383c; + --border-subtle: #1f2b2f; - --text-primary: #e4e6eb; - --text-secondary: #8b919e; - --text-muted: #565c6a; + --text-primary: #edf5f3; + --text-secondary: #9cada9; + --text-muted: #748583; - --blue: #3b82f6; - --blue-soft: rgba(59, 130, 246, 0.12); - --blue-glow: rgba(59, 130, 246, 0.18); - --green: #22c55e; - --green-soft: rgba(34, 197, 94, 0.12); - --orange: #f97316; - --orange-soft: rgba(249, 115, 22, 0.12); - --amber: #f59e0b; - --amber-soft: rgba(245, 158, 11, 0.12); - --red: #ef4444; - --red-soft: rgba(239, 68, 68, 0.12); - --cyan: #06b6d4; - --purple: #a78bfa; + --blue: #4d9aff; + --blue-soft: rgba(77, 154, 255, 0.14); + --blue-glow: rgba(77, 154, 255, 0.22); + --green: #8bdc2d; + --green-soft: rgba(139, 220, 45, 0.14); + --orange: #ff9148; + --orange-soft: rgba(255, 145, 72, 0.14); + --amber: #ffc247; + --amber-soft: rgba(255, 194, 71, 0.14); + --red: #ff6b6b; + --red-soft: rgba(255, 107, 107, 0.14); + --cyan: #38d5e6; + --purple: #a997ff; - --shadow-sm: 0 1px 2px rgba(0,0,0,0.2); - --shadow-md: 0 2px 8px rgba(0,0,0,0.3); + --shadow-sm: 0 1px 2px rgba(0,0,0,0.22); + --shadow-md: 0 8px 24px rgba(0,0,0,0.34); } * { margin: 0; padding: 0; box-sizing: border-box; } @@ -109,7 +111,7 @@ header { margin-bottom: 14px; padding-top: 4px; 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); border-bottom: 1px solid var(--border-subtle); } @@ -447,7 +449,7 @@ header { width: 42px; padding: 6px 4px; text-align: center; - background: var(--bg-base); + background: var(--bg-field); border: 1px solid var(--border); border-radius: var(--radius-sm); color: var(--text-primary); @@ -1176,7 +1178,7 @@ header { padding: 2px 6px; border-radius: 999px; border: 1px solid var(--border); - background: var(--bg-base); + background: var(--bg-field); color: var(--text-primary); font-size: 11px; line-height: 1.2; @@ -1238,7 +1240,7 @@ header { .data-input { flex: 1; padding: 7px 10px; - background: var(--bg-base); + background: var(--bg-field); border: 1px solid var(--border); border-radius: var(--radius-sm); color: var(--text-primary); @@ -1256,7 +1258,7 @@ header { min-height: 88px; resize: vertical; padding: 8px 10px; - background: var(--bg-base); + background: var(--bg-field); border: 1px solid var(--border); border-radius: var(--radius-sm); color: var(--text-primary); @@ -1890,7 +1892,7 @@ header { .data-select { flex: 1; padding: 7px 10px; - background: var(--bg-base); + background: var(--bg-field); border: 1px solid var(--border); border-radius: var(--radius-sm); 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-theme="dark"] .data-select { color-scheme: dark; } +#select-flow { + text-align: center; + text-align-last: center; +} + .data-input[readonly] { color: var(--text-secondary); background: var(--bg-surface); @@ -1955,7 +1962,7 @@ header { padding: 4px; border: 1px solid var(--border); border-radius: var(--radius-sm); - background: var(--bg-base); + background: var(--bg-surface); box-shadow: var(--shadow-md); } @@ -2158,7 +2165,7 @@ header { width: 16px; height: 16px; border-radius: 50%; - background: var(--bg-base); + background: var(--bg-field); box-shadow: var(--shadow-sm); transition: transform var(--transition), background var(--transition); } @@ -2268,7 +2275,7 @@ header { padding: 6px; max-height: 180px; overflow-y: auto; - background: var(--bg-base); + background: var(--bg-field); border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow-md); @@ -2755,7 +2762,7 @@ header { .step-manual-btn:disabled { color: var(--text-muted); border-color: var(--border-subtle); - background: var(--bg-base); + background: var(--bg-field); cursor: not-allowed; opacity: 0.5; } @@ -3269,7 +3276,7 @@ header { .modal-card { width: min(100%, 320px); - background: var(--bg-base); + background: var(--bg-surface); border: 1px solid var(--border); border-radius: 12px; box-shadow: var(--shadow-md), 0 18px 36px rgba(0, 0, 0, 0.18); diff --git a/sidepanel/sidepanel.html b/sidepanel/sidepanel.html index ad7f900..9e6bb54 100644 --- a/sidepanel/sidepanel.html +++ b/sidepanel/sidepanel.html @@ -4,7 +4,7 @@ - codex-oauth-automation-extension + FlowPilot
+ aria-label="打开 GitHub Releases 页面" title="打开 GitHub Releases 页面">FlowPilot0.0
@@ -111,10 +111,10 @@
- Flow + 注册
diff --git a/sidepanel/sidepanel.js b/sidepanel/sidepanel.js index 2f8d7db..93e9c0b 100644 --- a/sidepanel/sidepanel.js +++ b/sidepanel/sidepanel.js @@ -9729,7 +9729,7 @@ function getRepositoryHomeUrl() { return releasesPageUrl.replace(/\/releases\/?$/, ''); } - return 'https://github.com/QLHazyCoder/codex-oauth-automation-extension'; + return 'https://github.com/QLHazyCoder/FlowPilot'; } function getReleaseListUrl() { @@ -9823,7 +9823,7 @@ function renderUpdateReleaseList(releases = []) { const version = document.createElement('span'); version.className = 'update-release-version'; - version.textContent = release.displayVersion || `Ultra${release.version}`; + version.textContent = release.displayVersion || `FlowPilot${release.version}`; titleRow.appendChild(version); if (release.title) { @@ -9925,21 +9925,21 @@ function renderReleaseSnapshot(snapshot) { } case 'ignored': { - extensionUpdateStatus.textContent = localVersionText || 'Ultra0.0'; + extensionUpdateStatus.textContent = localVersionText || 'FlowPilot0.0'; extensionUpdateStatus.classList.add('is-version-label'); resetUpdateCard(); break; } case 'latest': { - extensionUpdateStatus.textContent = localVersionText || 'Ultra0.0'; + extensionUpdateStatus.textContent = localVersionText || 'FlowPilot0.0'; extensionUpdateStatus.classList.add('is-version-label'); resetUpdateCard(); break; } case 'empty': { - extensionUpdateStatus.textContent = localVersionText || 'Ultra0.0'; + extensionUpdateStatus.textContent = localVersionText || 'FlowPilot0.0'; extensionUpdateStatus.classList.add('is-version-label'); resetUpdateCard(); break; @@ -9947,7 +9947,7 @@ function renderReleaseSnapshot(snapshot) { case 'error': default: { - extensionUpdateStatus.textContent = localVersionText || 'Ultra0.0'; + extensionUpdateStatus.textContent = localVersionText || 'FlowPilot0.0'; extensionUpdateStatus.classList.add('is-version-label', 'is-check-failed'); extensionVersionMeta.textContent = snapshot?.errorMessage || 'GitHub Releases 检查失败'; extensionVersionMeta.hidden = false; @@ -9958,7 +9958,7 @@ function renderReleaseSnapshot(snapshot) { } 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) { btnReleaseLog.onclick = () => openExternalUrl(currentReleaseSnapshot?.logUrl || fallbackReleaseUrl); @@ -9970,8 +9970,8 @@ async function initializeReleaseInfo() { const localVersion = sidepanelUpdateService?.getLocalVersionLabel?.(chrome.runtime.getManifest()) || chrome.runtime.getManifest()?.version_name - || (chrome.runtime.getManifest()?.version ? `Ultra${chrome.runtime.getManifest().version}` : ''); - extensionUpdateStatus.textContent = localVersion || 'Ultra0.0'; + || (chrome.runtime.getManifest()?.version ? `FlowPilot${chrome.runtime.getManifest().version}` : ''); + extensionUpdateStatus.textContent = localVersion || 'FlowPilot0.0'; extensionUpdateStatus.classList.remove('is-update-available', 'is-check-failed'); extensionUpdateStatus.classList.add('is-version-label'); extensionVersionMeta.hidden = true; diff --git a/sidepanel/update-service.js b/sidepanel/update-service.js index 06bf5d0..5ac3d1d 100644 --- a/sidepanel/update-service.js +++ b/sidepanel/update-service.js @@ -1,6 +1,6 @@ (() => { 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_API_URL = `https://api.github.com/repos/${GITHUB_OWNER}/${GITHUB_REPO}/releases?per_page=10`; const CACHE_KEY = 'multipage-release-snapshot-v1'; @@ -9,12 +9,16 @@ const FETCH_TIMEOUT_MS = 8000; const MAX_RELEASES = 10; const MAX_NOTES_PER_RELEASE = 5; + const VERSION_FAMILY_FLOWPILOT = 'flowpilot'; const VERSION_FAMILY_ULTRA = 'ultra'; const VERSION_FAMILY_PRO = 'pro'; const VERSION_FAMILY_LEGACY = 'legacy'; function getVersionFamily(version, fallbackFamily = VERSION_FAMILY_LEGACY) { const trimmed = String(version || '').trim(); + if (/^flowpilot/i.test(trimmed)) { + return VERSION_FAMILY_FLOWPILOT; + } if (/^ultra/i.test(trimmed)) { return VERSION_FAMILY_ULTRA; } @@ -28,7 +32,7 @@ } 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) { @@ -63,6 +67,9 @@ } function getVersionFamilyPrefix(family) { + if (family === VERSION_FAMILY_FLOWPILOT) { + return 'FlowPilot'; + } if (family === VERSION_FAMILY_ULTRA) { return 'Ultra'; } @@ -73,6 +80,9 @@ } function getVersionFamilyRank(family) { + if (family === VERSION_FAMILY_FLOWPILOT) { + return 4; + } if (family === VERSION_FAMILY_ULTRA) { return 3; } @@ -206,7 +216,7 @@ } 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 : VERSION_FAMILY_LEGACY; const displayVersion = String(release?.displayVersion || '').trim(); @@ -267,7 +277,7 @@ } function setIgnoredUpdateVersion(version) { - const normalized = formatDisplayVersion(version, VERSION_FAMILY_ULTRA) || String(version || '').trim(); + const normalized = formatDisplayVersion(version, VERSION_FAMILY_FLOWPILOT) || String(version || '').trim(); try { if (normalized) { localStorage.setItem(IGNORED_UPDATE_VERSION_KEY, normalized); @@ -387,17 +397,17 @@ } 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) { return versionName; } 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 = {}) { - const localVersion = getLocalVersionLabel(chrome.runtime.getManifest()) || 'Ultra0.0'; + const localVersion = getLocalVersionLabel(chrome.runtime.getManifest()) || 'FlowPilot0.0'; try { const releases = await loadReleases(options); @@ -442,6 +452,7 @@ getLocalVersionLabel, getReleaseSnapshot, ignoreReleaseSnapshot, + repositoryUrl: `https://github.com/${GITHUB_OWNER}/${GITHUB_REPO}`, releasesPageUrl: RELEASES_PAGE_URL, stripVersionPrefix, }; diff --git a/tests/update-service.test.js b/tests/update-service.test.js index 393b891..b6f47f4 100644 --- a/tests/update-service.test.js +++ b/tests/update-service.test.js @@ -7,7 +7,7 @@ const source = fs.readFileSync('sidepanel/update-service.js', 'utf8'); function createUpdateService(options = {}) { const manifest = options.manifest || { version: '1.0', - version_name: 'Ultra1.0', + version_name: 'FlowPilot1.0', }; const cache = new Map(); 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({ manifest: { - version: '1.0', - version_name: 'Ultra1.0', + version: '9.99', + version_name: 'Ultra9.99', }, fetchImpl: async () => ({ ok: true, @@ -106,10 +106,19 @@ test('getReleaseSnapshot keeps Ultra releases ahead of historical Pro and legacy prerelease: false, }, { - tag_name: 'Ultra1.1', - name: 'Ultra1.1', - html_url: 'https://example.com/Ultra1.1', + tag_name: 'Ultra9.99', + name: 'Ultra9.99', + html_url: 'https://example.com/Ultra9.99', 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', draft: 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 }); assert.equal(snapshot.status, 'update-available'); - assert.equal(snapshot.localVersion, 'Ultra1.0'); - assert.equal(snapshot.latestVersion, 'Ultra1.1'); + assert.equal(snapshot.localVersion, 'Ultra9.99'); + assert.equal(snapshot.latestVersion, 'FlowPilot1.0'); assert.deepEqual( 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({ manifest: { version: '1.0', - version_name: 'Ultra1.0', + version_name: 'FlowPilot1.0', }, cachedSnapshot: { fetchedAt: Date.now(), @@ -158,14 +167,23 @@ test('getReleaseSnapshot reorders cached releases before choosing latest version notes: [], }, { - version: '1.1', - displayVersion: 'Ultra1.1', + version: '9.99', + displayVersion: 'Ultra9.99', family: 'ultra', title: '', - url: 'https://example.com/Ultra1.1', + url: 'https://example.com/Ultra9.99', publishedAt: '2026-04-19T00:00:00.000Z', 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 () => { @@ -177,19 +195,19 @@ test('getReleaseSnapshot reorders cached releases before choosing latest version assert.equal(getFetchCalls(), 0); assert.equal(snapshot.status, 'update-available'); - assert.equal(snapshot.latestVersion, 'Ultra1.1'); + assert.equal(snapshot.latestVersion, 'FlowPilot1.1'); assert.deepEqual( snapshot.newerReleases.map((release) => release.displayVersion), - ['Ultra1.1'] + ['FlowPilot1.1'] ); }); test('getReleaseSnapshot suppresses an ignored latest update until a newer release appears', async () => { let releases = [ { - tag_name: 'Ultra1.1', - name: 'Ultra1.1', - html_url: 'https://example.com/Ultra1.1', + tag_name: 'FlowPilot1.1', + name: 'FlowPilot1.1', + html_url: 'https://example.com/FlowPilot1.1', published_at: '2026-04-19T00:00:00.000Z', body: '- current release', draft: false, @@ -199,7 +217,7 @@ test('getReleaseSnapshot suppresses an ignored latest update until a newer relea const { api } = createUpdateService({ manifest: { version: '1.0', - version_name: 'Ultra1.0', + version_name: 'FlowPilot1.0', }, fetchImpl: async () => ({ ok: true, @@ -211,17 +229,17 @@ test('getReleaseSnapshot suppresses an ignored latest update until a newer relea const firstSnapshot = await api.getReleaseSnapshot({ force: true }); 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 }); assert.equal(ignoredSnapshot.status, 'ignored'); - assert.equal(ignoredSnapshot.ignoredVersion, 'Ultra1.1'); + assert.equal(ignoredSnapshot.ignoredVersion, 'FlowPilot1.1'); releases = [ { - tag_name: 'Ultra1.2', - name: 'Ultra1.2', - html_url: 'https://example.com/Ultra1.2', + tag_name: 'FlowPilot1.2', + name: 'FlowPilot1.2', + html_url: 'https://example.com/FlowPilot1.2', published_at: '2026-04-20T00:00:00.000Z', body: '- next release', draft: false, @@ -232,5 +250,5 @@ test('getReleaseSnapshot suppresses an ignored latest update until a newer relea const newerSnapshot = await api.getReleaseSnapshot({ force: true }); assert.equal(newerSnapshot.status, 'update-available'); - assert.equal(newerSnapshot.latestVersion, 'Ultra1.2'); + assert.equal(newerSnapshot.latestVersion, 'FlowPilot1.2'); });