Skip to content

One wiring profile and one saved connection across web, CLI, SDK and MCP - #27

Merged
wardviaene merged 1 commit into
mainfrom
one-source-of-truth
Oct 9, 2026
Merged

wardviaene merged 1 commit into
mainfrom
one-source-of-truth

Conversation

@wardviaene

Copy link
Copy Markdown
Member

UX plan tier 4: the web UI, the CLI, the SDK and the MCP server agree on which pod to use and which wiring profile it has.

One wiring profile

bp.wiring resolves, first match wins:

  1. the wiring= argument (pytest: --benchpod-wiring, then the benchpod_wiring fixture)
  2. the BENCHPOD_WIRING file
  3. the profile stored on embeddedci.com for this pod (the web UI's Wiring tab), source == "server":
    • cloud (embeddedci:<device>): that device (unchanged)
    • new: LAN (or a USB console that answers JSON): the device id the pod reports in cloud_status, when api_key=/BENCHPOD_API_KEY, cloud_user_token= or the benchpod login session is available and the device is on that account
  4. the defaults

Step 3 never raises: no credentials, pod not registered, server unreachable, 401/403/404 or a bad profile all log why and use the defaults. On LAN/USB the whole lookup (cloud_status + one GET) has a ~3 s budget; the transport timeouts are restored afterwards. Opt-out: wiring_source="local" / BENCHPOD_WIRING_SOURCE=local (skips the server lookup for every connection kind).

One saved connection

BenchPod() picks: connection argument > BENCHPOD_CONNECTION > the connection benchpod-cli saved (benchpod set-connection, ~/.config/benchpod-cli/config.json, $XDG_CONFIG_HOME respected; connection, else legacy bench_pod_addr). Read-only; missing/malformed file = nothing saved. The connection string saved names it explicitly.

The pytest plugin does not use the saved connection implicitly (no connection still skips the hardware fixtures); opt in with --benchpod-connection=saved.

MCP connect: argument > --connection > BENCHPOD_CONNECTION > CLI saved connection > mDNS. The benchpod login session is handed to the SDK for LAN/USB connections too (only when a login exists), and connect/status report wiring_source.

Behavior changes (in both CHANGELOGs)

  • A signed-in (or API-key) LAN pod that is registered and has a stored profile now gets that profile instead of the defaults; the first bp.wiring access makes one cloud_status call and one HTTP request.
  • BenchPod() without a connection used to raise ConnectionConfigError; it now connects to the CLI's saved pod when there is one.
  • MCP connect() without a connection goes to the CLI's saved pod before mDNS.

Compatibility

  • Additive SDK API: wiring_source= on BenchPod, modules embeddedci.benchpod.cli_config and embeddedci.benchpod.cli_login (api_surface.json refreshed). The MCP tool surface gains StatusResult.wiring_source.
  • The MCP pin stays embeddedci>=2.9: the saved connection is read via a guarded import, and the new MCP tests skip on an SDK without cli_config. Verified against embeddedci 2.9.0 from PyPI (147 passed, 17 skipped).
  • Unit-test conftests point XDG_CONFIG_HOME at a temp dir (not for e2e/examples), so a developer's saved connection or login never leaks into unit tests.

Tests

  • pytest packages/embeddedci: 600 passed, 175 skipped
  • pytest packages/embeddedci-mcp: 152 passed, 12 skipped
  • pytest packages/embeddedci-openhtf: 74 passed, 3 skipped; pytest scripts: 12 passed
  • HW (pod lock held, read-only) on benchpod-baea06 over LAN 192.168.1.220 with the benchpod login session: bp.wiring.source == "server" in 0.41 s, equal to the profile GET /benchpod/devices/{id}/wiring/profile returns (stored uart_rx: 3, where the defaults say 5). wiring_source="local" gives the defaults. Over USB (fw 3.8.0 text console) cloud_status is unavailable, so the defaults apply (logged at info).

🤖 Generated with Claude Code

- A LAN/USB BenchPod now uses the wiring profile stored on embeddedci.com for the device the
  pod reports in cloud_status, when BENCHPOD_API_KEY, a caller's user token or the
  `benchpod login` session is available. wiring=/BENCHPOD_WIRING still win; every failure
  logs and falls back to the defaults within ~3 s. New wiring_source= /
  BENCHPOD_WIRING_SOURCE=local opt-out.
- BenchPod() falls back to the connection benchpod-cli saved
  (~/.config/benchpod-cli/config.json, read-only): argument > BENCHPOD_CONNECTION > saved.
  The "saved" connection string names it; the pytest plugin only uses it when asked
  (--benchpod-connection=saved).
- MCP connect: argument > --connection > BENCHPOD_CONNECTION > saved > mDNS; the login is
  handed to the SDK on LAN/USB too; connect/status report wiring_source.
- New SDK modules cli_config and cli_login; READMEs, CHANGELOGs (behavior changes), tests.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@wardviaene
wardviaene merged commit b6bc315 into main Oct 9, 2026
20 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant