Skip to content

Track safer Claude plan-mode scroll patch #30

Description

@connorads

Context

The local Claude Code plan-scroll patch was reverted after it crashed plan mode:

ERROR  oe.getFreshScrollHeight is not a function. (In 'oe.getFreshScrollHeight()', 'oe.getFreshScrollHeight' is undefined)

/$bunfs/root/src/entrypoints/cli.js:9789:15675

Revert commit in dotfiles: b745cafd.

The installed Claude binary was also restored from claude.unpatched and re-patched with only the existing non-plan-scroll local patches.

Cause

The reverted patch replaced the plan approval render call from Claude's internal scroll component pW to a normal Ink Box ($) while keeping the same ref path.

That was unsafe. pW is not just layout; it exposes an imperative scroll-ref interface. In Claude Code 2.1.202, pW defines methods including:

  • scrollTo
  • scrollBy
  • scrollToBottom
  • getScrollHeight
  • getFreshScrollHeight
  • getViewportHeight
  • getViewportTop
  • subscribe

A nearby scroll manager then calls r?.current.getFreshScrollHeight() and other scroll-ref methods. A plain Ink Box ref does not implement that interface, causing the crash.

Evidence from local reverse-engineering:

  • Plan dialog call: ky.jsx(pW,{ref:ht,flexDirection:"column",height:At,stickyScroll:!1,children:zt})
  • pW implementation includes getFreshScrollHeight(){return i.current?.childNodes[0]?.yogaNode?.getComputedHeight()??i.current?.scrollHeight??0}
  • Consumer calls let Z=oe.getFreshScrollHeight() and later let te=Z.getFreshScrollHeight() through the scroll ref.

Safer follow-up options

  1. Leave Claude unpatched until upstream fixes the plan-mode scroll regression.
  2. Try a narrower height-only patch that preserves pW and its ref contract, e.g. change At=Ce?Le:void 0 to At=void 0 as a same-length binary edit.
  3. Patch only the pW call's sizing/sticky props while still rendering pW, so downstream scroll-ref consumers keep working.
  4. Avoid Box replacement unless also patching every consumer that expects the pW scroll-ref API. That is probably too brittle for a local binary patch.

Acceptance criteria for any retry

  • Do not replace pW with Box at this call site unless the scroll-ref contract is preserved.
  • claude --version and codesign --verify are not enough; run a real plan-mode approval screen with a long plan.
  • Include a tracked patch wrapper and Bats needle tests only after manual plan-mode verification.
  • --reapply must fail open with a stale marker on missing needles, matching the existing Claude patch lane.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions