diff --git a/apps/decodex-app/Sources/DecodexApp/AccountPanelView.swift b/apps/decodex-app/Sources/DecodexApp/AccountPanelView.swift index 825c746f..6bcda211 100644 --- a/apps/decodex-app/Sources/DecodexApp/AccountPanelView.swift +++ b/apps/decodex-app/Sources/DecodexApp/AccountPanelView.swift @@ -1117,6 +1117,7 @@ private enum AccountPrivacy { private enum AccountDisplay { static let randomNames = [ + "Alex", "Avery", "Bailey", "Blake", diff --git a/apps/decodex/src/accounts.rs b/apps/decodex/src/accounts.rs index 50524b43..a516f940 100644 --- a/apps/decodex/src/accounts.rs +++ b/apps/decodex/src/accounts.rs @@ -21,11 +21,11 @@ use crate::{ }; const ACCOUNT_RANDOM_NAMES: &[&str] = &[ - "Avery", "Bailey", "Blake", "Casey", "Charlie", "Clara", "Dana", "Drew", "Eden", "Elliot", - "Emery", "Evan", "Finley", "Harper", "Hayden", "Iris", "Jamie", "Jordan", "Kai", "Kendall", - "Lane", "Liam", "Logan", "Mason", "Maya", "Mia", "Morgan", "Noah", "Nora", "Owen", "Paige", - "Parker", "Quinn", "Reese", "Remy", "Riley", "Rowan", "Sage", "Sasha", "Sidney", "Taylor", - "Theo", "Val", + "Alex", "Avery", "Bailey", "Blake", "Casey", "Charlie", "Clara", "Dana", "Drew", "Eden", + "Elliot", "Emery", "Evan", "Finley", "Harper", "Hayden", "Iris", "Jamie", "Jordan", "Kai", + "Kendall", "Lane", "Liam", "Logan", "Mason", "Maya", "Mia", "Morgan", "Noah", "Nora", "Owen", + "Paige", "Parker", "Quinn", "Reese", "Remy", "Riley", "Rowan", "Sage", "Sasha", "Sidney", + "Taylor", "Theo", "Val", ]; pub(crate) struct AccountLoginRequest { diff --git a/apps/decodex/src/orchestrator/operator_dashboard.html b/apps/decodex/src/orchestrator/operator_dashboard.html index d75cc623..f6d10035 100644 --- a/apps/decodex/src/orchestrator/operator_dashboard.html +++ b/apps/decodex/src/orchestrator/operator_dashboard.html @@ -3410,7 +3410,6 @@

Run History

const FOLD_PANEL_ANIMATION_MS = 220; const THEME_STORAGE_KEY = "decodex.operator.theme"; const ACCOUNT_PRIVACY_STORAGE_KEY = "decodex.operator.accountPrivacy"; - const ACCOUNT_NAME_OFFSET_STORAGE_KEY = "decodex.operator.accountNameOffsets"; const ACCOUNT_POOL_SORT_STORAGE_KEY = "decodex.operator.accountSort"; const PROJECT_FILTER_STORAGE_KEY = "decodex.operator.projectFilter"; const PROJECT_LOCATION_PRIVACY_STORAGE_KEY = "decodex.operator.projectLocationPrivacy"; @@ -3441,6 +3440,7 @@

Run History

const ACCOUNT_IDENTITY_EDGE_CHARS = 6; const ACCOUNT_IDENTITY_MIN_EDGE_CHARS = 3; const ACCOUNT_RANDOM_NAMES = [ + "Alex", "Avery", "Bailey", "Blake", @@ -3556,11 +3556,10 @@

Run History

const reducedMotionQuery = window.matchMedia("(prefers-reduced-motion: reduce)"); let themeSelection = loadThemeSelection(); let accountEmailsHidden = loadAccountPrivacy(); - let accountNameOffsets = loadAccountNameOffsets(); + let pendingAccountNameOffsets = {}; let accountApiSnapshot = null; let accountApiRefreshInFlight = false; let accountApiRefreshedAt = 0; - const pendingAccountNameOffsetSyncs = new Set(); let accountPoolSort = loadAccountPoolSort(); let accountSelectionConfirmation = null; let projectFilterMode = loadProjectFilterMode(); @@ -4432,36 +4431,6 @@

Run History

} } - function loadAccountNameOffsets() { - try { - const stored = window.localStorage.getItem(ACCOUNT_NAME_OFFSET_STORAGE_KEY); - const parsed = stored ? JSON.parse(stored) : {}; - if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) { - return {}; - } - - return Object.fromEntries( - Object.entries(parsed) - .map(([key, value]) => [key, Number(value)]) - .filter(([key, value]) => key && Number.isInteger(value)) - .map(([key, value]) => [key, normalizeAccountNameOffset(value)]), - ); - } catch (_error) { - return {}; - } - } - - function persistAccountNameOffsets() { - try { - window.localStorage.setItem( - ACCOUNT_NAME_OFFSET_STORAGE_KEY, - JSON.stringify(accountNameOffsets), - ); - } catch (_error) { - /* Ignore storage failures and continue with the in-memory choice. */ - } - } - function normalizeAccountNameOffset(value) { const number = Number(value); if (!Number.isInteger(number)) { @@ -6049,13 +6018,13 @@

Run History

return codexAccountIdentityHash(identity).toString(16).padStart(8, "0"); } - function codexAccountStoredRandomNameOffset(account) { + function codexAccountPendingRandomNameOffset(account) { const key = codexAccountRandomNameKey(account); - if (!Object.prototype.hasOwnProperty.call(accountNameOffsets, key)) { + if (!Object.prototype.hasOwnProperty.call(pendingAccountNameOffsets, key)) { return null; } - return normalizeAccountNameOffset(accountNameOffsets[key]); + return normalizeAccountNameOffset(pendingAccountNameOffsets[key]); } function codexAccountServerRandomNameOffset(account) { @@ -6066,16 +6035,16 @@

Run History

function codexAccountRandomNameOffset(account) { return ( - codexAccountStoredRandomNameOffset(account) ?? + codexAccountPendingRandomNameOffset(account) ?? codexAccountServerRandomNameOffset(account) ?? 0 ); } function codexAccountRandomName(account) { - const storedOffset = codexAccountStoredRandomNameOffset(account); + const pendingOffset = codexAccountPendingRandomNameOffset(account); const serverName = String(account?.random_name || "").trim(); - if (storedOffset == null && serverName) { + if (pendingOffset == null && serverName) { return serverName; } @@ -6091,35 +6060,6 @@

Run History

return ACCOUNT_RANDOM_NAMES[index]; } - function syncStoredAccountNameOffsets(accounts) { - for (const account of accounts) { - const key = codexAccountRandomNameKey(account); - const storedOffset = codexAccountStoredRandomNameOffset(account); - const serverOffset = codexAccountServerRandomNameOffset(account) ?? 0; - if ( - storedOffset == null || - storedOffset === serverOffset || - pendingAccountNameOffsetSyncs.has(key) - ) { - continue; - } - - pendingAccountNameOffsetSyncs.add(key); - postAccountNameOffset(account, storedOffset) - .then((updated) => { - if (updated) { - delete accountNameOffsets[key]; - persistAccountNameOffsets(); - if (lastDashboardRender) { - renderDashboardState(lastDashboardRender); - } - } - }) - .catch(() => {}) - .finally(() => pendingAccountNameOffsetSyncs.delete(key)); - } - } - function codexAccountShowsEmail(account) { return Boolean(codexAccountEmail(account) && !accountEmailsHidden); } @@ -6921,7 +6861,6 @@

Run History

function renderAccountPool(snapshot) { const accounts = codexAccountPoolAccounts(snapshot); - syncStoredAccountNameOffsets(accounts); renderAccountModeControl(snapshot); renderStableList(nodes.accountPool, renderCodexAccountPool(accounts, snapshot)); syncAccountSelectionConfirmationDom(); @@ -9896,13 +9835,12 @@

${escapeHtml(worktree.branch_name)}

: null; const current = account ? codexAccountRandomNameOffset(account) - : normalizeAccountNameOffset(accountNameOffsets[key]); + : normalizeAccountNameOffset(pendingAccountNameOffsets[key]); const next = normalizeAccountNameOffset(current + 1); - accountNameOffsets = { - ...accountNameOffsets, + pendingAccountNameOffsets = { + ...pendingAccountNameOffsets, [key]: next, }; - persistAccountNameOffsets(); if (lastDashboardRender) { renderDashboardState(lastDashboardRender); } @@ -9910,8 +9848,7 @@

${escapeHtml(worktree.branch_name)}

postAccountNameOffset(account, next) .then((updated) => { if (updated) { - delete accountNameOffsets[key]; - persistAccountNameOffsets(); + delete pendingAccountNameOffsets[key]; if (lastDashboardRender) { renderDashboardState(lastDashboardRender); } diff --git a/apps/decodex/src/orchestrator/tests/operator/status/dashboard.rs b/apps/decodex/src/orchestrator/tests/operator/status/dashboard.rs index a2774675..cbabd9f1 100644 --- a/apps/decodex/src/orchestrator/tests/operator/status/dashboard.rs +++ b/apps/decodex/src/orchestrator/tests/operator/status/dashboard.rs @@ -513,7 +513,7 @@ fn operator_dashboard_account_privacy_controls_use_compact_identities() { let response = dashboard_response(); assert!(response.contains("const ACCOUNT_PRIVACY_STORAGE_KEY = \"decodex.operator.accountPrivacy\";")); - assert!(response.contains("const ACCOUNT_NAME_OFFSET_STORAGE_KEY = \"decodex.operator.accountNameOffsets\";")); + assert!(!response.contains("const ACCOUNT_NAME_OFFSET_STORAGE_KEY = \"decodex.operator.accountNameOffsets\";")); assert!(response.contains("const ACCOUNT_IDENTITY_EDGE_CHARS = 6;")); assert!(response.contains("const ACCOUNT_IDENTITY_MIN_EDGE_CHARS = 3;")); assert!(!response.contains("const ACCOUNT_EMAIL_LOCAL_HEAD_CHARS = 5;")); @@ -529,13 +529,17 @@ fn operator_dashboard_account_privacy_controls_use_compact_identities() { assert!(response.contains("function codexAccountEmail(account)")); assert!(response.contains("function compactAccountEmail(email)")); assert!(response.contains("function loadAccountPrivacy()")); - assert!(response.contains("function loadAccountNameOffsets()")); + assert!(!response.contains("function loadAccountNameOffsets()")); assert!(response.contains("function persistAccountPrivacy(hidden)")); - assert!(response.contains("function persistAccountNameOffsets()")); + assert!(!response.contains("function persistAccountNameOffsets()")); assert!(response.contains("function configuredDashboardAccounts(snapshot)")); assert!(response.contains("function renderAccountPrivacyToggle()")); assert!(response.contains("function codexAccountRandomNameKey(account)")); assert!(response.contains("function codexAccountRandomNameOffset(account)")); + assert!(response.contains("function codexAccountPendingRandomNameOffset(account)")); + assert!(response.contains("let pendingAccountNameOffsets = {};")); + assert!(!response.contains("function codexAccountStoredRandomNameOffset(account)")); + assert!(!response.contains("function syncStoredAccountNameOffsets(accounts)")); assert!(response.contains("function codexAccountDisplaySource(account, snapshot)")); assert!(response.contains("function renderCodexAccountRandomNameButton(account)")); assert!(response.contains("function codexAccountShowsEmail(account)")); @@ -560,7 +564,7 @@ fn operator_dashboard_account_privacy_controls_use_compact_identities() { assert!(response.contains("account-name-reroll")); assert!(response.contains("data-account-name-reroll")); assert!(response.contains("aria-label=\"Change account name\"")); - assert!(!response.contains("\"Alex\"")); + assert!(response.contains("\"Alex\"")); assert!(response.contains("return `${local.slice(0, 3)}...${local.slice(-3)}${domain}`;")); assert!(response.contains("return ACCOUNT_RANDOM_NAMES[index];")); assert!(response.contains("return status === \"selected\" ? 1 : 0;")); @@ -576,7 +580,6 @@ fn operator_dashboard_account_privacy_controls_use_compact_identities() { assert!(response.contains("renderAccountPrivacyToggle();")); assert!(response.contains("renderAccountModeControl(snapshot);")); assert!(response.contains("persistAccountPrivacy(accountEmailsHidden);")); - assert!(response.contains("persistAccountNameOffsets();")); assert!(response.contains("let lastDashboardRender = null;")); assert!(response.contains("lastDashboardRender = {")); assert!(response.contains("function renderDashboardState({")); diff --git a/apps/decodex/src/orchestrator/tests/operator/status/http.rs b/apps/decodex/src/orchestrator/tests/operator/status/http.rs index cd539626..ea649a09 100644 --- a/apps/decodex/src/orchestrator/tests/operator/status/http.rs +++ b/apps/decodex/src/orchestrator/tests/operator/status/http.rs @@ -1413,7 +1413,7 @@ fn operator_state_endpoint_persists_account_random_name_offset() { assert_eq!(data["accounts"][0]["random_name_offset"], 1); assert_eq!(data["accounts"][0]["random_name_key"], "df65f796"); - assert_eq!(data["accounts"][0]["random_name"], "Taylor"); + assert_eq!(data["accounts"][0]["random_name"], "Logan"); assert!( fs::read_to_string(accounts_dir.join("config.toml")) .expect("global config should read")