callstack / callstack/agent-device

scroll top/bottom reports "Already at bottom" when the capture is unreadable

Open
#2,468 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
4.6k
Forks
299
Avg merge
10h 17m
Merged PRs (30d)
515

Description

`captureEdgeState` in [src/daemon/scroll-runtime.ts](https://github.com/callstack/agent-device/blob/main/src/daemon/scroll-runtime.ts) coerces a failed read to `[]`, and `analyzeScrollEdgeState` reads an empty tree as no hidden content at the edge. So a capture that fails, or comes back sparse, makes `scroll bottom` report "Already at bottom; no hidden content below detected" instead of saying it could not see the screen.

Same defect class as the one fixed for `scroll --until` in #2436: a failed observation presented as a fact about the content. That PR refuses an unreadable capture before the edge analyzer runs, using `sparseCaptureQuality` from `@agent-device/selectors/absence-observation` as the single definition of readable.

## The shape of the fix

Reviewer's suggestion on #2436, and it is the right one: `runScrollUntilVisible` and `runScrollEdgePasses` are the same loop — capture, test a stop condition, scroll, count, cap. Today they are two loops with two budgets (12 and 40), two error vocabularies and two capture closures. One `runScrollPasses({ shouldStop, passLimit })` in capture-kit would carry both, `scroll bottom` becomes a stop condition, and the capture refusal lands once for both callers.

Kept out of #2436 deliberately: it changes the failure surface of `scroll top`/`scroll bottom`, which is separate from adding `--until`.

## Acceptance

`scroll bottom` against an unreadable or sparse capture fails with a typed capture refusal rather than an edge verdict, and both scroll loops share one pass-loop definition.

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.