Skip to content

feat(app): composer and model selector polish#223

Merged
Astro-Han merged 3 commits into
devfrom
feat/composer-polish-trio
Apr 24, 2026
Merged

feat(app): composer and model selector polish#223
Astro-Han merged 3 commits into
devfrom
feat/composer-polish-trio

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Apr 24, 2026

Copy link
Copy Markdown
Owner

Summary

Three small polish commits bundled into one PR:

  • [Feature] Redesign home composer default placeholder for non-technical users #176 — Swap 25 developer-oriented home placeholder prompts for non-technical workbench scenarios (email / Excel / PDF / text cleanup / summary-translate). Simplify placeholder shell from "Ask anything" / "随便问点什么" to "Try" / "试试" so the example leads the glance. zh and en pools are locale-native, not mirror translations.
  • [Feature] Show image-capability tag in model selector list #218 — Add plain-text 图片 / Image Tag to the model picker list item so image-capable models are scannable at a glance. Position: free -> Image -> latest, capped at 2 tags with priority free > Image > latest. Uses the existing modelSupportsInput helper from attachment-routing.ts. Layout: text-left + min-w-0 truncate on name span, shrink-0 rounded-full! on Tags so pills stay pill-shaped on narrow rows.
  • [Bug] Focus ring inconsistent across composer chips and input surfaces #215@opencode-ai/ui Button ghost variant had outline: none from base with only a hover-like background on :focus-visible — so model chip, + attachment, and every ghost button across the app lacked a visible keyboard focus ring. Restore outline: auto + outline-color: -webkit-focus-ring-color on ghost :focus-visible, so composer chips now render the same system blue ring as native buttons (variant chip, workspace chip, skills pills).

Why

Related Issue

Closes #176
Closes #218
Closes #215

How To Verify

bun --cwd packages/app typecheck
bun --cwd packages/app test:e2e:local -- e2e/models/models-visibility.spec.ts --grep "surfaces image-capable tag"
bun --cwd packages/app test:e2e:local -- e2e/app/a11y-chip.spec.ts

Manual (Electron via bun run dev:desktop):

  • Home composer placeholder rotates non-technical prompts in zh and en; Try... / 试试... prefix applied
  • Open model picker: 图片 / Image tag shows on image-capable models; text-only models do not; Tag is pill-shaped, no horizontal scroll
  • Tab through composer (attachment + → model chip → variant chip → workspace chip → send): all render consistent blue focus ring; also matches skills pills on home

Screenshots or Recordings

(to add after push — focus ring before/after + model picker with Image tag)

Checklist

  • I linked the related issue, or stated why there is no issue
  • This PR has type, scope, and priority labels, or I requested maintainer labeling
  • I listed the relevant verification steps, including tests when behavior changed
  • I manually checked visible UI or copy changes when needed, with screenshots or recordings
  • I considered macOS and Windows impact for desktop, packaging, updater, signing, paths, shell, or permissions changes (CSS change renders identically on Chromium, macOS verified on-device; Windows left to CI)
  • I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, or generated/local file changes when relevant
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English

Summary by CodeRabbit

  • New Features

    • Model list now displays capability tags indicating features like Image support.
    • Prompt suggestions refreshed with writing and document-focused examples.
  • Style

    • Updated prompt placeholder text from "Ask anything..." to "Try...".
    • Improved button focus ring visibility on interactive elements.

Replace 25 developer-oriented prompt.example.N entries with non-technical
workbench scenarios covering email/writing, spreadsheets/data, PDF/documents,
text cleanup, and summary/translation. zh and en pools are locale-native, not
mirror translations. Also simplify the placeholder shell from "Ask anything"
/ "随便问点什么" to "Try" / "试试" so the example prompt leads the glance.
Parity test continues to pass (key count preserved).

Closes #176
Add plain-text "图片"/"Image" Tag next to free/latest in the model
selector list item so image-capable models are scannable at a glance.
Position: free -> Image -> latest, capped at 2 tags per row with
priority free > Image > latest. Uses existing modelSupportsInput
helper for detection (same source of truth as attachment routing).
Layout: row uses text-left so name does not inherit the list-item
button's text-align: center; span has min-w-0 truncate; tags have
shrink-0 and rounded-full to stay pill-shaped even on narrow rows.

Closes #218
Button base has outline: none, and ghost variant only changed
background-color on :focus-visible (no border, shadow, or outline).
So composer model chip, attachment "+" button, and every ghost button
across the app lacked a visible keyboard focus ring — keyboard users
tabbing through the composer lost track of focus. Native <button>
elements (variant chip, workspace chip, skills pills) already render
the browser default blue outline.

Restore outline: auto on ghost :focus-visible so every @opencode-ai/ui
Button ghost renders the same browser default focus ring as native
buttons — consistent a11y across the app with a single CSS line.

The original issue described "workspace chip" but on-device verification
showed workspace chip already had native blue outline; the actually
missing ring was on model chip and attachment + button (both ghost
Buttons). Fixing the shared ghost variant covers both.

Closes #215
@Astro-Han Astro-Han added enhancement New feature or request P2 Medium priority ui Design system and user interface labels Apr 24, 2026
@coderabbitai

coderabbitai Bot commented Apr 24, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: a757fb34-199f-498b-95aa-1739f4c08eff

📥 Commits

Reviewing files that changed from the base of the PR and between c0634e1 and 19f89fb.

📒 Files selected for processing (5)
  • packages/app/e2e/models/models-visibility.spec.ts
  • packages/app/src/components/dialog-select-model.tsx
  • packages/app/src/i18n/en.ts
  • packages/app/src/i18n/zh.ts
  • packages/ui/src/components/button.css
📜 Recent review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (12)
  • GitHub Check: unit-opencode
  • GitHub Check: unit-desktop
  • GitHub Check: unit-windows-desktop
  • GitHub Check: unit-app
  • GitHub Check: unit-windows-opencode-session
  • GitHub Check: unit-windows-app
  • GitHub Check: unit-windows-opencode-server-tools
  • GitHub Check: unit-windows-opencode-config-project
  • GitHub Check: typecheck
  • GitHub Check: smoke-macos-arm64
  • GitHub Check: analyze-js-ts
  • GitHub Check: e2e-artifacts
🧰 Additional context used
📓 Path-based instructions (2)
packages/app/**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (packages/app/AGENTS.md)

Always prefer createStore over multiple createSignal calls in SolidJS

Files:

  • packages/app/e2e/models/models-visibility.spec.ts
  • packages/app/src/i18n/en.ts
  • packages/app/src/components/dialog-select-model.tsx
  • packages/app/src/i18n/zh.ts
packages/app/e2e/**/*.spec.ts

📄 CodeRabbit inference engine (packages/app/e2e/AGENTS.md)

packages/app/e2e/**/*.spec.ts: Import test utilities from ../fixtures instead of @playwright/test
Test files should be named with the pattern feature-name.spec.ts
Use lowercase, descriptive test names (e.g., 'sidebar can be toggled')
Use camelCase for variable names in tests
Use SCREAMING_SNAKE_CASE for constants in tests
Use fixture-managed cleanup with withSession(sdk, title, callback) for temporary sessions instead of calling sdk.session.delete(...) directly
Prefer the project fixture for tests that need a dedicated project with LLM mocking
Use data-component, data-action, or semantic roles for selectors instead of CSS class names or IDs
Use modKey from utils for cross-platform keyboard shortcuts (Meta on Mac, Control on Linux/Windows)
In terminal tests, type through the browser using runTerminal() and waitTerminalReady() instead of writing to the PTY through the SDK
Never use wall-clock waits like page.waitForTimeout(...) to make a test pass
Wait on observable state with expect(...), expect.poll(...), or existing helpers instead of assuming work is finished after an action
Use locator assertions like toBeVisible(), toHaveCount(0), and toHaveAttribute(...) for normal UI state verification
Use expect.poll(...) for probing mock or backend state rather than transient DOM visibility
Prefer fluent helpers and drivers when they make intent obvious and reduce locator-heavy noise in tests
Use direct locators when the interaction is simple and a helper would not add clarity
When validating routing, assert against canonical or resolved workspace slugs using shared helpers from ../actions to account for Windows canonicalization
Test one feature per test file
Call project.trackSession(sessionID, directory?) and project.trackDirectory(directory) for any resources created outside the fixture so teardown can clean them up

Files:

  • packages/app/e2e/models/models-visibility.spec.ts
🧠 Learnings (19)
📓 Common learnings
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 208
File: packages/app/src/components/prompt-input.tsx:1569-1611
Timestamp: 2026-04-24T05:39:56.086Z
Learning: In Astro-Han/pawwork `packages/app/src/components/prompt-input.tsx`, after the composer unification in PR `#208` (fixed in commit 5d810aa):
- `SendButton.disabled` does NOT gate on `store.mode !== "normal"`. Shell mode has a fully visible, clickable orange submit button that calls `handleSubmit` directly (same path as the Enter key in `handleKeyDown`). Do NOT suggest re-adding the mode gate.
- `SendButton` does NOT use the `buttons()` spring opacity animation (`style={buttons()}`). It is always fully visible regardless of mode.
- `WorkspaceChip` is gated on `props.homeMode && store.mode === "normal"` so it hides in shell mode (preventing it from appearing isolated/bright while neighboring controls fade).
- The left-side chip group (`aria-hidden={store.mode !== "normal"}`) covers attach/model/variant/workspace controls only; `SendButton` remains in a separate right-side sibling div.
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 208
File: packages/app/e2e/app/composer-parity.spec.ts:0-0
Timestamp: 2026-04-24T05:48:36.205Z
Learning: In Astro-Han/pawwork `packages/app/src/components/prompt-input.tsx`, the Model chip trigger button carries `data-action="prompt-model"` (around line 1187) and the Variant chip trigger button carries `data-action="prompt-model-variant"` (around line 1231), both set via `triggerProps`. These are therefore already captured by any `[data-action]` selector sweep in E2E tests and do not need a separate `[data-component]` query to be included in parity assertions — though unioning both is kept as belt-and-suspenders in `collectBarSet`.
📚 Learning: 2026-04-23T17:02:35.873Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 198
File: packages/app/src/index.css:95-97
Timestamp: 2026-04-23T17:02:35.873Z
Learning: In the pawwork repository, Stylelint is intentionally not configured (per AGENTS.md, only linting is enforced and the Biome formatter is disabled). When reviewing CSS files, do not raise Stylelint rule-based issues (e.g., `declaration-empty-line-before`) because they are false positives and not enforced by the project toolchain.

Applied to files:

  • packages/ui/src/components/button.css
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use locator assertions like `toBeVisible()`, `toHaveCount(0)`, and `toHaveAttribute(...)` for normal UI state verification

Applied to files:

  • packages/app/e2e/models/models-visibility.spec.ts
📚 Learning: 2026-04-24T05:48:36.205Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 208
File: packages/app/e2e/app/composer-parity.spec.ts:0-0
Timestamp: 2026-04-24T05:48:36.205Z
Learning: In E2E parity tests, prefer using the existing `[data-action]` coverage when asserting UI parity. For elements whose trigger props set `data-action` (e.g., `data-action="prompt-model"` and `data-action="prompt-model-variant"` on prompt input chip triggers), you generally do not need to add separate assertions driven by `[data-component]` for parity. Avoid duplicating component-specific queries when the `[data-action]` selector sweep already includes the elements; any extra unioning of selectors should be treated as optional belt-and-suspenders rather than required.

Applied to files:

  • packages/app/e2e/models/models-visibility.spec.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use `expect.poll(...)` for probing mock or backend state rather than transient DOM visibility

Applied to files:

  • packages/app/e2e/models/models-visibility.spec.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Import test utilities from `../fixtures` instead of `playwright/test`

Applied to files:

  • packages/app/e2e/models/models-visibility.spec.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use lowercase, descriptive test names (e.g., 'sidebar can be toggled')

