Skip to content

TUI: replace the wizard-replay ⌥s with a proper settings card - #1069

Merged
codyde merged 4 commits into
masterfrom
railway/settings-menu
Aug 11, 2026
Merged

TUI: replace the wizard-replay ⌥s with a proper settings card#1069
codyde merged 4 commits into
masterfrom
railway/settings-menu

Conversation

@codyde

@codyde codyde commented Aug 10, 2026

Copy link
Copy Markdown
Collaborator

What

⌥s used to replay the entire first-run wizard, and ⌥t cycled the theme blind — two chords on the main screen, one of them a four-step flow, to change a single answer.

⌥s now opens a settings card listing every preference from agent-prefs.json with its current value beside it:

╭─ settings ───────────────────────────────────────╮
│               Cloud agent settings               │
│                                                  │
│ ▌ Coding agent        ‹ claude ›                 │
│      Anthropic's Claude Code                     │
│   Default project     devtools (production)      │
│      Where new cloud agents are created          │
│   Skills sync         on · claude                │
│      Copied to the agent at launch               │
│   Theme               Railway                    │
│      Previews as you cycle                       │
│   Run first-time setup again                     │
│                                                  │
│   ↑↓ choose  ←→ change  enter edit  esc close    │
╰──────────────────────────────────────────────────╯
  • Agent, skills, theme cycle in place with / (enter also steps forward). The theme repaints the whole screen as it cycles, like the wizard's theme step.
  • Every change saves immediately, merged over the prefs file on disk so the skills exclude list survives; esc is only ever "close" — no dirty state, no confirm.
  • Default project opens a sub-picker (the wizard's project question: existing projects, "create a project" incl. the async create + spinner/error handling, "decide later" to clear the default) and returns straight to the card.
  • A last row replays first-run setup for anyone who wants the guided walk. The wizard itself is unchanged and remains the first-run flow.

Retired

  • ⌥t is gone — the theme now lives (and persists, which ⌥t never did) on the settings card. Its composed form falls through as plain text like any unclaimed Option-character.
  • Footer chords read ⌥s settings instead of ⌥t theme · ⌥s setup.

Implementation

  • New tui/settings.rs model mirroring wizard.rs's shape (Action enum, busy/error, narrative tests); reuses wizard::Outcome/ProjectOption and newly-extracted project_options()/harness_blurb().
  • New Screen::Settings + Effect::SaveSettings, handled in the event loop next to SaveSetup; Message::ProjectCreated now routes to whichever of wizard/settings is open.
  • Rendering reuses render_panel; the one shared tweak is that a row's dim tag brightens while its row is selected.
  • App gains skills_enabled, mirrored from prefs at startup so the card opens showing the saved answer.

Testing

  • cargo test cloud_agent: 256 passed (includes new settings model, key-routing, and draw tests).
  • cargo fmt --check, cargo clippy: clean in touched files.
  • Full suite: the only failures are the 3 pre-existing auth_sim tests, which also fail on a clean origin/master checkout in this environment (they pick up the machine's real Railway credentials).

Also: ⌥esc replaces shift+esc

Standardizing the TUI's own chords on one modifier family (⌥f, ⌥], ⌥s, ⌥esc): releasing a focused session is now ⌥esc / ^] instead of shift+esc / ^]. The trade is symmetric — both spellings require the enhanced keyboard protocol to be reportable at all (a plain terminal folds either into a bare Escape meant for the agent, and crossterm parses classic ESC ESC as plain Esc), so ^] and ^o remain the universal fallbacks. One platform note: Alt+Esc is an OS shortcut on Windows, where ^] is the way out.

Also: ⌥enter replaces shift+enter for full screen

shift+enter is the newline every text field gives you, and the harnesses running in a session bind it that way — so the TUI shouldn't reserve it. "Leave the TUI and connect full screen" moves to ⌥enter, joining the same family; f stays as the fallback for terminals that send no modifier with Enter.

⌥enter is actually more reportable than the chord it replaces: a terminal with Option-as-Meta sends ESC CR, which crossterm parses as Alt+Enter with no enhanced keyboard protocol needed, whereas shift+enter strictly required it.

Note this binding only ever fired with the tree focused — a focused session already forwards everything except ⌥f/⌥]/the release chords — so this is about which key the TUI reserves, not about what the pane passes through. A test now pins shift+enter as unclaimed from either focus.

Follow-up worth a separate PR

Freeing the binding is necessary but not sufficient for shift+enter to insert a newline in an embedded pane. session::encode_key currently discards the shift modifier (let _ = shift;) and encodes Enter as a bare \r regardless, so a harness inside the pane sees shift+enter and plain enter as the same byte and submits. Making it a newline means encoding it distinguishably — either kitty CSI-u (\x1b[13;2u, only understood if the harness negotiated that protocol, and literal garbage if it didn't) or translating it to ESC CR, the alt+enter newline chord harnesses already accept. That's a change to what bytes reach the agent, so it isn't bundled here. Full-screen sessions are unaffected either way — they bypass the emulator entirely.

@codyde codyde added the release/minor Author minor release label Aug 10, 2026
codyde added a commit that referenced this pull request Aug 11, 2026
Stacking #1069 on #1072 crosses three changes:

harness_blurb gains the railway arm. The extracted helper had `_ =>
"xAI's Grok"` as its catch-all, and with railway now leading HARNESSES
that fallback would have labelled Railway's own agent as Grok. Every
harness is named, and the catch-all says nothing rather than guessing.

The settings card's "create a project" row carries a workspace, since
CreateDefaultProject now takes one. It lists one row per workspace —
identical wording with a single workspace, named with several — rather
than defaulting to the first, which is the bug #1072 set out to fix.

The menu footer drops both `^t` (onto the target line, #1072) and `⌥t`
(onto the settings card, #1069), leaving `⌥s settings`.
@codyde
codyde force-pushed the railway/settings-menu branch from 2e58116 to afa9c4f Compare August 11, 2026 04:53
@codyde
codyde changed the base branch from master to railway/ca-workspace-first-onboarding-and-railway-agent August 11, 2026 04:53
@codyde
codyde force-pushed the railway/ca-workspace-first-onboarding-and-railway-agent branch from 1acc18b to 0afa4b1 Compare August 11, 2026 04:57
codyde added a commit that referenced this pull request Aug 11, 2026
Stacking #1069 on #1072 crosses three changes:

harness_blurb gains the railway arm. The extracted helper had `_ =>
"xAI's Grok"` as its catch-all, and with railway now leading HARNESSES
that fallback would have labelled Railway's own agent as Grok. Every
harness is named, and the catch-all says nothing rather than guessing.

The settings card's "create a project" row carries a workspace, since
CreateDefaultProject now takes one. It lists one row per workspace —
identical wording with a single workspace, named with several — rather
than defaulting to the first, which is the bug #1072 set out to fix.

The menu footer drops both `^t` (onto the target line, #1072) and `⌥t`
(onto the settings card, #1069), leaving `⌥s settings`.
@codyde
codyde force-pushed the railway/settings-menu branch from afa9c4f to 7ccbd80 Compare August 11, 2026 04:57
@codyde
codyde changed the base branch from railway/ca-workspace-first-onboarding-and-railway-agent to master August 11, 2026 05:05
@codyde codyde closed this Aug 11, 2026
@codyde codyde reopened this Aug 11, 2026
codyde added a commit that referenced this pull request Aug 11, 2026
Stacking #1069 on #1072 crosses three changes:

harness_blurb gains the railway arm. The extracted helper had `_ =>
"xAI's Grok"` as its catch-all, and with railway now leading HARNESSES
that fallback would have labelled Railway's own agent as Grok. Every
harness is named, and the catch-all says nothing rather than guessing.

The settings card's "create a project" row carries a workspace, since
CreateDefaultProject now takes one. It lists one row per workspace —
identical wording with a single workspace, named with several — rather
than defaulting to the first, which is the bug #1072 set out to fix.

The menu footer drops both `^t` (onto the target line, #1072) and `⌥t`
(onto the settings card, #1069), leaving `⌥s settings`.
@codyde
codyde force-pushed the railway/settings-menu branch from 7ccbd80 to 04e4ed8 Compare August 11, 2026 05:15
@codyde codyde removed the release/minor Author minor release label Aug 11, 2026
@codyde codyde added the release/skip Author no release label Aug 11, 2026 — with Railway App
@codyde
codyde changed the base branch from master to railway/ca-workspace-first-onboarding-and-railway-agent August 11, 2026 05:29
@codyde
codyde force-pushed the railway/ca-workspace-first-onboarding-and-railway-agent branch from 8c563ef to 3da2073 Compare August 11, 2026 05:52
Base automatically changed from railway/ca-workspace-first-onboarding-and-railway-agent to master August 11, 2026 05:54
codyde and others added 4 commits August 11, 2026 05:54
⌥s used to replay the whole first-run wizard, and ⌥t cycled the theme
blind — two chords, one of them a four-step flow, to change one answer.

⌥s now opens a settings card showing every preference from
agent-prefs.json with its current value: coding agent, default project,
skills sync, and theme. Values with a handful of options cycle in place
with ←/→ and save on every change (merged over the file on disk, so the
skills exclude list survives). The theme applies to the whole screen as
it cycles, exactly like the wizard's theme step, which is why ⌥t
retires. The default project opens the wizard's project question as a
sub-card — including "create a project" and "decide later" — and comes
straight back. A last row replays first-run setup for anyone who wants
the guided walk.

The wizard itself is unchanged and remains the first-run flow.
One modifier family for the TUI's own chords: ⌥f, ⌥], ⌥s, and now ⌥esc
to stop typing in a session. The trade is symmetric — both spellings
need the enhanced keyboard protocol to be reportable at all, and both
degrade to a bare Escape without it, which is why `^]` and `^o` keep
working everywhere.
shift+enter is the newline every text field gives you, and the harnesses
running in a session bind it that way. Claiming it for "leave the TUI
and connect full screen" meant the TUI took a key the agent needed.

Full screen moves to ⌥enter, joining the ⌥ family the other chords now
use. `f` stays as the fallback for terminals that send no modifier with
Enter — and ⌥enter needs one less than shift+enter did: a terminal with
Option-as-Meta sends ESC CR, which parses as Alt+Enter without the
enhanced keyboard protocol shift+enter required.

The binding only ever fired with the tree focused, so this is about
which key the TUI reserves rather than what a focused pane forwards; a
test now pins shift+enter as untouched from either focus.
Stacking #1069 on #1072 crosses three changes:

harness_blurb gains the railway arm. The extracted helper had `_ =>
"xAI's Grok"` as its catch-all, and with railway now leading HARNESSES
that fallback would have labelled Railway's own agent as Grok. Every
harness is named, and the catch-all says nothing rather than guessing.

The settings card's "create a project" row carries a workspace, since
CreateDefaultProject now takes one. It lists one row per workspace —
identical wording with a single workspace, named with several — rather
than defaulting to the first, which is the bug #1072 set out to fix.

The menu footer drops both `^t` (onto the target line, #1072) and `⌥t`
(onto the settings card, #1069), leaving `⌥s settings`.
@codyde
codyde force-pushed the railway/settings-menu branch from 04e4ed8 to 2007c25 Compare August 11, 2026 05:56
@codyde
codyde merged commit 2153ac3 into master Aug 11, 2026
7 checks passed
@codyde
codyde deleted the railway/settings-menu branch August 11, 2026 05:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release/skip Author no release

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant