feat(ui): onboarding, Settings screen and host picker #32

Merged
deadstyle merged 20 commits from feature/24-onboarding-settings into develop 2026-10-02 20:56:56 -05:00
Owner

Summary

First-run onboarding, a Settings screen (S) and a host picker (navigation level 0), so lazyforge can be set up and reconfigured without editing the config file.

Changes

  • Server check and Renovate suggestion: a token-free probe identifies Forgejo vs Gitea, and onboarding suggests the Renovate bot from open renovate/* PRs.
  • App root: host picker with + Add host (sorted by name, cursor on the last-used host), h back to it, S for Settings, session switching that drops results from the old host, ordered config saves, last-used host remembered. The latest pick always supersedes an in-flight connect.
  • Onboarding steps 1–7: masked token, permission list (read:user, write:repository, write:issue), connection test, name suggestion, edit-from-server-step for existing hosts.
  • Settings: hosts (add, edit, set default, remove with confirm; removing the connected host is refused), update-check toggle, "only merge when green" per host and per repo, saved immediately.
  • Startup wiring: no config opens onboarding, the picker shows when no single host is selected; --demo never touches config.
  • Docs: ADR 0012, architecture UI section, design.md step 4 permission list.

Test plan

  • make check: format, golangci-lint (0 issues), go test -race ./... (all packages ok), govulncheck, build — pass locally; shellcheck runs in CI (not installed locally, no shell scripts changed).
  • Backfilled tests per package (ui, cmd, gitea/core/config), each mutation-checked: picker order/cursor, stale-connect handling, live green-CI flag through Settings including per-repo overrides, cancelled Renovate scans, error wrapping, remove refusal, ordered 0600 saves, probe edge cases, config.Clone deep copy.
  • Reviews: spec and standards axes passed after three fix rounds; comments/test-quality review passed.

Closes #24

🤖 Generated with Claude Code

## Summary First-run onboarding, a Settings screen (`S`) and a host picker (navigation level 0), so lazyforge can be set up and reconfigured without editing the config file. ## Changes - **Server check and Renovate suggestion:** a token-free probe identifies Forgejo vs Gitea, and onboarding suggests the Renovate bot from open `renovate/*` PRs. - **App root:** host picker with **+ Add host** (sorted by name, cursor on the last-used host), `h` back to it, `S` for Settings, session switching that drops results from the old host, ordered config saves, last-used host remembered. The latest pick always supersedes an in-flight connect. - **Onboarding steps 1–7:** masked token, permission list (`read:user`, `write:repository`, `write:issue`), connection test, name suggestion, edit-from-server-step for existing hosts. - **Settings:** hosts (add, edit, set default, remove with confirm; removing the connected host is refused), update-check toggle, "only merge when green" per host and per repo, saved immediately. - **Startup wiring:** no config opens onboarding, the picker shows when no single host is selected; `--demo` never touches config. - **Docs:** ADR 0012, architecture UI section, design.md step 4 permission list. ## Test plan - `make check`: format, `golangci-lint` (0 issues), `go test -race ./...` (all packages ok), govulncheck, build — pass locally; shellcheck runs in CI (not installed locally, no shell scripts changed). - Backfilled tests per package (ui, cmd, gitea/core/config), each mutation-checked: picker order/cursor, stale-connect handling, live green-CI flag through Settings including per-repo overrides, cancelled Renovate scans, error wrapping, remove refusal, ordered 0600 saves, probe edge cases, `config.Clone` deep copy. - Reviews: spec and standards axes passed after three fix rounds; comments/test-quality review passed. Closes #24 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Probe reads /api/v1/version without a token; SuggestRenovateUser scans
the 10 most recently active repos for a renovate/ branch.

#24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Adds ui.App above the session model: start screen selection, the host
picker with + Add host, S/h interception, generation-stamped session
messages, live green-CI config, ordered config saves and last_host.
Onboarding and Settings are compiling stubs for wave 2. Adds
config.Config.Clone, ADR 0012 and the architecture UI notes.

#24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Replaces the onboarding stub: forge type, address probe, sign-in with
token or token_cmd, connection test, Renovate suggestion and host name,
with every async result checked against the inputs it was started for.
Records the token permission list in design.md step 4.

#24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Part of #24 (S4).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Refs #24. appDeps replaces realService; a missing config starts fresh
onboarding and several hosts without a default defer to the picker.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Share newHelp and renderStatusBar between Model and App, give the HOSTS,
SETTINGS and SETUP badges their own styles, send the window size to
onboarding opened after startup, and hide the h/S hints on a session
model that no App hosts (--demo).

Refs #24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Lint fixes (contextcheck, ineffassign, revive), failure reasons wrapped to the
frame width, the picker message names the host and innermost cause, unused
view params and newSettings removed, step 4 mentions closing PRs.

#24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Reopen the picker on the current host when pressing h from a session, so
enter returns to it. Factor the gg prefix into one helper used by the
model, picker and settings. Ignore cancelled Renovate scans, keep the
user in Settings when a picker connect lands, drop redundant Enter
matches, share the add-host row and host meta, name the hosted-session
key gate, use the PM refusal text, split the state path handling in
main, and trim name-restating comments.

#24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Picking the current host, opening + Add host, or removing the host now
drops a connect still in flight, and the Remove confirm re-checks the
active host.

#24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#24: --config tolerates a failing default-paths lookup, no --config
errors, StatePath and LastHost come from defaults, corrupt state is
tolerated.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Covers + Add host and Edit from Settings, not just the picker's row.

#24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
#24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
test: drop a duplicated clone test and tighten two assertions
All checks were successful
ci / check (pull_request) Successful in 3m16s
8bf8ab518b
#24

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
deadstyle merged commit 6e08f15016 into develop 2026-10-02 20:56:56 -05:00
deadstyle deleted branch feature/24-onboarding-settings 2026-10-02 20:56:56 -05:00
Sign in to join this conversation.
No description provided.