Applied to files:

  • packages/app/e2e/models/models-visibility.spec.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test one feature per test file

Applied to files:

  • packages/app/e2e/models/models-visibility.spec.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Use `data-component`, `data-action`, or semantic roles for selectors instead of CSS class names or IDs

Applied to files:

  • packages/app/e2e/models/models-visibility.spec.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Prefer fluent helpers and drivers when they make intent obvious and reduce locator-heavy noise in tests

Applied to files:

  • packages/app/e2e/models/models-visibility.spec.ts
📚 Learning: 2026-04-20T14:36:04.113Z
Learnt from: CR
Repo: Astro-Han/pawwork PR: 0
File: packages/app/e2e/AGENTS.md:0-0
Timestamp: 2026-04-20T14:36:04.113Z
Learning: Applies to packages/app/e2e/**/*.spec.ts : Test files should be named with the pattern `feature-name.spec.ts`

Applied to files:

  • packages/app/e2e/models/models-visibility.spec.ts
📚 Learning: 2026-04-24T03:51:54.050Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 206
File: packages/app/e2e/prompt/prompt-footer-focus.spec.ts:131-143
Timestamp: 2026-04-24T03:51:54.050Z
Learning: In Astro-Han/pawwork E2E tests under packages/app/e2e, do not manually call `project.trackSession(sessionID)` when you obtain a `sessionID` via `project.prompt(text)`. The `project.prompt()` implementation already registers `trackSession(next.sessionID, active.directory)` automatically after the prompt submission is observed and the active session is resolved, so calling `project.trackSession(sessionID)` again will create duplicate session ownership/teardown handling.

Applied to files:

  • packages/app/e2e/models/models-visibility.spec.ts
📚 Learning: 2026-04-23T07:23:23.849Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 180
File: packages/app/src/components/session/session-new-view.tsx:13-18
Timestamp: 2026-04-23T07:23:23.849Z
Learning: In pawwork (Astro-Han/pawwork), prefer using `createStore` instead of multiple `createSignal` calls only when the signals represent **coupled** object state that is updated together (i.e., there is at least one shared batch-update site where the state is changed in the same transaction). If the state fields are **independent** and are mutated by separate handlers (e.g., one handler updates only `selectedSkill` while another updates only `mode`), keep them as individual `createSignal` calls—using `createStore` for truly independent fields adds boilerplate without behavioral benefit.

Applied to files:

  • packages/app/e2e/models/models-visibility.spec.ts
  • packages/app/src/i18n/en.ts
  • packages/app/src/components/dialog-select-model.tsx
  • packages/app/src/i18n/zh.ts
📚 Learning: 2026-04-23T15:25:27.182Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 193
File: packages/app/e2e/sidebar/sidebar-leading-slot.spec.ts:5-55
Timestamp: 2026-04-23T15:25:27.182Z
Learning: In Astro-Han/pawwork E2E tests (e.g., *.spec.ts under packages/app/e2e), reaching a real "running" session state is not achievable with the bare `sdk` fixture. Use the `project` fixture (to bootstrap the model) and orchestrate the transition with `llm.wait(1)`; even if you set `agent: "build"` and a `system` prompt via `sdk.session.promptAsync`, the current test infrastructure does not trigger an actual LLM call, so it won’t simulate "running" cheaply. Review any attempt to mock/force "running" using only `sdk` as likely ineffective unless it also uses `project` + `llm.wait(1)`.

Applied to files:

  • packages/app/e2e/models/models-visibility.spec.ts
📚 Learning: 2026-04-24T00:02:50.599Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 203
File: packages/app/e2e/sidebar/sidebar-session-links.spec.ts:34-55
Timestamp: 2026-04-24T00:02:50.599Z
Learning: For Astro-Han/pawwork E2E tests under packages/app/e2e/**/*.spec.ts, do not call project.trackDirectory() or project.trackSession() before project.open() has run. The project fixture throws until open() initializes internal state. Use this ordering pattern: (1) call project.trackSession(sessionID) inside the beforeGoto callback (where state is already available), (2) call project.trackDirectory(directory) and any cross-workspace tracking like project.trackSession(id, directory) immediately after project.open() returns, and (3) if you create any resources before open() that cannot yet be tracked via the fixture, ensure you clean them up explicitly in finally blocks (e.g., cleanupSession / cleanupTestProject).

