Skip to content

chat: onboarding answers the pointer and a second enter, no telemetry notice or command, and free models only on a low account - #1720

Open
ZeroPoint95 wants to merge 16 commits into
devfrom
zeropoint95/onboarding-ux-cleanups
Open

ZeroPoint95 wants to merge 16 commits into
devfrom
zeropoint95/onboarding-ux-cleanups

Conversation

@ZeroPoint95

@ZeroPoint95 ZeroPoint95 commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Santosh's first-run notes from 2026-09-30, the non-Teams half (Notion), plus the owner's follow-ups on the same screen. Every item below is in docs/changes/unreleased/1720-onboarding-ux-cleanups.md as an invalidates line; the manual's getting-started, openrouter-credits and running-from-the-terminal pages follow it.

1. The interactive menus

  • The welcome screen's starting points took every enter. The first enter filled the box; the second, the one that sends, was still taken by the list and sent nothing. With words in the box, enter is the composer's: ↓ enter enter sends.
  • The setup's controls screen swallowed every mouse press. Rows now answer a press the way the key would (limit focuses, chat model opens the list, a model in the list is taken, Start a conversation leaves); the wheel scrolls the open list.
  • Enter goes on. After a model is taken the focus moves to the next row, so enter alone walks the whole form.

2. Telemetry

  • The usage-counts notice no longer appears on the first conversation's screen, ahead of --once, or ahead of a task; the "nothing sent until shown" gate goes with it.
  • codeaf telemetry (status, info, show, on, off) is removed. The disclosure is the README's Telemetry section and docs/TELEMETRY.md, held to the switches by the telemetry package's doc test. The switches are unchanged: /settings telemetry toggle, CODEAF_TELEMETRY=off, DO_NOT_TRACK=1, the project file, an empty endpoint.

3. OpenRouter account state

  • Low balance: the setup's model list is cut to free rows (:free ids and zero-priced catalog rows) and says free only; the model in use stays on the list. The warning stands right-aligned on the frame's last row, where the keys row carries it outside the setup.
  • Expired key (new): a balance read answered API key expired is a reading of its own (credits.Reading.Expired, kept beside low in credits.json). Your OpenRouter key has expired — make a new one at openrouter.ai/settings/keys stands under the message box in a conversation and on Home for every OpenRouter model, free included; the setup says it on its last row; a turn refused as expired asks for a fresh read through provider.APIError.KeyExpired (the taxonomy law forbids reading the status in the surface); the free defaults are not used for it.

