Files
better-claude-config/PR87-test-checklist.md
the_ogandClaude Opus 4.8 4743c4a995
CI / Lint (ruff) (pull_request) Successful in 19s
CI / Tests (py3.12 / windows-latest) (pull_request) Successful in 24s
CI / Tests (py3.10 / ubuntu-latest) (pull_request) Successful in 29s
CI / Tests (py3.12 / ubuntu-latest) (pull_request) Successful in 29s
CI / Tests (py3.13 / ubuntu-latest) (pull_request) Successful in 31s
CI / Catalog signature (pull_request) Successful in 22s
feat(#83): offer move-to-env on args rows; explain the gate instead of an empty menu
Two things surfaced testing the GUI:

1. Args rows showed the secret warning but no move action -- the args
   editor is a free-text widget, not a table, and was deliberately left out
   of the first cut. Wired it up: ArgsEdit gains a context menu that offers
   "Move to environment variable…" on exactly the args that look like a
   credential. New pure core: secret_arg_indices (which args are secrets,
   mirroring args_secret_warning per-index) and suggested_env_var_for_arg
   (default var name from the preceding flag -- `--api-key <secret>` ->
   API_KEY, else SECRET). The move replaces that one arg line with ${VAR}
   and copies the secret to the clipboard, same contract as the tables.

2. On a Claude Desktop profile (or any non-expanding client) the menu showed
   NOTHING, so it read as broken. Now a real stored secret always shows the
   item -- enabled on a client that expands references, or disabled with the
   reason ("unavailable for Claude Desktop -- it doesn't expand ${VAR}") so
   the gate is visible rather than silent. Applies to env, headers and args.

Not a change: after converting, env_ref_warnings still notes a variable that
isn't set in the environment. That's #82's advisory doing its job -- the user
runs the export line the dialog handed them; auto-adding a ':-default' would
bake a fallback back into the config and defeat moving the secret out.

Tests: +5 core (secret_arg_indices for token/flag-value/embedded-URL/
reference-excluded, suggested_env_var_for_arg with and without a flag).
483 passed, ruff clean. GUI wiring (context menus) remains untestable in CI.

Refs #83

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EKwBecy6N83jnqQmw8ezwE
2026-08-04 04:03:47 +00:00

3.4 KiB

PR #87 — "Move to environment variable" (#83): manual test checklist

The logic is covered by 15 unit tests in CI; what CI can't exercise is the GUI (no PySide6). This checklist is only the parts a human needs to click. Should take ~10 minutes.

Setup

cd ~/Documents/Claude/Projects/BetterClaudeConfig/better-claude-config
git fetch origin
git checkout feat/83-move-to-env-var
git pull                      # ensure you're on 8fdbe90 or later
source .venv/bin/activate     # or recreate: python3 -m venv .venv && source .venv/bin/activate && pip install -r requirements.txt
python bcc.py

Pick a Claude Code profile (e.g. ~/.claude.json) that has, or add, a server with an env value that looks like a secret — e.g. env: { "API_KEY": "ghp_test123" }. (You can use a throwaway value; nothing is sent anywhere.)

The checklist

Gating — where the action appears

  • Right-click the value cell of a secret env row (API_KEY) on a Claude Code profile → a "Move to environment variable…" item appears.
  • Right-click a non-secret row (e.g. REGION = us-east-1) → the item does not appear.
  • Right-click a row whose value is already a reference (${API_KEY}) → the item does not appear.
  • Switch to a Claude Desktop profile (a claude_desktop_config.json), right-click the same kind of secret row → the item does not appear. (Desktop doesn't expand ${VAR}, so offering it would break the config — this is the important gate.)

The dialog

  • Trigger the action → dialog opens with Variable pre-filled from the key, sanitized to a legal shell name (e.g. api-key → API_KEY).
  • Edit the variable name → the shown shell line updates live and matches your platform (export VAR='…' on macOS/Linux, setx VAR "…" on Windows), with the other platform shown in parentheses.
  • If you type a variable name that is already set in your shell environment, the green "already looks set" note appears; if not, it's hidden.
  • Cancel → nothing changes (value still the raw secret, no dirty state).

The conversion

  • Move && copy secret → the cell now shows the reference ${VAR} (visible, not masked to dots), and the window goes dirty (Save enabled).
  • Paste from your clipboard somewhere → it's the original secret value (handed back before removal).
  • The reference value is not flagged as a secret warning anymore (it's the recommended state).

Headers + persistence

  • Repeat on a remote server's Headers table (e.g. an Authorization header) → same behavior.
  • Save, then open the config file on disk in a text editor → the servers block holds ${VAR}, and the plaintext secret is gone from the file.
  • Re-open the profile in BCC → the row still shows ${VAR} (round-trips).

Undo (nice-to-have)

  • After a conversion, Ctrl+Z / Cmd+Z restores the previous value.

Known scope (not bugs)

  • Args rows are out of scope for this PR — the core supports them, but the args editor is a free-text widget, so wiring that UI is a deliberate follow-up. Right-clicking args won't offer the action yet.
  • The "already set" check reads BCC's environment, which may differ from the client's — it's advisory, worded that way.

If anything's off

Tell me which checkbox failed and what you saw; I'll fix on the branch and re-push. If everything passes, approve/merge #87 (or tell me to merge it).