Launching from the App Hub (or any double-click) no longer needs
AGENTS_API_KEY manually injected. Order of resolution:
1. AGENTS_API_KEY env var → apikey_source = "env"
2. `pass agentes/api-key` shell → apikey_source = "pass"
3. neither → apikey_source = "missing"
On Windows the fallback shells via `wsl.exe -e sh -c "pass ... | head -n1"`
so the secret stays in the WSL user's GnuPG keychain (never copied to a
Windows file). On Linux it's a direct popen of `pass ...`.
Failure mode: GPG agent locked → empty output → "missing" state in UI
with a "Retry pass" button (user runs `pass agentes/api-key` once to
unlock the agent, clicks Retry, app refetches without restart).
Connection panel shows the active source:
✓ loaded from AGENTS_API_KEY env var
✓ loaded via `pass agentes/api-key`
⚠ apikey not found (env empty + pass failed)
--connect-test uses the same two-tier resolution so e2e exercises the
production code path.
E2E: renamed test_connect_fails_without_apikey →
test_connect_falls_back_to_pass_when_env_empty. Verifies that with
empty env, the .exe still returns OK N. Skips if `pass` is locked.
All 24 tests passing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Security: apikey NUNCA mas vive en local DB ni se introduce por UI.
Se lee al arranque via getenv("AGENTS_API_KEY"), sourced typically con
`pass agentes/api-key` antes de lanzar el .exe.
Connection panel:
- Removed apikey TextInput (+show/hide button)
- Removed UI mask flag
- Replaced con indicador "loaded from env" verde / "missing" rojo
- Hint visible: "Launch with: AGENTS_API_KEY=$(pass agentes/api-key) <exe>"
Persistencia local:
- db_save_connection: solo base_url (blob de apikey ya no se cifra)
- db_load_connection: solo base_url
- No mas roundtrip a fn_secret en runtime de la UI (la funcion del
registry secret_store_cpp_infra sigue util para otras apps)
CLI:
- --connect-test <url> ahora lee apikey de AGENTS_API_KEY env var
- trim_url() en make_url + en CLI defensivo contra paste con CR/LF
- run_self_test sin cambios (secret_store roundtrip se mantiene)
E2E tests (tests/test_connect_e2e.py, 5 casos):
- test_connect_succeeds_with_valid_apikey
- test_connect_fails_without_apikey
- test_connect_fails_on_bad_host
- test_count_matches_direct_curl
- test_url_trim_robust_to_whitespace
Lanzar con:
AGENTS_API_KEY=$(pass agentes/api-key) \
python3 -m pytest -v tests/test_connect_e2e.py
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>