Skip to content

fix(app): preserve multiline question answers - #56911

Open
1052326311 wants to merge 6 commits into
anomalyco:devfrom
1052326311:question-multiline
Open

1052326311 wants to merge 6 commits into
anomalyco:devfrom
1052326311:question-multiline

Conversation

@1052326311

@1052326311 1052326311 commented Oct 19, 2026 •

Copy link
Copy Markdown
Contributor

Issue for this PR

Closes #56895

Type of change

  • Bug fix
  • New feature
  • Refactor / code improvement
  • Documentation

What does this PR do?

Restore a textarea for custom question answers so pasted newlines survive. The custom row stays 40px when empty, grows for short answers, and scrolls for long ones. Enter confirms; Shift+Enter adds a newline; composing Enter, including Safari keyCode 229, does not confirm. Predefined choices and the current keyboard-first question dock remain usable.

How did you verify your code works?

On merge parent dev@48432428d94a70b6aaf95440426cb65ec8be2146, the rendered dock regression fails: the single-line input turns first\nsecond\nthird\nfourth into first second third fourth. With this PR integrated on that base, the production build and built-mode Playwright dock suite pass 5/5. The suite checks multiline persistence in the submitted reply, four visible lines, long-answer scrolling, the 40px empty row, predefined multiselect answers, number-key selection, Enter, Shift+Enter, composing Enter and keyCode 229.

Bun 1.4.4, app and session-ui typechecks, focused Prettier and lint, and root bun run check pass (35/35 typecheck tasks). Published head: 842fad34b7d756b49634116a798fab2df2d1bd46. With upstream/dev fetched at dae4077a96243257ea0a2086068504b791629f10, git diff --check upstream/dev...842fad34b7d756b49634116a798fab2df2d1bd46 passes for the three-file PR delta; later dev commits do not touch these files.

Visual

<svg xmlns="http://www.w3.org/2000/svg" width="240" height="72" viewBox="0 0 240 72" fill="none">
  <rect x="1" y="1" width="238" height="70" rx="5" stroke="currentColor" stroke-opacity="0.3"/>
  <rect x="9" y="8" width="222" height="56" rx="3" stroke="currentColor" stroke-opacity="0.55"/>
  <path d="M18 20h88M18 32h142M18 44h108" stroke="currentColor" stroke-width="3" stroke-linecap="round" stroke-opacity="0.8"/>
  <rect x="18" y="52" width="2" height="7" fill="currentColor">
    <animate attributeName="opacity" values="1;0.15;1" dur="1.2s" repeatCount="indefinite"/>
  </rect>
</svg>

Screenshots / recordings

The bot's earlier UI-head review includes these before/after captures. The merge-base behavior is covered by the rendered dock test above.

Before: pasted newline becomes a space

After: multiline custom answer

Additional final-UI-head screenshot

Checklist

  • I have tested my changes locally
  • I have not included unrelated changes in this PR

@github-actions

Copy link
Copy Markdown
Contributor

The following comment was made by an LLM, it may be inaccurate:

@opencode-agent opencode-agent 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.

The fix works: with this change the custom answer keeps pasted newlines, Shift+Enter adds a line, and Enter still commits. I ran the updated session-request-docks.spec.ts in Chromium: all 4 tests pass here, and on the base its multiline test fails with alpha beta. I also pasted a multi-line answer on both checkouts and took screenshots (attached). typecheck passes for app and session-ui.

Public API: unchanged (UI and CSS only).

What I'd change before merging:

  • Sizing (inline): the custom option is now a fixed 64px row with a 52px textarea. When empty it is taller than the other options. With three or more lines the text scrolls inside about two visible rows and the first line gets cut off.
  • Safari IME (inline): the Enter guard only checks isComposing. Elsewhere the app also checks keyCode === 229.
  • Screenshots: the three PNGs under packages/app/e2e/screenshots/ only illustrate the PR description. Please drop them from the commit.
  • Test: the isComposing step uses a synthetic dispatchEvent, which doesn't cover the Safari keyCode case.

Before

After

Screenshot

inline-size: 100%;
min-inline-size: 0;
block-size: 28px;
block-size: 52px;

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.

This fixes the custom row at 64px, with a 52px textarea, whatever the content. When empty, the row is taller than the other 40px options and the placeholder sits at the top (see the after screenshot). With three or more lines the textarea scrolls inside about two visible rows and the first line gets clipped. v2.0.21 used rows={1} plus resizeInput to grow with the content. Could you keep the 40px resting height, grow the textarea to fit its content, and cap it with a max-block-size, scrolling past that?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 22e9f30: the empty custom row is 40px, the one-row textarea grows with scrollHeight to a 124px cap, then scrolls. The Chrome keeper failed before on the 64px row and four-line clipping; it now passes on desktop and mobile, including 12-line scrolling. The three PNGs are absent from the final PR diff; the PR body links immutable hosted before/after images.

if ((e.metaKey || e.ctrlKey) && !e.altKey) return

