fix(desktop): honor real harness readiness in provider UI#8
Merged
OmGuptaIND merged 1 commit intomainfrom Apr 22, 2026
Merged
Conversation
On a fresh install the Settings page showed the codex CLI as "Connected"
and the composer pill displayed a leftover default model even though no
provider was actually usable. Root cause: `providerHasKey()` returns
`true` for any harness-type provider (so the CLI never needs an API
key), but the desktop UI was treating that value as a generic "is this
provider ready" signal.
Introduce a single-source-of-truth `isProviderReady` / `anyProviderReady`
helper in `packages/desktop/src/lib/providers.ts` that consults the real
harness detection state (`harnessStatuses[name].installed && auth.loggedIn`)
for harness providers and `hasApiKey` for API providers. Route every
relevant surface through it:
- Settings > AI Models ProviderRow — "Connected" badge now reflects
real CLI install + login state.
- Settings > Default model card — empty state ("No model selected" +
"Select model" CTA) when nothing is ready, instead of a misleading
default.
- Composer ModelSelector — `anyReady` drives the "Select a model"
empty state (previously broken because `p.type === 'harness'` made
`hasAnyKey` always true).
- ModelPopover `groupFor` — now pure and reactive to `harnessStatuses`
changes while the popover is open (pre-existing latent bug: memo
deps didn't include the status map).
- HarnessProviderSwitch — disabled state now based on real readiness;
tooltip differentiates "not installed" vs "not logged in".
- ChatInput send button — disabled when no provider is ready; Enter-key
path gated in `handleSend` to match.
Also adds a `composer__model--empty` CSS modifier so the empty-state
pill matches the populated pill's 26px height and balanced padding
(previously the missing avatar collapsed the pill vertically and the
label jammed against the border).
Backend `providerHasKey()` semantics intentionally left alone — they
are load-bearing for agent-runner chat gating and there are no tests.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
OmGuptaIND
added a commit
that referenced
this pull request
Apr 24, 2026
### Features - multi-format file attachments with @-mentions and preview renderers (#12) ### Fixes - pnpm lock - workspace safety net — no more /root EACCES, atomic writes, version handshake (#11) ### Chores - clean up biome lint + format across repo ### Other - feat(desktop): remove new-project attachments, add text-file creator in files view (#10) - feat(desktop): reasoning effort pill + provider modal redesign + onboarding tour (#9) - fix(desktop): honor real harness readiness in provider UI (#8) - fix(harness): persist session title to meta.json across reloads (#7)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
codexas Connected (green dot) and the default-model card displayed a leftover model, even though no CLI was installed or logged in. Root cause:providerHasKey()returnstruefor any harness-type provider (so the CLI never needs an API key), and the desktop UI was treating that as a generic is this provider ready signal.isProviderReady/anyProviderReadyinpackages/desktop/src/lib/providers.tsas the single source of truth — consultsharnessStatuses[name].installed && auth.loggedInfor harness providers,hasApiKeyfor API providers — and routes every relevant surface through it.ModelPopover.groupFor: the grouping memo didn't includeharnessStatusesin its deps, so a harness login completed while the popover was open wouldn't move the provider out of "Not configured".Surfaces fixed
No model selected+ Select model CTA) when nothing is ready, instead of a misleading default.anyReadydrives the "Select a model" empty state; the pill's oldhasAnyKeypredicate was always true whenever harness providers existed in the defaults list.groupForis now pure; the popover subscribes toharnessStatusesand includes it in memo deps so groupings update live.p.installed, a field the backend never populates — so the switch was effectively always disabled.handleSendto match.composer__model--emptymodifier keeps the empty-state pill at the same 26px height (matching the avatar-populated pill withbox-sizing: border-box) and balances horizontal padding so the label doesn't jam against the left border.Not changed (deliberately)
providerHasKey()inpackages/agent-config/src/config.tsstill returnstruefor harness providers. That value is load-bearing foragent-runner.tschat gating (lines 420, 929, 1062) and there are zero tests underpackages/agent-config,packages/agent-server, orpackages/desktop. A frontend-only fix is tightly scoped and mirrors the already-correctModelSelector.groupForpattern.pickDefaultProvider()(falls back toanthropic/claude-sonnet-4-6). It has to come from a leftover~/.anton/config.yamlor a prior onboarding selection. With this change that no longer misleads the UI — a stale default is never shown as "Connected".Test plan
No automated tests exist in this monorepo; manual QA on a clean profile:
~/.anton/config.yamland ensurewhich codexis empty.codexbut don't log in → both surfaces still show Connect; switch tooltip shows "not logged in".codex login→ Settings row flips to green "Connected" without closing Settings; popover moves codex from "Not configured" to "Subscriptions" without reopen; composer pill shows the real model; send button re-enables.🤖 Generated with Claude Code