CodeNomad/docs/help/en/providers.md
Pascal André 5bc483d08d
feat(ui): toggle several rows at once by dragging across toggles (#1221)
Setting many rows of the same kind (Message content eyes, session
selection checkboxes, model visibility) took one click per row. Image
editors let users drag across a column of layer eyes instead; CodeNomad
now does the same.

Pressing a toggle and dragging out of it flips it, and every toggle of
the same column or list the pointer then crosses takes that new state;
toggles already in that state stay as they are. Releasing the button
clicks nothing, including the first toggle when the drag returns to it.
It works for mouse and pen; touch drags keep scrolling, and a touch
landing during a mouse drag leaves the sweep going.

Implementation: `lib/toggle-sweep.ts` installs one capture listener on
first use. Toggles opt in with `data-toggle-sweep={toggleSweepGroup(...)}`,
one group per column or list, so the Message content eyes and chevrons
sweep separately and exclusive selectors (tabs, presets) never sweep.
Each toggle changes through its own click, so its handlers, disabled
state and accessibility are unchanged; state is read from `checked`
(labels stand for their checkbox) or `aria-pressed`/`aria-checked`. The
drag is sampled every 4 px so fast moves skip no row, text selection
and native drag are blocked during a sweep, the trailing click is
swallowed, and a sweep whose release went elsewhere ends at the next
move without the button. `afterSweep` defers costly work until the
sweep ends.

Groups: Message content visibility and expansion columns, session
selection checkboxes, right-panel customization (built-in tabs and
Status sections; extension activation is a trust decision and stays
out), notification routing, model visibility, and the multi-select
options of agent forms and provider sign-in forms.

Message content dropped clicks made while a save was pending and showed
a row only once the server confirmed it, re-rendering the transcript
for each. Rows now show their requested state at once; a sweep saves
once, on release, so the transcript re-renders once. Saves run in
order and each batch of rows is sealed as it joins the queue, so a
later click never jumps ahead of a preset change nor rides along with a
sweep still held.

Notification routing shows each box at once, writes the whole table
once per sweep, runs its writes one after another so an older table
never lands last, and asks for System permission once per gesture.
Model visibility already showed pending changes and wrote them in
order.

Validation: browser regressions in transcript-presets (a single jump
across four eyes with slow saves, shown during the drag with nothing
saved, then one write on release; a hidden row that stays hidden; a
release back on the origin; the chevron column alone; a held sweep not
persisted by queued saves; a row clicked after a preset applying after
it), session-search (both directions, a release over a row title
opening no session, a lost release leaving no sweep, a touch mid-drag)
and notification-routing (one write per sweep, serialized writes with
the last winning, one permission request). Each fails with its part of
the fix removed. Two gatekeeper rounds ended with no P0-P2 finding; the
user validated the behaviour in a separate Electron dev instance.
dev-docs/UI_CONVENTIONS.md and dev-docs/TRANSCRIPT.md record the
convention, and the help describes the gesture in all ten languages.
2026-10-31 00:49:50 +01:00

11 KiB

Providers and accounts

Provider authentication belongs to the connected OpenCode service, not to the browser device or one CodeNomad project. Model-display preferences, subscription quotas and web-search choices have different scopes.

Connect a model or search provider

  1. Open a workspace, then Settings → Providers. Models starts expanded; expand Web search for search providers. Images holds the image settings.
  2. In that group, choose Select provider, then Connect.
  3. For a model provider, complete the native Authentication method offered: API key, OAuth or command. For OAuth, use Open authorization page and submit an authorization code only when requested. Search providers connect with an API key.
  4. Check the configured-provider row after completion. Models rereads after connections, account changes and reconnects; Web search also has Refresh.

Search-only integrations appear under Web search, not Models. Saving authentication does not choose a model or change the default search provider. API keys and OAuth credentials are saved by the active OpenCode server. The browser receives connection metadata, not saved credential secrets. A connection sourced from environment variables is read-only in this UI: change its owning environment rather than trying to disconnect it here.

If the authorization window is blocked, use Open authorization page, Open in this tab or Copy link from the flow. Do not publish the authorization link or code in diagnostics.

Select and manage accounts

  1. In the provider's row, use Active account to select a saved credential.
  2. Use Add account to authenticate another connection.
  3. To manage a different saved account, select it first, then use Rename account or Remove account. Renaming uses Account label and Save; Remove account acts immediately, without a confirmation.

Selection, renaming and removal affect that integration across the OpenCode service, including other projects and clients. Removing a credential can leave those clients without authentication; it does not delete conversation history or revoke the provider's remote account. Environment connections cannot be selected as writable saved credentials or removed here. If an operation fails, CodeNomad rereads the accounts: check Active account again before acting.

Automatic selection limits

With multiple saved credentials on a supported integration, Auto-select account opts into quota-based selection before the next prompt/custom-command admission through CodeNomad. The setting is per integration in CodeNomad configuration; a resulting account selection is service-wide.

Eligible integration Eligible account type
OpenAI / Codex Codex browser/device OAuth subscription accounts, not OpenAI pay-as-you-go keys or the ChatGPT sign-in method whose usage OpenAI does not provide.
OpenCode Go Go key, or OpenCode Console sign-in/key used for the Go provider only, not Zen pay-as-you-go credits.
Anthropic OpenCode's Claude Pro/Max OAuth login, not the Claude Code login.
GitHub Copilot OAuth with readable premium-request quota; enterprise-endpoint credentials are not readable candidates.
Coding plans Key-based zai-coding-plan, zhipuai-coding-plan, kimi-for-coding, minimax-coding-plan, minimax-cn-coding-plan.

Only a full current account triggers switching; merely having a fuller alternative does not. Reads examine explicit saved credentials without activating candidates or exchanging refresh tokens. Codex, Copilot and coding plans require a demonstrably available candidate. Go, Console and Claude may use an unknown-quota candidate unless a recent native quota failure marks it exhausted. OpenCode Go's usage endpoint and Console OAuth usage remain unverified upstream, so availability is not guaranteed.

This is not in-flight failover. It neither retries failed requests nor replays prompts, commands or mutations. It does not rotate environment connections, arbitrary providers, pay-as-you-go balances or external Claude Code logins. Manual account changes are respected during selection preparation; there is no cross-client account lock. On quota/authentication errors, inspect Active account, refresh Usage and sign in with the credential's owner as needed before deliberately sending again.

Model visibility, favorites and Thinking

  1. Choose Manage models beside a model provider.
  2. Search by name/ID and change visibility; Show all and Hide all affect that provider's selector list. Drag across the checkboxes to change several models at once.
  3. In a conversation's Model selector, use Add to favorites or Remove from favorites; Show all models leaves favorites-only filtering.
  4. Use Thinking in the composer for variants the selected model exposes.

Visibility and favorites organize CodeNomad's selectors; they do not uninstall models, remove credentials or prevent other OpenCode clients from using them. Hiding a model is not account disconnection. Thinking selects a model variant for subsequent sends, not the visibility of reasoning already in the transcript. Restore hidden models with Manage models → Show all.

Usage, token counts and expired logins

Use Usage in the right panel for the active conversation's provider-plan windows, reset times and supported balances. These provider readings are different from per-message Tokens and cost estimates: a subscription quota is not a bill calculated from the visible transcript. A missing, stale or unknown reading is not zero usage or proof of remaining capacity. Provider credit balance in Settings → Advanced controls supplemental balance display.

OpenAI does not provide usage for one ChatGPT sign-in method: Usage says so instead of showing quota windows. Chatting still works, and reconnecting the same login does not restore the reading.

Usage follows the selected native credential. Claude through anthropic/claude uses OpenCode's Anthropic OAuth. OpenCode's Claude Agent provider (claude-agent) and the claude-code provider use the Claude Code login on the daemon's host, including its WSL distribution: CLAUDE_CODE_OAUTH_TOKEN, then the stored login, with CLAUDE_SECURESTORAGE_CONFIG_DIR / CLAUDE_CONFIG_DIR or ~/.claude determining file storage; local macOS can use Keychain. CodeNomad does not substitute one Claude login for the other.

For an expired provider login, refresh/sign in through its owner—OpenCode, Claude Code or Codex CLI—then refresh CodeNomad. CodeNomad does not exchange externally owned refresh tokens. A CodeNomad server-login expiry is separate: reconnect/sign in to CodeNomad without assuming a failed provider request will be resent. See Troubleshooting.

Optional usage environment variables

Set these in the environment of the CodeNomad backend process before launching it. They are usage-reader credentials, not browser settings or model-selection controls. Changing the session Environment Variables editor does not update a running backend's process.env for these readers. Restart the backend under the intended environment when changing them; do not restart the shared OpenCode service just for a usage-reader variable.

Usage integration Environment variable
Cursor CURSOR_ACCESS_TOKEN, falling back to CURSOR_TOKEN
Ollama Cloud OLLAMA_CLOUD_COOKIE
OpenCode Go supplemental usage OPENCODE_GO_WORKSPACE_ID and OPENCODE_GO_AUTH_COOKIE together
ZenMux ZENMUX_PLATFORM_API_KEY — platform key, distinct from the inference key
exe.dev EXE_DEV_USAGE_TOKEN
Command Code COMMAND_CODE_API_KEY fallback when a native credential is unavailable

Keep tokens/cookies out of shell history, screenshots and reports. Optional readers depend on provider APIs and credential validity; configuring a variable is not a guarantee of usable quota data.

  1. In Settings → Providers, expand Web search and connect the search integration with its API key if it needs one.
  2. Choose Default search for Global configuration.
  3. Use For the current project to override it for the active Location. Hover or focus that selector to see Search in this project with the effective result.

Changes save automatically. Default / inherited uses inherited configuration or the saved native choice; a Project override wins over Global. Disabled turns search off at the selected scope; Automatic provider requests native automatic provider selection. Web search loads its connections and choices only while expanded. Disconnect removes a saved search key; a connection supplied by an environment variable is labelled read-only and has no Disconnect.

Search credentials remain service-global even when the provider choice is Project-scoped. Saving a key does not select it as the search default. If reading/saving fails, refresh before retrying; do not replace configuration blindly. For native configuration details, see OpenCode documentation and OpenCode setup.

Image generation and storage

  1. In Settings → Providers, expand Images.
  2. Image generation is On, automatic model unless you change it: choose one of the image models offered by your connected providers instead, or Off to turn it off in the Global configuration.
  3. Check Store images once to keep each attached or generated image a single time instead of inside every message that uses it.

Changes save automatically to the Global OpenCode configuration and apply to every project. Both are experimental OpenCode features: Images shows only the settings the connected OpenCode version supports. Agents get the image tool only while a connected provider offers an image model. Each image is generated in the background and saved as a file; the agent reports its path. Store images once applies to new messages. If the project's own OpenCode configuration file decides Store images once, the box shows the value used there and saving also writes it to that file. Otherwise, when another OpenCode configuration, such as the project's own, decides a setting instead, Images says so under that setting. If saving would hide the experimental settings of another OpenCode configuration file, Images stays read-only and says so; change the options in that file instead.

To create, compare and refine images in a dedicated conversation, see Create images with the Design extension.