if (e.key !== "Enter") return
if (e.key !== "Enter" || e.shiftKey || e.isComposing) return

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.

Safari can send the keydown that confirms IME input with isComposing === false and keyCode === 229, so this would commit the answer while someone is still entering Japanese or Chinese text. Elsewhere the app checks e.isComposing || e.keyCode === 229 (e.g. home/sessions/view.tsx, settings/providers/account-name.tsx). Could you use the same check here?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 22e9f30 with the existing app guard pattern: isComposing or keyCode 229 prevents confirmation. The keeper creates a keydown with an explicit 229 property and checks editing stays active; removing the guard makes that test fail, while ordinary Enter still commits. Full Chrome dock suite: 4/4.

@opencode-agent opencode-agent 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.

My earlier points are all fixed at 22e9f3021. The empty custom row is now 40px, the same as the other options. The field grows to fit and scrolls once it reaches its cap. Enter is ignored for Safari's keyCode 229, and the PNGs are gone. I re-ran session-request-docks.spec.ts in Chromium (4/4 pass) and took new screenshots (attached). typecheck passes for app and session-ui.

Public API: unchanged (UI and CSS only).

One request: the test now has about 30 lines of layout measurements (inline). Please trim them so it keeps to the behaviour.

Before

After

Screenshot

await expect(terminal).toBeChecked()

await input.fill("Updated custom answer")
await input.fill("first\nsecond\nthird\nfourth")

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.

These checks pin exact layout numbers: the row height, more than 52px for four lines, at most 124px, a 12-line case and scroll positions. They will fail on any future design tweak even when the behaviour is fine. The fix only needs the newline kept, Shift+Enter adding a line, composing and 229 Enter not committing, and the multi-line answer being posted. Could you cut this block down to one simple check that four lines aren't clipped, or drop it? In the 229 step below, toBe(229) only checks the test's own defineProperty, so that assertion can go too.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in 010ac84: removed the fixed 52px/124px and scroll-position probes and the self-confirming toBe(229). The keeper retains one four-line unclipped check, an overflow check for long text, and the 40px empty-row check requested in the prior review; newline, Shift+Enter, IME 229, and posted-answer assertions remain. Revised test is red on untouched 501b15a (pasted lines become spaces), then green 4/4 as a file and 10/10 at five workers on the fixed production build.

@opencode-agent

Copy link
Copy Markdown
Contributor

Thanks, I checked 010ac842d. The fixed 52px/124px heights, the scroll-position probe and the self-checking toBe(229) are gone. The test still covers what matters: newlines are kept, Shift+Enter adds a line, Enter during composition or with keyCode 229 doesn't commit, and the multi-line answer is posted. Since that commit only changes the test, the app code is the same as what I reviewed at 22e9f3021. I have nothing further from my review.

@opencode-agent opencode-agent 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.

My earlier points are fixed at 9504aa44da. The custom row stays 40px when empty, grows to fit, and scrolls past its cap. The pixel and scroll-position checks are gone from the test. Since the rebase, dev already skips Enter during composition, including Safari's keyCode 229, both at the top of this field's key handler and in question-keys.ts. I re-ran session-request-docks.spec.ts in Chromium. It passes here and fails on the base (ed74ec82ce), where the four lines become one. bun test src/session/requests passes, and tsc is clean for app and session-ui. Screenshots attached.

Public API: unchanged (UI and CSS only).

Minor: two test edits aren't needed for this fix and could be dropped: picking "Terminal" with 2 instead of a click, and the first test submitting with Ctrl+Enter instead of a click.

Before

After

Screenshot

@1052326311

Copy link
Copy Markdown
Contributor Author

Resolved the current dev question-dock conflict on head 842fad34b7d756b49634116a798fab2df2d1bd46. The PR delta remains the three intended files and preserves the newer dock motion and keyboard behavior. The rendered test fails on merge parent 48432428 because the input flattens pasted newlines; the integrated production build and built-mode dock suite pass 5/5. Root bun run check passes 35/35, focused Prettier/lint pass, and git diff --check upstream/dev...HEAD passes with dev@dae4077a.

GitHub now reports the PR mergeable. Standards/compliance passed. Hosted check, check-test, and check-nix are action_required with zero jobs; they have not run and are still awaiting the repository's approval.

@opencode-agent opencode-agent 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.

The new commit only merges a newer dev, and the PR's own change is the same as in 9504aa44da. That dev reworked the question dock, so I re-ran session-request-docks.spec.ts in Chromium. It passes here and fails on the base (48432428d9), where the four lines become one. A pasted 4-line answer shows in full once the dock's height animation settles, and the empty row is still 40px (screenshots attached). bun test src/session/requests passes, and tsc is clean for app and session-ui.

Public API: unchanged (UI and CSS only).

My earlier points (sizing, Safari composition Enter, test size) remain fixed. No new concerns.

Before

After

Screenshot

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

question tool: free-form answer cannot accept multi-line input (silent truncation since #54822)

1 participant