clauddy 1.21.0 → 1.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/main.js +19 -3
  2. package/package.json +1 -1
  3. package/renderer/pet.js +23 -9
package/main.js CHANGED
@@ -678,16 +678,32 @@ function startUsagePoll() {
678
678
  }
679
679
 
680
680
  // push the logged-in account's identity (email + plan) to the renderer
681
- async function sendProfile() {
681
+ let profileTimer = null
682
+ async function sendProfile(tries = 0) {
683
+ clearTimeout(profileTimer)
682
684
  if (!auth.isConnected()) return
685
+ // whose profile this is, decided *before* the await: a switch during the
686
+ // fetch would otherwise label the new account with the old one's email
687
+ const id = accounts.activeId()
683
688
  try {
684
689
  const p = await auth.fetchProfile()
690
+ if (id !== accounts.activeId()) return // switched under us — this is stale
685
691
  if (p?.email) {
686
- accounts.label(accounts.activeId(), p.email) // a better name than "acct-xyz"
692
+ accounts.label(id, p.email) // a better name than "acct-xyz"
687
693
  sendAccounts()
688
694
  }
689
695
  if (win && !win.isDestroyed()) win.webContents.send('profile', p)
690
- } catch {} // non-fatal: the chip just stays hidden
696
+ } catch {
697
+ // a rate limit or a blip would otherwise hide the chip — and with it the
698
+ // account switcher — until the app is restarted, so keep trying for a while
699
+ if (tries >= 4) return
700
+ profileTimer = setTimeout(
701
+ () => {
702
+ if (id === accounts.activeId()) sendProfile(tries + 1)
703
+ },
704
+ 30 * 1000 * 2 ** tries,
705
+ )
706
+ }
691
707
  }
692
708
 
693
709
  // begin() has to run *after* any account switch: switching resets the pending
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "clauddy",
3
3
  "desktopName": "clauddy.desktop",
4
- "version": "1.21.0",
4
+ "version": "1.21.1",
5
5
  "description": "A cute desktop pet that tracks your Claude Code usage",
6
6
  "main": "main.js",
7
7
  "bin": {
package/renderer/pet.js CHANGED
@@ -700,26 +700,38 @@ window.api.onAuthState((s) => {
700
700
  })
701
701
 
702
702
  // logged-in account chip (email + plan) shown top-left when connected
703
+ let lastProfile = null
703
704
  function showProfile(p) {
705
+ lastProfile = p
706
+ paintChip()
707
+ }
708
+
709
+ // The chip is also the account switcher, so it must not vanish just because the
710
+ // profile fetch failed — that would strand the user on one account until a
711
+ // restart. The label main stored for the active account is the same email, so
712
+ // it stands in until the profile lands.
713
+ function paintChip() {
714
+ const p = lastProfile
715
+ const a = lastAccounts
716
+ const active = (a?.accounts || []).find((x) => x.id === a?.active)
717
+ const email = p?.email || (active?.connected ? active.label : null)
704
718
  // the settings line says who is connected, not just that someone is
705
- el('acc-ok').textContent = p?.email
706
- ? `● ${p.email}${p.plan ? ` · ${p.plan}` : ''}`
707
- : '● Connected'
719
+ el('acc-ok').textContent = email ? `● ${email}${p?.plan ? ` · ${p.plan}` : ''}` : '● Connected'
708
720
  const chip = el('account-chip')
709
721
  const mini = el('mini-acct')
710
- if (!p?.email) {
722
+ if (!email) {
711
723
  chip.hidden = true
712
724
  mini.hidden = true
713
725
  return
714
726
  }
715
727
  // expanded: full email chip in the top bar
716
- el('ac-email').textContent = p.email
717
- chip.title = p.name ? `${p.name} · ${p.email}` : p.email
718
- setPlan(el('ac-plan'), p.plan)
728
+ el('ac-email').textContent = email
729
+ chip.title = p?.name ? `${p.name} · ${email}` : email
730
+ setPlan(el('ac-plan'), p?.plan)
719
731
  chip.hidden = false
720
732
  // collapsed: short name + plan in the mini block (email won't fit at 116px)
721
- el('mini-acct-name').textContent = p.name || p.email.split('@')[0]
722
- setPlan(el('mini-acct-plan'), p.plan)
733
+ el('mini-acct-name').textContent = p?.name || email.split('@')[0]
734
+ setPlan(el('mini-acct-plan'), p?.plan)
723
735
  mini.hidden = false
724
736
  }
725
737
  function setPlan(node, plan) {
@@ -765,6 +777,8 @@ function accountRow(acc, a) {
765
777
  function renderAccounts(a) {
766
778
  lastAccounts = a
767
779
  document.body.classList.toggle('one-account', (a?.accounts || []).length < 2)
780
+ paintChip() // the label may be all the chip has to go on
781
+
768
782
  if (el('acc-menu').hidden) return
769
783
  // the switch is done: the chip now names the account the menu was pointing at
770
784
  if (switching && !a?.busy) closeAccountMenu()