Skip to content

fix(devices): clean up pending_auth on device-code timeout/cancel - #790

Merged
ctkm-aelf merged 2 commits into
mainfrom
investigate-nyxid-706-resolution
May 19, 2026
Merged

ctkm-aelf merged 2 commits into
mainfrom
investigate-nyxid-706-resolution

Conversation

@ctkm-aelf

@ctkm-aelf ctkm-aelf commented May 18, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • CLI nyxid service add --device-code now redraws a countdown timer each tick, prompts [Y/n] to renew on expiry in TTY mode (default Y), and bails immediately in non-TTY mode. Every abort path (expiry+declined, denial, 30 consecutive errors, ctrl+C) DELETEs the placeholder via ?only_if_pending=true before exit.
  • Dashboard add-key-dialog::DeviceCodeStep gets the same cleanup discipline: Back/Cancel buttons, expired/denied poll outcomes, and component unmount (X / Esc / outside-click) now drop the placeholder. The success branch nulls a ref so the happy path skips the redundant DELETE.
  • No backend changes — both CLI and dashboard see terminal poll responses (expired/denied) directly from POST /providers/{id}/connect/device-code/poll and own the placeholder lifecycle via the existing DELETE /keys/{id}?only_if_pending=true endpoint. Earlier draft included a backend fast-fail in poll_device_code's denied arm, but it raced the CLI/dashboard cleanup (flipping to failed made ?only_if_pending no-op and the row lingered in service list) and was reverted per code review.

Closes #706.

Test plan

  • nyxid service add llm-openai-codex --device-code --label \"QA-$(date +%s)\" --base-url https://nyx-api.chrono-ai.fun — let the code expire, decline renewal at the prompt → nyxid service list shows no leftover
  • Same flow — accept renewal at the prompt, complete auth on the provider page → exactly one active row, no duplicates
  • Same flow — hit ctrl+C mid-poll → no leftover
  • nyxid service add ... --device-code < /dev/null (simulate non-TTY) — let expire → bails immediately with timeout message, no leftover
  • Dashboard: open Add Key → pick a device-code provider (e.g. Codex) → close the dialog via X mid-flow → no leftover in /keys
  • Dashboard: complete auth normally → row appears as active
  • Dashboard: click Back from the show_code or error screen → no leftover

🤖 Generated with Claude Code

ctkm-aelf and others added 2 commits May 18, 2026 17:26
CLI + dashboard device-code flows now DELETE the placeholder via
?only_if_pending=true on every abort path (expiry+declined renewal,
denial, network errors, ctrl+C, dashboard Back/Cancel, dialog
unmount), so `nyxid service list` no longer accumulates leftover
services from abandoned attempts. Also adds a redrawn countdown
timer and a [Y/n] renewal prompt in the CLI's TTY mode; non-TTY
bails on first expiry without prompting.

Closes #706.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Ports the device-code countdown + on-expiry/denied cleanup from the
terminal-only and dashboard paths to the cli-wizard's DeviceCodeFlow
(frontend/src/components/cli-wizard/auth-flows.tsx), which is the
default path most users hit. The wizard now reads init.expires_in for
its client-side deadline (was hardcoded 10min), shows an "Expires in
MM:SS" chip beside the CODE label, and calls releaseServerState() on
expired/denied so the placeholder doesn't linger if the user walks
away. The "Request a new code" button continues to work via existing
startSession() re-entry.

CLI follow-ups in the same change:
- Decouple countdown redraw from poll cadence: the inner loop now
  ticks every 1s for visible MM:SS movement while the HTTP poll is
  throttled to the provider's `interval` (5s+).
- Add NYXID_DEVICE_CODE_DEADLINE_SECS env var that clamps the
  client-side deadline in both the terminal flow and (via a
  forwarded ?expires_in_override query param) the wizard, so QA can
  exercise expiry/renewal paths in seconds instead of waiting ~15min
  for a real provider expiry.

Wizard now ships a responsive SVG favicon (nyxid-app-icon.svg)
matching the dashboard's <link rel="icon"> — previously the wizard
served only the static .ico fallback.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@ctkm-aelf
ctkm-aelf marked this pull request as ready for review May 19, 2026 05:53
@ctkm-aelf
ctkm-aelf merged commit e823481 into main May 19, 2026
15 checks passed
@ctkm-aelf
ctkm-aelf deleted the investigate-nyxid-706-resolution branch May 19, 2026 05:53
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.

[Bug] [CLI Wizard Device Code] Expired device-code flow times out in CLI but leaves a pending_auth service

1 participant