* feat(aimlapi): AI/ML API guided onboarding (top-up + key issuance)
Add the AI/ML API provider integration to the zero CLI: a guided TUI
onboarding sub-flow that takes an existing key or an email top-up and
writes the issued key into the provider profile, attributed to the
Gitlawb rebate partner.
- internal/aimlapi: OpenAI-compatible client, partner-checkout top-up,
key validation, streaming, and endpoint config (Paths A/B/C).
- providercatalog / providermodelcatalog: register the aimlapi provider
with default headers and models.
- tui: aimlapi onboarding screen wired into the provider wizard and
onboarding flow.
Default endpoints point at production (auth/app/api/pay/aimlapi.com);
each is overridable via AIMLAPI_*_URL env vars.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
* fix(aimlapi): address review findings in onboarding flow
- topup: use errors.As for the 5xx retry check so a wrapped APIError
still retries instead of aborting a paid checkout.
- onboarding: a Path-A top-up on an email with no account now lands on a
single coherent "key saved, balance not topped up" screen instead of a
green "ready" plus a red error.
- onboarding: an empty amount field is rejected instead of silently
falling through to the $25 default.
- collapse the two identical top-up prompt constants into MsgTopUpPrompt
and drop the dead amountPrompt() branch.
- reuse stdlib maps.Clone instead of a third bespoke header-copy helper.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
* fix(aimlapi): retry transient poll errors and sharpen amount validation
* fix(aimlapi): retry transient poll errors and surface real amount errors
* docs(aimlapi): document exported client API; drop out-of-scope gitignore entry
Addresses the two CodeRabbit PR checks on #655:
- Add doc comments to the exported aimlapi client API (Client, APIError,
the session/checkout/onboarding types and their methods) and
ParseAmountUSD, to satisfy the docstring-coverage check.
- Remove the unrelated /zero.exe~ .gitignore entry that an earlier
review-fix commit added; it is out of scope for the provider work, so
the PR no longer touches .gitignore.
Co-Authored-By: Claude Opus 4.8 <[email protected]>
* fix(aimlapi): render aimlapi row like other recommended providers
* fix(aimlapi): resolve onboarding review findings (Path A funding, base URL, request cancellation)
* fix(aimlapi): validate pasted API keys
* test(aimlapi): clarify pasted key validation
* test(aimlapi): cover key-balance low-balance transition
* fix(aimlapi): reject non-finite top-up amounts
* fix(cli): scope and canonicalize provider headers
* fix(tui): distinguish invalid verification codes
* feat(aimlapi): resume account-bound top-ups safely
* feat(tui): offer top-up for existing AIMLAPI keys
* feat(tui): reuse AIMLAPI env key on first run
* feat(tui): reuse configured AIMLAPI profiles
* test(aimlapi): trim redundant flow coverage
* fix(tui): preserve existing AIMLAPI profile metadata
* fix(tui): clone AIMLAPI headers in env fallback
* fix(aimlapi): address remaining review findings
* fix(aimlapi): harden onboarding lifecycle
* fix(aimlapi): preserve validated checkout context
* fix(aimlapi): harden checkout retry state
* fix(tui): clarify AIMLAPI configured choices
* fix(aimlapi): make checkout retries idempotent
* fix(aimlapi): validate checkout responses
* fix(providers): reconcile aimlapi catalog after rebase
---------
Co-authored-by: Lookoff123 <[email protected]>
Co-authored-by: Claude Opus 4.8 <[email protected]>
* fix(provider): stop dropping custom no-auth providers on restart
Custom OpenAI/Anthropic-compatible catalog entries hardcode
RequiresAuth as a template default for the setup wizard, not a fact
about the user's actual endpoint. Leaving the credential step blank
(e.g. a local llama.cpp server) still stamped the saved profile with
a guessed OPENAI_API_KEY/ANTHROPIC_API_KEY env var, and that same
static RequiresAuth flag then made the profile look like it was
missing a required credential on the next run, silently filtering it
out of /model.
Add a Custom flag to the catalog descriptor so both the wizard
(write side) and setupMissingCredentialEnv (read side) judge these
profiles by their own explicit APIKeyEnv instead of the catalog's
static default.
Fixes#555
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Co-authored-by: Pierre Bruno <[email protected]>
* fix(provider): self-heal legacy custom profiles stamped by the old wizard bug
CodeRabbit flagged that profiles saved before this fix could already
carry the phantom APIKeyEnv the old wizard stamped on every custom
provider (e.g. OPENAI_API_KEY), and the new custom-branch logic would
keep treating any non-empty APIKeyEnv as an explicit requirement —
leaving already-affected users' providers filtered out of /model even
after upgrading.
Treat an APIKeyEnv that exactly matches the catalog's own guessed
default as indistinguishable from unset, so already-broken saved
profiles self-heal without a config.json migration. A deliberately
different env var name (e.g. via --api-key-env) still means auth is
required.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Co-authored-by: Pierre Bruno <[email protected]>
* fix(provider): centralize custom-endpoint credential logic, fix two more surfaces
Copilot's review of the earlier fix found the same RequiresAuth-as-
authoritative bug in two more places that decide whether a saved
provider needs a credential:
- validateProviderRuntimeReady (zero providers check) would hard-error
a no-auth custom endpoint with "requires API key".
- providerWizardCredentialLabel and providerCredentialRequired (/providers
status, wizard summary) would still claim/warn that one was needed.
Added config.ProviderProfile.MissingCredentialEnv as the single source
of truth for this decision (custom-endpoint self-heal included), and
had setupMissingCredentialEnv and validateProviderRuntimeReady delegate
to it. providerWizardCredentialLabel and providerCredentialRequired
take the same Custom-aware fix directly, since their non-catalog
fallback path uses runtime-resolved provider-kind metadata that
shouldn't be collapsed into the canonical helper.
Co-Authored-By: Claude Sonnet 5 <[email protected]>
Co-authored-by: Pierre Bruno <[email protected]>
* fix(ci): request pinned Go toolchain directly
Co-authored-by: Pierre Bruno <[email protected]>
---------
Co-authored-by: Amp <[email protected]>
Encrypted credential storage
- internal/securefile: AES-256-GCM at-rest crypter (fail-closed, atomic, locked).
- internal/credstore: provider API-key store, keyring-first with an encrypted-file
fallback; plaintext only via an explicit ZERO_CRED_STORAGE=file opt-out.
- Provider API keys no longer live in config.json: captured straight into the store
from the wizard/CLI setup, and any existing inline plaintext key is migrated to the
store on launch (fail-soft; stripped only after the store write succeeds).
- buildProvider and every model/provider switch reload the credential (stored key,
env var, or OAuth bearer), so a stored-key provider always authenticates.
- `zero auth logout <provider>` now also removes the stored API key and its marker.
/model and /provider
- /model lists every authenticated provider (filtered to those with a usable
credential), grouped per provider under section headers.
- Each provider's models are live-discovered (its real served models) rather than a
static catalog; local providers show only the models actually pulled.
- Selecting a model from another provider switches provider and model together.
- /provider offers keep / replace / remove when a provider already has a stored key.
Gated throughout: go build, go vet ./..., go test ./... -race, lint.
Resolve product/UX audit findings for the OSS launch: doctor now fails uncredentialed remote providers (no false green), Redact() no longer mangles the common first-run auth error, SSRF-safe loopback exemption unblocks keyless local models, new validated --theme flag, WCAG-AA contrast fixes, NO_COLOR compliance, clearer first-contact errors, and full OSS scaffolding (SECURITY/CoC/CHANGELOG/templates/release workflow). Audit ledger maps every Fixed claim to a real change with zero overclaims.
Introduce zero setup plus first-run onboarding for missing provider credentials, backed by the provider catalog and config save path.
Make the TUI fullscreen in interactive mode, keep setup transitions inside the chat surface, and add managed transcript scrolling so wheel/PageUp/PageDown do not recall composer history.
Tested: GOCACHE=/tmp/zero-go-cache go test ./...
Tested: git diff --check