Skip to content

Replace hardcoded 7-day inactive token refresh window with dynamic half-lifetime#1

Draft
Copilot wants to merge 3 commits intomainfrom
copilot/switch-claude-code-account
Draft

Replace hardcoded 7-day inactive token refresh window with dynamic half-lifetime#1
Copilot wants to merge 3 commits intomainfrom
copilot/switch-claude-code-account

Conversation

Copy link

Copilot AI commented Mar 11, 2026

The inactive-account proactive refresh window was a hardcoded 7 days, ignoring Claude's actual OAuth token lifetime. For a 30-day token this triggers unnecessarily early; for a shorter-lived token it may not trigger at all.

Changes

  • store.Credentials — added IssuedAt int64 (unix ms, omitempty) to record when a token was issued or last refreshed

  • tokenNeedsRefreshInactive — replaced the 7-day constant with a dynamic half-lifetime threshold:

    refresh when: (expiresAt - now) < (expiresAt - issuedAt) / 2
    

    Falls back to 24 h for tokens missing IssuedAt (accounts saved before this change) or with invalid timestamps (issuedAt ≥ expiresAt)

  • IssuedAt population — set to time.Now() at every credential write point:

    • cmd/login.go — on auto-switch login
    • store.SyncActiveToken — when Claude Code's background rotation is detected
    • refreshClaudeCredentials — after a successful OAuth refresh

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

- Add tokenNeedsRefreshInactive (7-day window) for accounts not currently
  active in Claude Code; inactive accounts have no racing concern with
  Claude Code's background token rotation
- Update refreshClaudeCredentials to take activeEmail and apply the narrow
  1-hour window only to the active account (or all accounts when active
  account is unknown), and the wider 7-day window to inactive accounts
- Pass Scopes to WriteCredentials in switchAndLaunch to preserve scope info
- Warn clearly with actionable guidance when switching to an expired account
- Update callers in claude.go and list.go to pass claude.ActiveEmail()

Co-authored-by: zhangweiii <31117497+zhangweiii@users.noreply.github.com>
Copilot AI changed the title [WIP] Explain account switching mechanism for Claude Code Fix credential expiration for inactive Claude Code accounts Mar 11, 2026
…etime

Record IssuedAt when a Claude credential is first saved, auto-synced, or
refreshed. Compute the inactive-account refresh threshold as half the
token's total lifetime (expiresAt - issuedAt) / 2, so the window
self-calibrates to Claude's actual OAuth token duration. Tokens without
a recorded IssuedAt fall back to a 24-hour look-ahead.

- internal/store/store.go: add IssuedAt int64 field to Credentials
- internal/store/sync.go: set IssuedAt when auto-syncing active token
- cmd/login.go: set IssuedAt when saving credentials via auto-switch login
- cmd/common.go: dynamic tokenNeedsRefreshInactive(expiresAt, issuedAt),
  set IssuedAt after successful refresh, fix stale 7-day doc comment

Co-authored-by: zhangweiii <31117497+zhangweiii@users.noreply.github.com>
Copilot AI changed the title Fix credential expiration for inactive Claude Code accounts Replace hardcoded 7-day inactive token refresh window with dynamic half-lifetime Mar 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants