Skip to content

feat(agents): sticky header + compact model params layout#8

Closed
bashrusakh wants to merge 8 commits into
mainfrom
issue-1702-wise-narwhal
Closed

feat(agents): sticky header + compact model params layout#8
bashrusakh wants to merge 8 commits into
mainfrom
issue-1702-wise-narwhal

Conversation

@bashrusakh

@bashrusakh bashrusakh commented Jun 28, 2026

Copy link
Copy Markdown
Owner

Summary

Agent settings editor layout redesign — phase 1. Closes openchamber#1702.

Changes

  • Sticky header — agent name + always-visible Save button, sits above ScrollableOverlay
  • Compact Model & Parameters — 2 rows instead of 4:
    • Row 1: Model selector + Variant ("Thinking") inline
    • Row 2: Sampling label + Temperature + Top P side by side
  • Section order: Identity & Role → Model & Parameters → System Prompt → Tool Permissions
  • Same layout for both edit and new-agent-creation flows
  • i18n: shortened variant label to "Thinking" in all locales, added missing permission keys
  • Settings search: restored data-settings-item attributes for variant/temperature/top-p
  • Cleanup: removed unused isMobile / useDeviceInfo

Files changed

File Change
packages/ui/src/components/sections/agents/AgentsPage.tsx Layout restructure + compact Model & Parameters
packages/ui/src/lib/i18n/messages/*.settings.ts Shortened variant label, added missing keys

Validation

  • bun run type-check in packages/ui — passes
  • bun run build — passes

Summary by CodeRabbit

  • New Features

    • Improved the mobile chat and settings experience with clearer layouts, larger text, and better-aligned controls.
    • Added provider logos and updated labels in the Agents settings UI for a cleaner model-selection flow.
    • Introduced translated copy updates across multiple languages for new Agents settings and permissions options.
  • Bug Fixes

    • Improved scroll stability in chat on mobile and touch devices.
    • Prevented the “Add provider” form from closing unexpectedly during background updates.
    • Fixed mobile chat behavior so earlier messages load more reliably while scrolling.

Exported package-manager helpers used by openchamber update
Added regression coverage for the update-available path
Gate passive auto-follow on active (working/settling) state so idle layout
churn from virtualizer re-measurement no longer re-pins the viewport to the
bottom. Render default-open tool bodies synchronously on mount so the
virtualizer measures the real row height up front instead of growing a frame
later and lurching scroll past several messages.
Give touch surfaces a larger, viewport-relative head start for loading older
history so an in-flight fetch completes before the finger reaches the top.
Raise the mobile virtualizer overscan so fast flings stay populated instead of
leaving blank gaps, and drop the fixed itemSize hint so virtua auto-estimates
row heights from measured sizes instead of a flat constant.
Redesign the mobile composer model and agent buttons as borderless, full-bleed
labels that hug their content, truncate with an ellipsis when space is tight,
and show the provider logo inline before the model name. Tighten the footer
action buttons (sessions / attach / auto-accept) so they sit close together,
with a small left inset on the group. In the mobile model selection overlay,
make the thinking-variant control text-only with a chevron, vertically center
the variant and favorite controls in each row, and place the provider logo
inline with the model name.
@coderabbitai

coderabbitai Bot commented Jun 28, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 949aaad9-e4a1-4da9-ae57-bf6875a89025

📥 Commits

Reviewing files that changed from the base of the PR and between 7b22220 and 04dfa5b.

📒 Files selected for processing (11)
  • packages/ui/src/components/sections/agents/AgentsPage.tsx
  • packages/ui/src/lib/i18n/messages/en.settings.ts
  • packages/ui/src/lib/i18n/messages/es.settings.ts
  • packages/ui/src/lib/i18n/messages/fr.settings.ts
  • packages/ui/src/lib/i18n/messages/ja.settings.ts
  • packages/ui/src/lib/i18n/messages/ko.settings.ts
  • packages/ui/src/lib/i18n/messages/pl.settings.ts
  • packages/ui/src/lib/i18n/messages/pt-BR.settings.ts
  • packages/ui/src/lib/i18n/messages/uk.settings.ts
  • packages/ui/src/lib/i18n/messages/zh-CN.settings.ts
  • packages/ui/src/lib/i18n/messages/zh-TW.settings.ts

📝 Walkthrough

Walkthrough

Version 1.13.7 release comprising: active-session gating in useChatAutoFollow to suppress idle scroll/twitch; mobile-adaptive scroll thresholds and virtualizer buffer sizes; synchronous tool-part expansion on first mount; mobile composer button and typography CSS updates; __add_provider__ sentinel preservation across config store refreshes; AgentsPage sticky-header refactor; CLI update helper exports; and version/changelog bumps across all packages.

Changes

Chat Scroll Stability and Mobile UI

Layer / File(s) Summary
useChatAutoFollow active-session gating
packages/ui/src/hooks/useChatAutoFollow.ts
Introduces SETTLE_MS, settlingRef, settleTimerRef, and isActive() so passive follow and ResizeObserver re-pinning are suppressed during idle layout churn; adds two-phase working→settling→idle transition.
Mobile scroll threshold and virtualizer buffer sizing
packages/ui/src/components/chat/hooks/useChatTimelineController.ts, packages/ui/src/components/chat/MessageList.tsx
Adds resolveHistoryScrollThreshold(clientHeight) and resolveMessageListBufferSize() returning larger values on mobile; applies them to handleHistoryScroll and the static history Virtualizer.
ToolPart synchronous expansion on initial mount
packages/ui/src/components/chat/message/parts/ToolPart.tsx
useDeferredExpandedContent initializes shouldRender from isExpanded and uses mountedRef to render synchronously on first mount when expanded, deferring only subsequent user-initiated expansions.
Mobile composer buttons and CSS
packages/ui/src/components/chat/MobileModelButton.tsx, packages/ui/src/components/chat/MobileAgentButton.tsx, packages/ui/src/components/chat/ChatInput.tsx, packages/ui/src/components/chat/ModelControls.tsx, packages/ui/src/styles/mobile.css
MobileModelButton gains ProviderLogo; MobileAgentButton switches to nested flex label; ChatInput adds composer-mobile-actions class; ModelControls row alignment changed to items-center; mobile CSS typography scale increased and .composer-mobile-actions button sizing forced via !important.

Add-Provider Sentinel Preservation

Layer / File(s) Summary
Sentinel helpers and partialize
packages/ui/src/stores/useConfigStore.ts
Adds sanitizeSelectedProviderId (sentinel → "" for storage) and preserveSelectedProviderId (keeps sentinel during selection updates); updates zustand partialize to sanitize both top-level and directoryScoped snapshots.
Sentinel-aware apply functions
packages/ui/src/stores/useConfigStore.ts
Updates applyResolvedModelSelection, applyDefaultModelAgentSelection, and applyOpenCodeConfigDefaults to call preserve/sanitize helpers instead of blindly replacing selectedProviderId.
Config store sentinel tests
packages/ui/src/stores/useConfigStore.test.ts
Two new tests: sentinel is stored as "" in persisted snapshot; emitSyncConfigChanged updates model/agent without overwriting the sentinel.

AgentsPage Layout and i18n

Layer / File(s) Summary
Sticky header and responsive layout refactor
packages/ui/src/components/sections/agents/AgentsPage.tsx
Removes useDeviceInfo/isMobile; adds sticky header outside ScrollableOverlay containing the save button; rewrites model/variant/temperature controls without mobile-conditional wrappers.
Agents i18n: sampling and permissions strings
packages/ui/src/lib/i18n/messages/*.settings.ts
Adds settings.agents.page.field.sampling and five settings.agents.page.permissions.* keys (search placeholder, explicit, inherited, noResults, noPatternRules) across all 10 locale files; shortens variant label.

CLI Update Command Export

Layer / File(s) Summary
Export detectPackageManager and executeUpdate
packages/web/server/lib/package-manager.js, packages/web/server/lib/package-manager.test.js, packages/web/bin/lib/commands-update.test.js
Adds export keyword to both functions; adds export-verification test; adds integration test asserting the update command calls executeUpdate with detected package manager and { silent: true }.

Version Bump and Changelogs

Layer / File(s) Summary
Version 1.13.7 across all packages
package.json, packages/*/package.json, CHANGELOG.md, packages/vscode/CHANGELOG.md
Bumps all manifests to 1.13.7 and adds release notes for the features in this PR.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 40.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main UI changes: a sticky header and a compact Model & Parameters layout.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ 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 issue-1702-wise-narwhal

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.

🔧 OpenGrep (1.23.0)
packages/ui/src/lib/i18n/messages/uk.settings.ts

┌──────────────┐
│ Opengrep CLI │
└──────────────┘

�[32m✔�[39m �[1mOpengrep OSS�[0m
�[32m✔�[39m Basic security coverage for first-party code vulnerabilities.

[00.18][ERROR]: unable to find a config; path .coderabbit-opengrep-fallback.yml does not exist

packages/ui/src/lib/i18n/messages/zh-CN.settings.ts

┌──────────────┐
│ Opengrep CLI │
└──────────────┘

�[32m✔�[39m �[1mOpengrep OSS�[0m
�[32m✔�[39m Basic security coverage for first-party code vulnerabilities.

[00.16][ERROR]: unable to find a config; path .coderabbit-opengrep-fallback.yml does not exist

packages/ui/src/lib/i18n/messages/zh-TW.settings.ts

┌──────────────┐
│ Opengrep CLI │
└──────────────┘

�[32m✔�[39m �[1mOpengrep OSS�[0m
�[32m✔�[39m Basic security coverage for first-party code vulnerabilities.

[00.16][ERROR]: unable to find a config; path .coderabbit-opengrep-fallback.yml does not exist


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

- Sticky header with agent name and always-visible Save button
- Compact Model & Parameters: 2 rows (Model+Variant, Sampling+TopP)
- Shortened variant label to 'Thinking' in all locales
- Added missing i18n keys for all locales
- Restored data-settings-item attrs for settings search
- Removed unused isMobile/useDeviceInfo
@bashrusakh bashrusakh force-pushed the issue-1702-wise-narwhal branch from 7b22220 to 04dfa5b Compare June 28, 2026 19:18
@bashrusakh bashrusakh closed this Jun 28, 2026

@coderabbitai coderabbitai 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.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/web/server/lib/package-manager.js (1)

772-783: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Whitelist pm before building the shell command. resolvePackageManagerCommand() falls back to the original value, and quoteCommand() leaves non-whitespace strings unchanged, so an unexpected pm can still reach spawnSync(..., shell: true). Reject unknown package managers here or switch to an executable + args form.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/web/server/lib/package-manager.js` around lines 772 - 783,
executeUpdate currently builds a shell command from pm and passes it to
spawnSync with shell enabled, so an unexpected package manager value can still
be executed. Add validation in executeUpdate (or before
getUpdateCommand/resolvePackageManagerCommand is used) to allow only known
package managers, or refactor the spawnSync call to use an executable plus args
instead of a shell string. Keep the fix localized around executeUpdate,
getUpdateCommand, and resolvePackageManagerCommand/quoteCommand so invalid pm
values cannot reach the shell.

Source: Linters/SAST tools

🧹 Nitpick comments (1)
packages/ui/src/stores/useConfigStore.ts (1)

34-35: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Share one sentinel constant across UI, store, and tests.

The store, providers page, model controls, and tests all rely on the exact "__add_provider__" value. Since persistence now treats it specially, export/import a single constant to avoid silent drift.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/stores/useConfigStore.ts` around lines 34 - 35, The special
add-provider sentinel is duplicated as the exact "__add_provider__" string
across useConfigStore, the providers page, model controls, and tests, so
introduce and export a single shared constant for this value and update all call
sites to use it. Make sure the store’s persistence logic, any UI selection
checks, and the related tests reference the same constant so the sentinel cannot
drift silently.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/ui/src/lib/i18n/messages/es.settings.ts`:
- Line 393: The localized label for settings.agents.page.field.variant in
es.settings.ts no longer matches the updated English meaning for “Thinking.”
Update the Spanish translation in the messages map to the equivalent of
“Thinking” (for example, “Pensamiento”) so it stays consistent with the other
locales and the new English wording.

In `@packages/ui/src/lib/i18n/messages/fr.settings.ts`:
- Line 382: The localized label for settings.agents.page.field.variant in the
French settings messages is still using an outdated translation that no longer
matches the updated English wording. Update the value in fr.settings.ts from the
current variant text to the French equivalent of “Thinking,” and keep it aligned
with the existing variantTooltip terminology in the same locale file so the UI
wording stays consistent across languages.

In `@packages/ui/src/stores/useConfigStore.ts`:
- Around line 197-199: The helper preserveAddProviderSelection is only used in
one place, but the loadProviders failure fallback still overwrites
parsed.providerId directly and can close the add-provider flow after a failed
refresh. Update the remaining automatic overwrite path in loadProviders so that
settingsDefaultModel is applied through preserveAddProviderSelection, keeping
ADD_PROVIDER_SENTINEL when the current selection is the add-provider state and
only replacing it otherwise.

In `@packages/ui/src/styles/mobile.css`:
- Around line 88-96: The .composer-mobile-actions button rule is overriding the
mobile touch-target minimum and shrinking the footer action buttons too far.
Update the mobile.css styles so the session / attach / auto-accept buttons keep
the 36px minimum touch size defined by the global mobile button rule, and avoid
using !important or explicit widths that bypass that floor. Use the
composer-mobile-actions selector to preserve spacing, but let the buttons remain
at the mobile minimum tap target.

---

Outside diff comments:
In `@packages/web/server/lib/package-manager.js`:
- Around line 772-783: executeUpdate currently builds a shell command from pm
and passes it to spawnSync with shell enabled, so an unexpected package manager
value can still be executed. Add validation in executeUpdate (or before
getUpdateCommand/resolvePackageManagerCommand is used) to allow only known
package managers, or refactor the spawnSync call to use an executable plus args
instead of a shell string. Keep the fix localized around executeUpdate,
getUpdateCommand, and resolvePackageManagerCommand/quoteCommand so invalid pm
values cannot reach the shell.

---

Nitpick comments:
In `@packages/ui/src/stores/useConfigStore.ts`:
- Around line 34-35: The special add-provider sentinel is duplicated as the
exact "__add_provider__" string across useConfigStore, the providers page, model
controls, and tests, so introduce and export a single shared constant for this
value and update all call sites to use it. Make sure the store’s persistence
logic, any UI selection checks, and the related tests reference the same
constant so the sentinel cannot drift silently.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9dd5c8c9-ba6d-4066-ab7b-0d768cb0048e

📥 Commits

Reviewing files that changed from the base of the PR and between 2ef5f2a and 7b22220.

📒 Files selected for processing (33)
  • .github/workflows/release-desktop-smoke.yml
  • CHANGELOG.md
  • package.json
  • packages/electron/package.json
  • packages/ui/package.json
  • packages/ui/src/components/chat/ChatInput.tsx
  • packages/ui/src/components/chat/MessageList.tsx
  • packages/ui/src/components/chat/MobileAgentButton.tsx
  • packages/ui/src/components/chat/MobileModelButton.tsx
  • packages/ui/src/components/chat/ModelControls.tsx
  • packages/ui/src/components/chat/hooks/useChatTimelineController.ts
  • packages/ui/src/components/chat/message/parts/ToolPart.tsx
  • packages/ui/src/components/sections/agents/AgentsPage.tsx
  • packages/ui/src/hooks/useChatAutoFollow.ts
  • packages/ui/src/lib/i18n/messages/en.settings.ts
  • packages/ui/src/lib/i18n/messages/es.settings.ts
  • packages/ui/src/lib/i18n/messages/fr.settings.ts
  • packages/ui/src/lib/i18n/messages/ja.settings.ts
  • packages/ui/src/lib/i18n/messages/ko.settings.ts
  • packages/ui/src/lib/i18n/messages/pl.settings.ts
  • packages/ui/src/lib/i18n/messages/pt-BR.settings.ts
  • packages/ui/src/lib/i18n/messages/uk.settings.ts
  • packages/ui/src/lib/i18n/messages/zh-CN.settings.ts
  • packages/ui/src/lib/i18n/messages/zh-TW.settings.ts
  • packages/ui/src/stores/useConfigStore.test.ts
  • packages/ui/src/stores/useConfigStore.ts
  • packages/ui/src/styles/mobile.css
  • packages/vscode/CHANGELOG.md
  • packages/vscode/package.json
  • packages/web/bin/lib/commands-update.test.js
  • packages/web/package.json
  • packages/web/server/lib/package-manager.js
  • packages/web/server/lib/package-manager.test.js

"settings.agents.page.field.overrideModel": "Sobrescribir modelo",
"settings.agents.page.field.variant": "Variante de pensamiento",
"settings.agents.page.field.sampling": "Muestreo",
"settings.agents.page.field.variant": "Variante",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

variant label does not match the new English "Thinking" wording.

English changed this label to 'Thinking' (and pl/zh-TW were updated to the equivalent "Thinking"). The Spanish value here is 'Variante' ("Variant"), so the displayed label semantics diverge across locales. Per the commit notes ("some locale labels were corrected to match the English 'Thinking' label"), this likely should be something like 'Pensamiento'.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/lib/i18n/messages/es.settings.ts` at line 393, The localized
label for settings.agents.page.field.variant in es.settings.ts no longer matches
the updated English meaning for “Thinking.” Update the Spanish translation in
the messages map to the equivalent of “Thinking” (for example, “Pensamiento”) so
it stays consistent with the other locales and the new English wording.

'settings.agents.page.field.overrideModel': 'Remplacer le modèle',
'settings.agents.page.field.variant': 'Variante de réflexion',
'settings.agents.page.field.sampling': 'Échantillonnage',
'settings.agents.page.field.variant': 'Variante',

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

variant label diverges from the new English "Thinking" wording.

English is now 'Thinking' and pl/zh-TW were aligned accordingly, but this French value is 'Variante' ("Variant"). To keep the label consistent across locales, consider 'Réflexion' (matching the existing variantTooltip which already refers to "raisonnement/réflexion").

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/lib/i18n/messages/fr.settings.ts` at line 382, The localized
label for settings.agents.page.field.variant in the French settings messages is
still using an outdated translation that no longer matches the updated English
wording. Update the value in fr.settings.ts from the current variant text to the
French equivalent of “Thinking,” and keep it aligned with the existing
variantTooltip terminology in the same locale file so the UI wording stays
consistent across languages.

Comment on lines +197 to +199
const preserveAddProviderSelection = (currentSelectedProviderId: string | undefined, nextProviderId: string): string => (
currentSelectedProviderId === ADD_PROVIDER_SENTINEL ? ADD_PROVIDER_SENTINEL : nextProviderId
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Use this helper in the remaining automatic overwrite path.

Line 1702 and Line 1707 still assign parsed.providerId directly in the loadProviders failure fallback, so a failed background refresh can still close the add-provider flow when it applies settingsDefaultModel.

Proposed fix
-                                        nextState.selectedProviderId = parsed.providerId;
+                                        const nextSelectedProviderId = preserveAddProviderSelection(
+                                            state.selectedProviderId,
+                                            parsed.providerId,
+                                        );
+                                        nextState.selectedProviderId = nextSelectedProviderId;
 
                                         nextSnapshot.currentProviderId = parsed.providerId;
                                         nextSnapshot.currentModelId = parsed.modelId;
                                         nextSnapshot.currentVariant = currentVariant;
-                                        nextSnapshot.selectedProviderId = parsed.providerId;
+                                        nextSnapshot.selectedProviderId = nextSelectedProviderId;
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const preserveAddProviderSelection = (currentSelectedProviderId: string | undefined, nextProviderId: string): string => (
currentSelectedProviderId === ADD_PROVIDER_SENTINEL ? ADD_PROVIDER_SENTINEL : nextProviderId
);
const nextSelectedProviderId = preserveAddProviderSelection(
state.selectedProviderId,
parsed.providerId,
);
nextState.selectedProviderId = nextSelectedProviderId;
nextSnapshot.currentProviderId = parsed.providerId;
nextSnapshot.currentModelId = parsed.modelId;
nextSnapshot.currentVariant = currentVariant;
nextSnapshot.selectedProviderId = nextSelectedProviderId;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/stores/useConfigStore.ts` around lines 197 - 199, The helper
preserveAddProviderSelection is only used in one place, but the loadProviders
failure fallback still overwrites parsed.providerId directly and can close the
add-provider flow after a failed refresh. Update the remaining automatic
overwrite path in loadProviders so that settingsDefaultModel is applied through
preserveAddProviderSelection, keeping ADD_PROVIDER_SENTINEL when the current
selection is the add-provider state and only replacing it otherwise.

Comment on lines +88 to +96
/* Composer footer action buttons (sessions / attach / auto-accept): hug the
icon so the group stays tight. The container only renders in the mobile
JSX, so no pointer/runtime gating is needed; !important overrides both the
w-8 utility and the global mobile touch-target min-width regardless of
cascade layer or specificity. */
.composer-mobile-actions button {
width: 1.5rem !important;
min-width: 0 !important;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Keep the footer action tap targets at the mobile minimum.

Lines 94-95 shrink every button in this group to 24px wide and explicitly bypass the 36px mobile floor defined a few lines above. That makes the session / attach / auto-accept actions materially harder to hit on touch screens.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/ui/src/styles/mobile.css` around lines 88 - 96, The
.composer-mobile-actions button rule is overriding the mobile touch-target
minimum and shrinking the footer action buttons too far. Update the mobile.css
styles so the session / attach / auto-accept buttons keep the 36px minimum touch
size defined by the global mobile button rule, and avoid using !important or
explicit widths that bypass that floor. Use the composer-mobile-actions selector
to preserve spacing, but let the buttons remain at the mobile minimum tap
target.

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.

Improve Agent settings editor layout: sticky Save button, sticky header, and redesigned permissions UI

2 participants