Conversation
Replace isViewMaximized/wideView/compactView with one stored preferredView. The rendered pane layout derives from that preference, result availability, and the responsive tier; resizing never rewrites it. - Persisted isViewMaximized migrates to preferredView on read and import. - Agent reads report preferred_view plus live view/tier from the renderer's hydration-aware pane state. - Drop legacy tool inputs: editor_visible, is_view_maximized, grid h back-solve, and the set_cell_view_maximized tool. - Reveal a result hidden by an editor preference when the user runs, or switches to Table/Chart, in any tier. - Reserve grid rows for a multi-statement result when any statement renders a grid, not only the first. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013ceLPBG4yUmAWH1zqYD9w8
…ontract - Cells resolve their pane layout during render. The grid expansion delay is gone, so tool responses and the rendered pane always agree. - Grid transitions run for drag, drop, and width changes. They are suppressed only while the notebook container is being resized. Item height never animates, so a pane switch and its box land together. - The measured grid container width is published once per notebook and read by set_cell_layout, instead of travelling through every cell. - apply_notebook_state rejects changing an existing cell's kind. - Markdown cells report preferred_view, view, and result_height as null. view and result_height inputs are ignored for markdown instead of rejected. auto_refresh is dropped for markdown. - Tool descriptions and the notebook prompt describe the new contract. - e2e/questdb submodule bumped to current master. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015sKRGPKxxoNvBSKEPrEP4K
…fter persist, statement key memo - Stop button in the cell header for a first run or first chart fetch: cancels the run, or aborts the chart round with a cancelled canvas state and Retry. Draw from an empty cell counts as a first run, so its validation can be stopped too. Refreshes never show it. - Cancel markers: a launched statement keeps the unverifiable "Cancelled by user" error; a queued or never-started one is recorded as cancelled by the user, and the sequential cascade tells an abort from a failure. - A deleted cell's in-flight run is superseded, so the agent is told the cell was deleted instead of that its result was cleared. - Snapshot rows drop only after the document write lands; the live controller's transitions settle after the write and report persist_failed on failure. - Per-consumer statement key memo and per-frame result key cache, so a keystroke over a large script formats one statement. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…le, linear key passes - delete the 500-entry identity map, the per-consumer key memo, and the per-frame WeakMap; normalizeStatementIdentity calls the formatter directly - charts compare statements by formatter identity: a whitespace or casing edit keeps the frame and runs nothing - an edit-triggered chart settle carries every statement with chartable rows and executes only the edited ones; poll ticks and manual refresh still run all - CellBottomContent derives its tab list from the engine debounced queries, so a keystroke never re-keys the cell - the engine keeps slotKeys and identities per entry, derived once per SQL change; grid rounds carry frame keys through commits instead of re-keying per slot; reconcile and hydration take precomputed keys - resultsEquivalent skips the identity compare for byte-identical queries - statementIdentityPasses.test pins formatter calls per event Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
emrberk
marked this pull request as ready for review
September 8, 2026 10:33
Web Console deploy preview
|
…agent freshness Address the review findings on notebook cell refresh and resize: - normalizeStatementIdentity falls back to trimmed text when the statement contains a backslash. The MySQL-dialect formatter reads \' as an escaped quote, which QuestDB does not, so two statements with different literals collapsed to one identity and the grid kept stale rows. - Chart rounds record a fetch time per slot. A settle that carries unchanged rows keeps their original time instead of restamping them with the edit time. The times persist in the snapshot and re-enter the engine on hydration through seedRefreshState, which replaces seedRefreshErrors. - Hydration re-keys snapshots saved with trimmed-text statement keys to the formatter-based keys, so refresh errors and the active tab survive the upgrade. The re-keyed snapshot is rewritten once. Reconciliation takes precomputed result keys so the formatter runs once per result. - The split handle keeps the drag in local state and writes the store on drop, and in grid layout also when the box needs another row, instead of on every pointer move. - hasAgentVisibleCellHeightChanged compares the pane heights the agent reads in both layouts. The split handle signals once per drag against the cell it started from, and the edge handles signal on commit. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Statement identity used sql-formatter's MySQL dialect, which uppercased keyword-named aliases and removed the space in number literals. Edits such as `as rank` to `as Rank` or `1. e5` to `1.e5` kept the old result as current although QuestDB returns a different column or value. The formatter also grew faster than linearly with statement size: a 500-row INSERT froze the tab for about 0.6 s at every typing pause. - normalizeStatementIdentity calls `format` from @questdb/sql-parser directly with a pinned `capitalize: true`. It keeps literals, identifiers and aliases as written, and identity never follows the editor's keyword-casing setting. - Statements above 8 KB keep their trimmed text as identity. The formatter costs about 1 ms per KB and runs several times per edit. - The backslash fallback is gone. The QuestDB parser reads `'\'` as one literal and returns SQL it cannot read unchanged. - @questdb/sql-parser bumps to 0.1.19, which adds `format`. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…, fold legacy maximized heights Results now take the text of the statement they belong to at every accept point (reconcile, chart accept, settle write), so raw-text readers such as resolveDraw and snapshots agree with identity keying. A whitespace or casing edit keeps the saved chart config instead of falling back to inferred series. Statement identity no longer formats on render, notify, or run paths: sameStatementIdentity compares raw text first, the tab frame and pane sizing claim results by text and take the engine's slot keys, FrameKeys derives a frame's keys from the statements that wrote it (strict prefix, so a run that lands inside the edit debounce never mis-numbers a case-variant duplicate), and the debounce pass runs inside batchUpdates. A frame that kept every row under new text is re-persisted so hydration can release the cell again. Cells persisted with isViewMaximized fold the editor height into the result pane once, on the read that infers the pane view, so an upgrade keeps the size main showed. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…t fetch stopped A result now carries the time its rows were fetched (fetchedAt, stamped in singleResultFromExec). The status line reads the refresh stamp first and falls back to that time, so an edit that re-persists kept rows, a reload, and a draw-to-table switch after a chart carry no longer show the save or settle time over older rows. The chart settle keeps carried result objects under the new text instead of rebuilding them. savedAt stays the write time. A reveal (scroll back into the near band, tab shown again) no longer re-sends a chart fetch the user stopped. Retry, a SQL edit, and an auto-refresh tick still fetch again. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…b from its run, fold legacy chart heights - A stopped first chart fetch on an auto-refresh cell no longer re-sends on scroll-back or tab-show: the stop stamps lastFetchedAt and a reveal restarts the poll with a full-interval wait, so the next tick fetches. - Error and cancelled results carry fetchedAt like success results, so a reload dates every tab from the run, not from a later edit's save time. cancelledResult() replaces the hand-built cancelled literals. - A legacy maximized chart with no stored result height folds its default height on read, so upgraded agent-made charts keep their size. - A chart settle round persists the frame it shows: carried rows are no longer dropped from disk when the edited sibling statement fails. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A result's fetch time had four homes — result.fetchedAt, the engine's slotFetchedAt map, the frame timestamp, and snapshot.savedAt — and the status line fell back through them, so each review found one more path to a wrong time. Replace the paths with a model: - fetchedAt on the result is the only persisted fetch time. Every constructor stamps it (singleResultFromExec, errorResult, cancelledResult); no result literals remain. - slotVerifiedAt is a session-only overlay for a poll that returned identical rows. It is never persisted, seeded or carried, so an identical tick still costs no frame write. The status line shows the later of the two; after a reload it shows the rows' true fetch time until the next tick. - The frame timestamp is the run token, not a time: InlineResultTable takes it as runToken, StatusNotification no longer receives it, ChartResult drops it, and poll freshness reads frameFetchedAt. - Hydration folds fetchedAt once into results saved without it, from the snapshot's legacy per-slot stamp or its save time, and rewrites. The snapshot's slotFetchedAt is read only there and never written. - A restarted poll loop sleeps until its next tick is due, for fixed and adaptive intervals alike, so a reveal after a Stop never re-sends the stopped query early. - ResultGridPanel memoizes its data source on columns, dataset and timestamp instead of the result object. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…e current cell ResizeHandle binds its document mousemove and mouseup listeners at mousedown and called the onResize and onResizeEnd captured in that render. Since the split handle started writing the store when the grid box needs another row, that stale closure compared every move against the drag-start cell: after the first row crossing every move wrote the store, and a drag back into the start rows left the box one row stale until mouseup. The listeners now read the callbacks through refs synced in an effect, so the orchestration compares against the fresh cell and writes once per row. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…etry The Table and Chart segments locked with native disabled while a run or chart fetch was in flight, so activating "View chart" from the keyboard disabled the focused button and Chromium dropped focus to the document body. They now lock with aria-disabled and a click guard, as the Run and Draw toggles do, and keep focus. DrawCanvas's Retry unmounted under focus when the refresh replaced the cancelled state. When Retry is the active element it now hands focus to the cell toolbar before publishing the refresh, the same handoff the Stop button uses on unmount. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…run, re-key legacy snapshots per snapshot, fold imports before the clamp - apply_notebook_state returns `results_cleared`, the cells whose whole result the apply discarded; both shells add the snapshot-only cases - an auto-refresh change resets the poll interval and the first sleep is capped at one interval, so Auto never resumes on a fixed interval and a clock set back cannot stall the loop - a run that Stop aborted before any statement launched reports "cancelled" to the agent instead of "error" - a legacy snapshot is detected by its missing fetch time, and every key maps by position, so a legacy key that spells another statement's head key lands on the statement it described - a notebook import folds legacy maximized heights before the pane clamp, matching the in-place read Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Requested: stable chart sizing across viewport changes
Reported problem: charts squashed and stretched while moving windows or opening the Editor panel, so the chart shape did not hold.
paneView) and make it independent of the viewport. Under 480 px the compact tier used to hide the editor and stretch the chart to the full cell height; widening collapsed it back. The tier now affects only the toolbar.Note: the chart width still follows the container. This PR stabilizes the height; it does not lock a width-to-height ratio.
Other improvements
editor_height,result_height, andviewcontrols. Snapshots report the stored view, mode, and semantic heights.Validation
Deferred follow-up