Skip to content

feat(autoresearch): improve new-task composer controls (GROW-124)#3205

Merged
fercgomes merged 2 commits into
mainfrom
posthog-code/grow-124-autoresearch-composer-polish
Jul 6, 2026
Merged

feat(autoresearch): improve new-task composer controls (GROW-124)#3205
fercgomes merged 2 commits into
mainfrom
posthog-code/grow-124-autoresearch-composer-polish

Conversation

@fercgomes

Copy link
Copy Markdown
Contributor

What

Polish pass on the autoresearch mode in the new-task composer (follow-up to the autoresearch feature, GROW-103).

1. Autoresearch moved into the agent-mode dropdown

  • Removed the standalone "Autoresearch" toolbar button.
  • It's now the last item of the mode dropdown (after a separator), as a checkbox toggle applied on menu close — the same deferral the mode radio items use, so the composer doesn't relayout under the closing menu.
  • Arming it defaults the agent mode to the most hands-off option available — bypassPermissions when the user has it enabled, otherwise acceptEdits — since an unattended iteration loop would stall on permission prompts.

2. Fixed the target/iterations inputs stealing focus on click

  • Root cause: they lived inside the composer's InputGroup, whose click handler refocuses the editor on any non-button click, so clicking an input bounced focus straight to the prompt.
  • Fixed structurally by relocating them (see chore: set up biome and ci #3) into the outer container, which already respects focusable elements.

3. Controls moved outside the input box

  • The autoresearch controls now render as a bar between the dropdown row and the prompt input, instead of inside the composer's header addon.

4. Controls rewritten to be self-explanatory

  • Before: a bare Maximize, an unlabeled Target box, a stray ≤ 10 iterations, and a Claude Opus 4.8 · Max line that didn't look clickable.
  • After: reads as one sentence — Optimize to maximize until it reaches [optional] or after [10] iterations using [model] — with a tooltip on each label and an explainer on the Autoresearch chip. Tooltips wrap only plain label spans (never the inputs) to avoid reintroducing focus flicker.

Feature-flag gating

Both new surfaces stay behind useAutoresearchEnabled() (staff-gated flag; always on in dev):

  • The dropdown toggle is passed to PromptInput/ModeSelector only when autoresearchService && autoresearchEnabled.
  • The controls bar renders only when autoresearchDraft is set, which is forced null while the flag is off.
  • ModeSelector and PromptInput stay flag-agnostic; the gate lives solely in TaskInput.

Files

  • packages/ui/src/features/message-editor/components/ModeSelector.tsx
  • packages/ui/src/features/message-editor/components/PromptInput.tsx
  • packages/ui/src/features/task-detail/components/TaskInput.tsx
  • packages/ui/src/features/autoresearch/AutoresearchComposerControls.tsx

Testing

  • pnpm typecheck (full monorepo, 22/22) and Biome lint pass on all changed files.
  • ⚠️ Not yet driven in the running app — live check of the focus fix, the dropdown toggle applying the hands-off mode, and tooltip/label wrapping still pending.

Fixes GROW-124


Created with PostHog Code

Move the Autoresearch toggle into the agent-mode dropdown as its last
item; arming it defaults the mode to bypassPermissions (or acceptEdits)
so the unattended loop isn't blocked on permission prompts.

Move the target/iterations controls out of the composer InputGroup —
whose click handler refocused the editor on every click, stealing focus
from the inputs — into a bar between the dropdown row and the input.

Rewrite that bar to read as a sentence ("Optimize to maximize until it
reaches N or after K iterations using <model>") with per-label tooltips,
replacing the unlabeled Maximize / Target / <= controls.

Feature-flag gating (autoresearchEnabled) is preserved on both the
dropdown toggle and the controls bar.

Generated-By: PostHog Code
Task-Id: 14b7baf0-7253-47ec-96a5-110520071729
@trunk-io

trunk-io Bot commented Jul 6, 2026

Copy link
Copy Markdown

Merging to main in this repository is managed by Trunk.

  • To merge this pull request, check the box to the left or comment /trunk merge below.

After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown

React Doctor found no issues in the changed files. 🎉

Reviewed by React Doctor for commit 4319801.

@greptile-apps

greptile-apps Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "feat(autoresearch): improve new-task com..." | Re-trigger Greptile

Comment on lines +689 to +697
// The loop iterates unattended, so a permission prompt would stall it.
// Default to the most hands-off mode available: bypass when the user has
// enabled it, otherwise accept-edits.
const autonomousMode = allowBypassPermissions
? "bypassPermissions"
: "acceptEdits";
if (modeOption && isValidConfigValue(modeOption, autonomousMode)) {
setConfigOption(modeOption.id, autonomousMode);
}

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.

P2 Previous mode silently dropped on disarm

When arming autoresearch, setConfigOption overrides the user's selected mode with bypassPermissions or acceptEdits. The early-return branch on disarm (store.clearDraftreturn) never calls setConfigOption to restore the original mode. A user who was in "Plan" mode will be left in "Accept Edits" after the autoresearch cycle ends without any automatic restore — they have to notice the mode button changed and fix it manually.

Comment on lines +129 to +145
{autoresearch && (
<>
<DropdownMenuSeparator />
<DropdownMenuCheckboxItem
checked={autoresearch.active}
onCheckedChange={() => {
pendingAutoresearchRef.current = true;
setOpen(false);
}}
>
<span className="text-violet-11">
<ChartLineUp size={12} />
</span>
<span className="whitespace-nowrap">Autoresearch</span>
</DropdownMenuCheckboxItem>
</>
)}

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.

P2 Checkbox checked visual state can lag behind onCheckedChange resolution

onCheckedChange sets pendingAutoresearchRef.current = true and calls setOpen(false), but the actual store update (and thus the new value of autoresearch.active) only fires during onOpenChangeComplete after the menu's close animation ends. If Radix UI optimistically flips the checkbox's visual checked state inside onCheckedChange, it will momentarily disagree with the checked={autoresearch.active} prop until the animation completes. In practice the menu closes immediately so the user may never see the inconsistency, but it's worth verifying Radix's DropdownMenuCheckboxItem doesn't eagerly render the toggled state before the controlled prop catches up.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

…124)

Add two product-analytics events for autoresearch mode usage:
- "Autoresearch armed" — fired when the mode is turned on from the
  agent-mode dropdown (default_mode, workspace_mode).
- "Autoresearch run started" — fired when an armed task is submitted
  (direction, has_target, max_iterations, stages_split, per-stage
  model/effort, workspace_mode).

Both fire only through the feature-flag-gated arm/submit paths, so no
events emit when autoresearch is disabled.

Generated-By: PostHog Code
Task-Id: 14b7baf0-7253-47ec-96a5-110520071729
@fercgomes

Copy link
Copy Markdown
Contributor Author

Added product-analytics instrumentation for autoresearch usage (commit 4319801).

Two events (defined in packages/shared/src/analytics-events.ts, fired from TaskInput.tsx):

  • Autoresearch armed — fired when the user turns the mode on from the agent-mode dropdown.
    • default_mode (bypassPermissions | acceptEdits), workspace_mode
  • Autoresearch run started — fired when an armed task is submitted and the run kicks off.
    • direction, has_target, max_iterations, stages_split, implement_model, measure_model, implement_effort, measure_effort, workspace_mode

Together they give an arm → run funnel. Properties are compile-time-checked via EventPropertyMap.

Both fire only through the feature-flag-gated arm/submit paths, so nothing emits when autoresearch is disabled.

@fercgomes fercgomes requested review from a team and rafaeelaudibert July 6, 2026 19:23
@fercgomes fercgomes merged commit 6cfb8b3 into main Jul 6, 2026
24 checks passed
@fercgomes fercgomes deleted the posthog-code/grow-124-autoresearch-composer-polish branch July 6, 2026 19:39
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.

2 participants