Applied to files:

  • packages/app/e2e/models/models-visibility.spec.ts
📚 Learning: 2026-04-23T15:10:21.635Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 191
File: packages/app/src/components/session/pawwork-skill-meta.ts:38-39
Timestamp: 2026-04-23T15:10:21.635Z
Learning: This repo configures Tailwind v4 with `--color-*: initial`, which effectively breaks standard Tailwind palette utilities (e.g., `text-violet-500` can resolve to no CSS variable and render as a no-op/black). For brand/accent colors that are not backed by semantic design tokens, use inline styles with the exact hex value (e.g., `style={{ color: '#8B5FBF' }}` / `homeIconStyle: { color: '#8B5FBF' }`) and add a short comment explaining that Tailwind palette utilities won’t work due to the `--color-*: initial` setup. Do not suggest replacing these inline hex colors with Tailwind palette classes anywhere in this repo.

Applied to files:

  • packages/app/src/i18n/en.ts
  • packages/app/src/components/dialog-select-model.tsx
  • packages/app/src/i18n/zh.ts
📚 Learning: 2026-04-24T05:48:36.205Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 208
File: packages/app/e2e/app/composer-parity.spec.ts:0-0
Timestamp: 2026-04-24T05:48:36.205Z
Learning: In Astro-Han/pawwork `packages/app/src/components/prompt-input.tsx`, the Model chip trigger button carries `data-action="prompt-model"` (around line 1187) and the Variant chip trigger button carries `data-action="prompt-model-variant"` (around line 1231), both set via `triggerProps`. These are therefore already captured by any `[data-action]` selector sweep in E2E tests and do not need a separate `[data-component]` query to be included in parity assertions — though unioning both is kept as belt-and-suspenders in `collectBarSet`.

Applied to files:

  • packages/app/src/components/dialog-select-model.tsx
📚 Learning: 2026-04-24T05:39:56.086Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 208
File: packages/app/src/components/prompt-input.tsx:1569-1611
Timestamp: 2026-04-24T05:39:56.086Z
Learning: In Astro-Han/pawwork `packages/app/src/components/prompt-input.tsx`, after the composer unification in PR `#208` (fixed in commit 5d810aa):
- `SendButton.disabled` does NOT gate on `store.mode !== "normal"`. Shell mode has a fully visible, clickable orange submit button that calls `handleSubmit` directly (same path as the Enter key in `handleKeyDown`). Do NOT suggest re-adding the mode gate.
- `SendButton` does NOT use the `buttons()` spring opacity animation (`style={buttons()}`). It is always fully visible regardless of mode.
- `WorkspaceChip` is gated on `props.homeMode && store.mode === "normal"` so it hides in shell mode (preventing it from appearing isolated/bright while neighboring controls fade).
- The left-side chip group (`aria-hidden={store.mode !== "normal"}`) covers attach/model/variant/workspace controls only; `SendButton` remains in a separate right-side sibling div.

Applied to files:

  • packages/app/src/components/dialog-select-model.tsx
📚 Learning: 2026-04-22T05:32:29.012Z
Learnt from: Astro-Han
Repo: Astro-Han/pawwork PR: 98
File: packages/desktop-electron/src/main/menu-labels.ts:1-2
Timestamp: 2026-04-22T05:32:29.012Z
Learning: In Astro-Han/pawwork, the app i18n layer (`packages/app/src/i18n/`) only contains `en.ts` and `zh.ts`, and `normalizeLocale` (in `packages/app/src/context/language.tsx`) only returns `"en"` or `"zh"`. The desktop `MenuLocale = "en" | "zh"` union in `packages/desktop-electron/src/main/menu-labels.ts` is intentionally limited to these two locales and is not a broader restriction — do not flag it as overly restrictive or suggest adding other locales.

Applied to files:

  • packages/app/src/i18n/zh.ts
