Skip to content

ui: lead the launcher with the prompt and one configuration line - #131

Merged
hbrooks merged 1 commit into
mainfrom
ui/launcher-prompt-first
Aug 23, 2026
Merged

ui: lead the launcher with the prompt and one configuration line#131
hbrooks merged 1 commit into
mainfrom
ui/launcher-prompt-first

Conversation

@hbrooks

@hbrooks hbrooks commented Aug 23, 2026

Copy link
Copy Markdown
Member

Important

Restructures the launcher's layout: the prompt now leads, followed by a one-line configuration summary, then the session list, with the "connected to" line moved to the bottom.

  • Launcher layout now leads with the prompt as the first actionable row, where ↓ descends to a summary line that shows what the next run will use (model, repo count, custom Dockerfile, environment variables).
  • Configuration editor swaps in place of the session list when you press enter on the summary line, so you can change model/repos without growing the launcher height.
  • Token display removed from session rows — compactTokens() deleted, rowMeta() now shows only cost and age, never token counts.
  • UI test suite removedtest/screenshot.test.ts, test/connect-render.test.ts, test/scrollback.test.ts and their snapshots deleted; @xterm/headless dependency removed. Added CLAUDE.md documenting that tests must cover pure functions only, not UI rendering.
  • New configSummary() function reads the saved config's Dockerfile and variables (which the pickers can't reach directly) and the current model/repo picks to produce a one-line summary.

This description was created by Ellipsis for 2c32688. It will automatically update as commits are pushed.

The prompt was buried under a who-line and three settings rows, so the
first thing on screen was chrome rather than the thing you came to do. It
now opens the block, with one summary line under it naming what the next
run will use and carrying the way into changing it. The editor takes the
session list's place, so the block's height never depends on which is up.

Also drop every UI-rendering test: tests here are unit tests, so the
launcher's summary logic moved into configSummary() and is tested there.
@hbrooks
hbrooks merged commit f46fcd5 into main Aug 23, 2026
1 check passed

@ellipsis-dev ellipsis-dev Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Changes requested ❌ — 2 issues

Reviewed 2c32688 in 4 minutes, 50 seconds.
  • Reviewed 1 commit with 534 lines of code in 11 files
  • Ran 1 review agent producing 2 comments where 2 were posted
  • This pipeline runs no gatekeeper, so findings are posted as written.
  • View full details on ellipsis.dev

This review was created by Ellipsis. You can tag @ellipsis in this pull request.

Comment thread src/ui/SessionsApp.tsx
Comment on lines +909 to +912
const pickedModelLabel = modelOptions[modelIdx]?.label ?? null
const summary = configSummary({
model: pickedModelLabel === 'Default' ? null : pickedModelLabel,
repos: repoSel === null ? null : [...repoSel],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The summary line names the account-default model even when the selected Agent config declares its own claude.model, so it reports a model the run will not use; the config's model should win whenever the Model row is untouched (modelPick === null).

With GET /models returning a model flagged is_default_agent_model, composerModelOptions gives that row the null id but its raw id as the label, so an untouched Model row makes pickedModelLabel a real id (e.g. claude-opus-5), never the string Default. configSummary therefore takes input.model and never reaches its agentConfig.claude.model fallback. Pick an Agent config whose YAML sets claude: {model: claude-haiku-4-5-20251001}, leave the Model row alone: submit() sends no model override (modelOptions[modelIdx].id is null), the server resolves haiku from the config, and the launcher line says claude-opus-5. Note the repos bit gets this precedence right — untouched means null, and the config's environment.repositories answers. Fix needs both ends: pass model: modelPick === null ? null : pickedModelLabel and give configSummary a defaultModel argument it falls back to after the config's own model, so the untouched-row-with-no-config case still names the account default.

Comment thread src/ui/SessionsApp.tsx
setCursor({ kind: 'prompt' })
return
}
if (ch && !key.ctrl && !key.meta) toPromptWith(ch)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Typing while the editor is open moves the cursor to the prompt but leaves editing true, so the session list stays hidden and the esc: back to your sessions hint below it does nothing — setEditing(false) belongs in toPromptWith.

Press ↓, enter (editor opens), then type any character: toPromptWith sets the cursor to prompt while editing stays true, so showList is false and the status line still reads esc: back to your sessions (line 926). At the prompt, esc hits if (key.escape || key.ctrl || key.meta || key.tab) return and is a no-op, so the list only comes back by pressing ↓ and then esc.

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