4. The controls screen itself (owner's follow-ups)

  • One column: the example panel on top (up to 92 cells, whole or not at all), two blank rows, the heading Basic settings, the keys line directly under it, then the rows. The old two-column layout, Models and spending + lead sentence, and the panel's An illustration… foot line are gone.
  • The panel's edge carries the example's title; a fifth example, Hand off complex coding tasks, asks /senior-dev …; commands in requests, explanations and the note wear the composer's chip.
  • The panel turns on its own clock: opens on 1/5, next every 3 s round the ring; ←/→ browse; any key holds the clock 3 s; the focus never moves it; the screen-reader tier never turns by itself.
  • Row names: body ink until answered, accent while focused, dim once enter has acted. Keys line: enter sets the limit · ↑↓ moves · …, no tab moves, no ←→ examples. The loose enter beside Start a conversation is gone.
  • The review row (Other settings use defaults · review) is removed; a dim note Everything else is in /settings stands under the way out.
  • The model list is a flat list of exact ids. The limit's explanation names /budget, the model's /model; ? on the limit explains the day's and the conversation's ceilings and how they meet.

Proof

  • Tests cover every item above (internal/tui3, internal/credits, internal/config, internal/provider, internal/telemetry, cmd/codeaf), the manual gate has new probes, the untagged internal/e2e needle gate and make test-laws are green, and make test-quick is green on the branch head.
  • Verified by hand in tmux against a fresh home: clicks on every row, the welcome without the notice, ↓ enter enter sending, the one-column layout at 130×40 and its fallback at 120×24, the panel turning on its clock and holding on keys, the chips in the capture's escape bytes, and the expired-key warning on the welcome screen against a local stub.
  • Not seen by hand: the low-credits and expired-key lines on the setup's last row (the paste-a-key road needs a reachable OpenRouter); their placement is pinned by unit tests.
  • make pr-ready has not been run on this branch.

Open question left to the owner: the ←/→ glyphs read as asymmetric in the terminal font; every mirror-image alternative is a vocabulary glyph with another meaning, so they were left as they are.

A Linux arm64 build of the head is packaged as a Docker image for first-run trials (docker run -it --rm codeaf-onboarding); the Dockerfile lives outside the repository.

🤖 Generated with Claude Code

ZeroPoint95 added a commit that referenced this pull request Oct 1, 2026
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@ZeroPoint95
ZeroPoint95 marked this pull request as draft October 1, 2026 15:22
ZeroPoint95 added a commit that referenced this pull request Oct 1, 2026
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@ZeroPoint95
ZeroPoint95 force-pushed the zeropoint95/onboarding-ux-cleanups branch from 6bff8fc to 8576e80 Compare October 1, 2026 20:10
ZeroPoint95 and others added 16 commits October 1, 2026 16:52
… notice or command, and free models only on a low account

Santosh's first-run notes (2026-09-30), the non-Teams half.

- The welcome screen's starting points took every enter: the first filled
  the box, the second did nothing — four of five new people read that as
  enter not working. With words in the box, enter is the composer's.
- The Models and spending screen swallowed every press; its rows now act
  like the key they stand for (a press on the model row opens the list, on
  a model takes it, on Start leaves), the wheel scrolls the open list, and
  enter goes on after a model is taken or a review is shown, so enter
  alone walks the whole form.
- The six-line usage-counts notice is gone from the first conversation's
  screen, from --once and from task commands, and the send gate on it with
  it; `codeaf telemetry` (status, info, show, on, off) is removed. The
  disclosure is README.md and docs/TELEMETRY.md; the switches are the
  settings sheet's telemetry row, CODEAF_TELEMETRY, DO_NOT_TRACK and the
  project file, unchanged.
- While the OpenRouter account reads low, the setup's chat-model list is
  cut to free rows, says `free only`, and a line under the field says why.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…message box and on the setup screen

A balance read that OpenRouter answered with `API key expired` was a failed
read: nothing recorded, nothing said, and the next turn failed with a plain
auth error. The 401 that says expired is now a reading of its own
(credits.Reading.Expired, kept beside low in credits.json): `Your OpenRouter
key has expired — make a new one at openrouter.ai/settings/keys` stands at
the right of the keys row in a conversation and on Home for every model the
default service serves, free included, and under the chat model on the
setup screen, where the list is not cut because the free rows fail on the
same key. A turn refused as expired asks for a fresh read, through a fact
stamped on the provider's refusal (APIError.KeyExpired) so no surface reads
the status for itself. A new key clears it before it is read.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… window allows

The example was a second column beside the form, 36 cells wide, drawn
from 112 columns up and level with the first field: on a tall window the
lower half of the screen stayed empty while the panel wrapped every
sentence three ways. It is one column now — the form, its keys line, one
blank row, then the panel at up to 92 cells, whole or not at all. A window
with no rows to spare under the form draws the form alone and the keys
line stops naming the arrows. The form is 64 cells on every window.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ts title on its edge, and shows a /senior-dev hand-off

Under the form, the legend stood between the form and the panel and read
as a caption for the wrong one. The order is now the panel, two blank
rows, the keys line, and the form directly under it. The panel's top edge
reads `○ Example · <the example's title>` and the title is no longer a row
of the body. A fifth example, `Hand off complex coding tasks`, asks
`/senior-dev Add retries with backoff to the HTTP client, with tests.`
beside `Start a conversation`, and a command in any example's request
wears the composer's chip. The keys line says `enter sets the limit` on
the limit row and `↑↓ moves` in place of `tab moves` everywhere; the tmux
suite's needle follows it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…t, the panel loses its foot line, and the account's warning rides the frame's foot

`Models and spending` over `Keep these choices or change them.` is one
line, `Basic settings`, and the keys line is the row directly under it
rather than the foot of the form. The keys line no longer names the
example's arrows: the panel's own bottom edge carries them. The panel no
longer ends on `An illustration. Nothing here has run.`; its `Example`
label says that once. The low-credits and expired-key lines leave the
chat-model row and stand right-aligned on the frame's last row, where the
keys row carries the same warning outside the setup; the expired-key line
is shortened to fit any window the panel fits.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…grey once answered, white until then

`→` on the last example is the first again, and `←` on the first the
last. Every row's name — the limit, the chat model, the review, the way
out — is painted by one rule: the accent while the focus is on it, dim
once enter has acted on it (the limit set, a model taken from the list,
the review shown), and the body ink until then. Opening the list and
leaving it with esc answers nothing.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Each row was the catalog's friendly name with the exact id drawn under
the cursor's row, which read as a heading with a subheading and made the
one row a person could act on two rows tall. Each row is the id now, one
row per model; typing still finds a model by its friendly name and the
field above still shows it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…t points at /settings

`Other settings use defaults · review` showed three settings and let
nobody change them — a door painted on a wall, and people pressed on it.
The form is three rows now: the limit, the chat model, the way out. Under
`Start a conversation` one dim line reads `Everything else is in
/settings`, with the command painted as the composer's chip.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…ut carries no loose enter

The limit's line ends `/budget changes it later.` and the chat model's
`/model changes it later.`, each command painted as the composer's chip
the way the note's /settings is. The dim `enter` at the right of `Start a
conversation` is gone: the keys line under the heading already says
`enter starts` when the focus is there.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…and never follow the focus

The panel followed the focused row, which read as it jumping about under
a person walking the form. It opens on the first example and turns to
the next every three seconds, round the ring; ←/→ browse by hand; any
key — typing, walking the rows, browsing, a press — holds the clock for
a full three seconds from that key; the screen-reader tier never turns
by itself. Each arriving example plays its demonstration once.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…n's ceilings

`?` on the Daily limit row now says what the two ceilings are and how
they meet: /budget 50 changes the day's and /budget none removes it;
/budget conversation 20 gives the open conversation a smaller ceiling of
its own and keeps it as the default for new ones; both hold at once and
whichever is reached first stops the work — the day's everything until
midnight, the conversation's just that conversation; the running turn
always finishes. Each /budget wears the composer's chip.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…on the list

TestModelNamesReadAsNamesAndKeepTheirLevel still expected the open list to
draw "DeepSeek V4 Flash", which the flat list of exact ids stopped doing on
purpose; it now asserts the two halves that hold — the field row and the
typed search speak the friendly name, every row of the open list is the
exact id — and leaves the flat shape itself to the test that owns it.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… the setup's prose catches up

The setup's foot said "esc to paste a new one" on every frame, while the keys
line two rows up said "esc skips setup" whenever the controls step stood
alone — a key already in the shell or the profile, only the controls asked.
The line is now chosen by the same rule as the keys line: with a connect
step before it, esc goes back there; standing alone, it names /connect as
the door to a new key. A test pins the alone case on the same frame.

The manual stops listing the review row's enter verbs (`shows them`, `goes
on`) and stops saying the setup shows memory, permissions and the countdown
under `Other settings`; both pages that explained esc on an expired key say
the conditional thing.

The comments the redesign left behind say what is true now: the example
turns on a clock and the focus never moves it, the panel stands above the
form, the edge label — not a foot line — is what says it is an illustration,
and `codeaf telemetry show` is spoken of as the command that went.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@ZeroPoint95
ZeroPoint95 force-pushed the zeropoint95/onboarding-ux-cleanups branch from 297c81a to 1580bb7 Compare October 1, 2026 20:54
@ZeroPoint95
ZeroPoint95 marked this pull request as ready for review October 1, 2026 21:12
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