🔇 Additional comments (6)
packages/ui/src/components/button.css (1)

53-57: Focus ring restoration for ghost buttons looks correct.

This re-enables visible keyboard focus for ghost buttons while preserving disabled-state guardrails.

packages/app/e2e/models/models-visibility.spec.ts (1)

63-79: Image-tag visibility coverage looks good.

This test directly validates the new model-picker behavior and uses stable, intent-revealing selectors/assertions.

packages/app/src/components/dialog-select-model.tsx (2)

2-2: Import additions are appropriate for the new tag flow.

For and modelSupportsInput are correctly introduced to support dynamic image-tag rendering.

Also applies to: 16-16


75-89: Tag computation and display rules are implemented correctly.

Priority (free -> image -> latest) and max-visible-tag cap (2) are applied cleanly, and the image capability now comes from the shared input-support helper.

packages/app/src/i18n/en.ts (1)

210-210: English i18n updates are coherent and complete for this feature.

The new model.tag.image key and updated placeholder/example copy align with the model-tag and home-composer polish objectives.

Also applies to: 251-253, 261-285

packages/app/src/i18n/zh.ts (1)

230-230: Chinese i18n changes look correct and product-aligned.

The new image tag label and refreshed placeholder/example set are consistent with the intended non-technical home composer experience.

Also applies to: 270-272, 279-303


📝 Walkthrough

Walkthrough

The PR implements three features across the app: adds visible image-capability tags to the model selector list, replaces home composer placeholder examples from code-centric to document-oriented tasks, updates placeholder text phrasing, and adds focus-visible ring styling for ghost buttons. An e2e test validates image tag visibility in the model picker.

Changes

Cohort / File(s) Summary
Model Selector Tags
packages/app/src/components/dialog-select-model.tsx
Renders image capability tags on models using modelSupportsInput(), switching from conditional Show to array-driven rendering with max 2 tags per item.
Internationalization
packages/app/src/i18n/en.ts, packages/app/src/i18n/zh.ts
Adds new i18n key for image tag label, updates prompt placeholder text from "Ask anything…" to "Try…" format, replaces 25 code-centric prompt examples with document/writing-oriented tasks.
Focus Ring Styling
packages/ui/src/components/button.css
Adds :focus-visible outline styling for ghost buttons using -webkit-focus-ring-color to ensure visible keyboard navigation indicators.
E2E Testing
packages/app/e2e/models/models-visibility.spec.ts
New Playwright test validates model picker dialog displays image capability tag and correctly closes with Escape key.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

app

Poem

🐰 A tag appears beside each model's name,
"Image"—the spark that users seek without shame.
New prompts for writers, no code in sight,
And focus rings glow—ah, keyboard delight! ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(app): composer and model selector polish' clearly summarizes the main changes: improvements to the composer placeholder, model selector visibility, and button focus styling.
Description check ✅ Passed The description comprehensively covers all three bundled changes, includes linked issue references, provides specific verification steps with commands, and addresses all checklist items. Screenshots are noted as pending but the description is otherwise complete.
Linked Issues check ✅ Passed The PR successfully implements all requirements from #176 (non-technical placeholder examples in zh/en), #218 (image tag in model selector with proper priority and styling), and #215 (focus ring restoration on ghost buttons).
Out of Scope Changes check ✅ Passed All code changes directly support the three linked issues: new e2e test validates image tag visibility, dialog-select-model displays the image tag with correct priority, i18n files contain non-technical examples and the new image tag key, and button.css restores focus ring styling. No out-of-scope modifications detected.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/composer-polish-trio

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Code Review

This pull request adds an 'image' tag to the model selection dialog, updates prompt placeholders and examples to focus on general productivity tasks, and includes a new E2E test for model visibility. It also improves button focus styles. Feedback was provided to correct the Tailwind CSS important modifier syntax in the model selection component, as the modifier should be a prefix rather than a suffix.

Comment thread packages/app/src/components/dialog-select-model.tsx
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request P2 Medium priority ui Design system and user interface

Projects

None yet

1 participant