Skip to content

feat: switch between named GitHub profiles from the TUI#12

Open
sashml wants to merge 2 commits into
zombocoder:mainfrom
sashml:feat/profile-switcher
Open

feat: switch between named GitHub profiles from the TUI#12
sashml wants to merge 2 commits into
zombocoder:mainfrom
sashml:feat/profile-switcher

Conversation

@sashml

@sashml sashml commented Jul 17, 2026

Copy link
Copy Markdown
Contributor

Profile switcher: switch GitHub contexts from inside the TUI

Adds named profiles so you can juggle multiple contexts — work vs. personal, public github.com vs. a GitHub Enterprise host — and switch between them from the TUI with a keypress, no restart or config editing.

Config ([[profiles]], back-compatible)

Each profile is a named body of the existing github/dashboard/cache/ui fields, plus an optional top-level active_profile. If no profiles are defined, the top-level config is treated as a single default profile — existing configs work unchanged.

active_profile = "work"

[[profiles]]
name = "work"
[profiles.github]
orgs = ["my-org"]
api_url = "https://api.github.com/graphql"
token_env = "GHDASH_TOKEN_WORK"   # env var NAME — never the token itself

[[profiles]]
name = "acme-enterprise"
[profiles.github]
orgs = ["acme"]
api_url = "https://ghe.acme.corp/api/v3"
token_env = "GHDASH_TOKEN_ACME"

Behavior

  • p opens a centered, type-to-filter modal picker (arrows navigate, Enter switches, Esc cancels). The active profile is marked and always shown as a status-bar chip.
  • Switching drops the old client, rebuilds it for the new profile's token and api_url, clears the PR set, and re-fetches.
  • Per-profile token resolution: token_envGITHUB_TOKENgh auth token --hostname <host>GH_TOKEN. api.github.com maps to github.com for gh; Enterprise hosts are used as-is.
  • Per-profile cache namespace (<cache-dir>/<profile-name>/) so switching never shows another profile's cached data.
  • Secret hygiene: tokens are only ever held in memory and only sourced from env/gh — never written to config, cache, logs, or the UI.

Tests

Adds coverage for the config schema and back-compat, host mapping, token resolution order, cache isolation, the picker reducer, and a check that no token value appears in serialized config or rendered output. cargo test, cargo clippy --all-targets -- -D warnings, and cargo fmt --check all pass.

sashml added 2 commits July 17, 2026 09:51
Add a profile switcher so you can juggle multiple contexts (work vs.
personal, public github.com vs. a GitHub Enterprise host) without editing
config or restarting.

- Config: optional [[profiles]] array, each a named body of the existing
  github/dashboard/cache/ui fields, plus an optional active_profile. When no
  profiles are defined, the top-level config is treated as a single "default"
  profile, so existing configs are unchanged.
- Per-profile token resolution, never persisted: token_env (env var NAME) ->
  GITHUB_TOKEN -> `gh auth token --hostname <host>` -> GH_TOKEN. Per-profile
  api_url supports Enterprise hosts; api.github.com maps to github.com for gh.
- Per-profile cache namespace (cache dir / <profile-name>) so switching never
  shows another profile's cached data.
- Modal picker on `p`: centered, type-to-filter, arrow-key navigation, Enter
  switches, Esc cancels; the active profile is marked and always shown as a
  status-bar chip. Switching drops the old client, rebuilds it for the new
  profile's token + api_url, clears the PR set, and re-fetches.
- Help overlay and README document the `p` binding, the chip, and the
  profiles config + token handling.

Tokens are never logged, rendered, cached, or serialized. Adds tests covering
the config schema and back-compat, host mapping, token resolution order, cache
isolation, the picker reducer, and secret hygiene (no token in serialized or
rendered output).

Signed-off-by: sashml <ml.den@disruptinc.io>
… github.com

A profile api_url that doesn't end in /graphql previously fell back to
api.github.com for REST (diff) calls — sending that profile's token to the
wrong host (incorrect + a token-leak risk for Enterprise). Derive the REST
base from the api_url's host instead, warn once, and keep public github.com
behavior. Adds rest_base tests incl. the Enterprise no-github-fallback case.

Signed-off-by: sashml <ml.den@disruptinc.io>
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